在 Swift 中动态存储和访问数据的最佳方式
Posted
技术标签:
【中文标题】在 Swift 中动态存储和访问数据的最佳方式【英文标题】:Best way to dynamically store and access data in Swift 【发布时间】:2020-09-29 09:07:37 【问题描述】:我有一个应用程序,每次启动时(在初始屏幕内),它都会通过 API 端点从我的数据库中获取当前登录的用户数据。 当应用请求数据时,预期返回给应用的 JSON 类型如下所示:
"username": "test",
"email": "test@gmail.com",
"uid": "5f661ffe1a80160027a6cb0c",
"isVerified": true,
"hub":
"hubID": "npnDsZegiSL5",
"isSetup": true,
"hubSWVersion": 0.11,
"_id": "5f661ffe1a80160027a6cb0d",
"cameraService":
"isSetup": true,
"bridgeIP": "192.168.0.12",
"username": "JesCGSr6HrWoKbKnnNOHSayVKdb1"
,
"servicesSetup":
"1": "cameraService",
"2": "TPLinkPlug"
,
"code": "100",
"message": "Success. User details have been provided"
随着用户添加服务/更新值,此数据库结构将不断变化。这是我的问题。有很多这样的问题都有相同的答案,使用 JSONDecoder
并将值推送到可观察对象,该对象可以通过创建它的实例在整个应用程序中访问,或者只是简单地将值分配给获取对象时的对象。我已经完成并且目前正在使用的:
类userData
对象:
class userData: NSObject, ObservableObject
var userdata = userData.self
@Published var uid: String = ""
@Published var isVerified: Bool = false
@Published var username: String = ""
@Published var email: String = ""
当我在我的应用程序中收到上述 json 时,我将值分配给对象的代码:
...
@EnvironmentObject var user: userData
print("Successfully got user data. Code: \(code ?? "0"). UID: \(response?["uid"] as! String). Username: \(response?["username"] as! String)")
DispatchQueue.main.async
user.email = response?["email"] as! String
user.uid = response?["uid"] as! String
user.username = response?["username"] as! String
...
然后我可以通过我的任何地方访问它:
@EnvironmentObject var user: userData
username = self.user.username
但这需要硬编码代码来分配我的数据库中的每个值,是否有更好、更动态的方法来将来自我的 API 的整个 json 响应(无论有什么值/嵌入的 json)分配给一个对象并通过该对象在我的应用中访问这些数据值?
谢谢
【问题讨论】:
您可以将响应存储为Dictionary
并遍历键而不是硬编码字段。
@MohammadRahchamani 如果您认为这是最好的方法,您能否在此评论中添加示例代码作为答案,以便此问题可以帮助包括我在内的其他人?
@MohammadRahchamani 我如何能够从应用程序内的任何位置访问所述字典?
这取决于您的架构。例如,您可以将该字典作为EnvironmentObject
传递。或将其存储在您的数据库等中。
【参考方案1】:
因为您的响应中将包含新的键值对,所以我认为您应该将响应存储为 Dictionary
并从该字典中获取所需的值,而不是解析响应并存储单独的变量。
这是一个例子:
let jsonStr = """
\"username\": \"test\",
\"email\": \"test@gmail.com\",
\"uid\": \"5f661ffe1a80160027a6cb0c\",
\"isVerified\": true,
\"hub\":
\"hubID\": \"npnDsZegiSL5\",
\"isSetup\": true,
\"hubSWVersion\": 0.11,
\"_id\": \"5f661ffe1a80160027a6cb0d\",
\"cameraService\":
\"isSetup\": true,
\"bridgeIP\": \"192.168.0.12\",
\"username\": \"JesCGSr6HrWoKbKnnNOHSayVKdb1\"
,
\"servicesSetup\":
\"1\": \"cameraService\",
\"2\": \"TPLinkPlug\"
,
\"code\": \"100\",
\"message\": \"Success. User details have been provided\"
"""
let data = jsonStr.data(using: .utf8)
do
// store this variable
let dict = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any]
for (k,v) in dict!
// example access to values
print("key: \(k), value: \(v)")
catch
print(error.localizedDescription)
【讨论】:
您正在使用jsonStr
传递给JSONSerialization
函数。我有一个从我的 API 返回的 json 对象。如果我改为传递那个 json 对象(try JSONSerialization.jsonObject(with: json!, options: [])
我得到错误:Type of expression is ambiguous without more context
我要么需要让 json 对象返回与上面相同的格式,要么使用不同的函数?
我假设您收到的回复为String
。
它有效,我之前已经这样做了,只是我无法获得嵌入到该 json 中的值,例如hub
中的值
因为hub
值本身就是Dictionary
,您应该将其转换为Dictionary
以访问其中的值。例如:让 hubDict = dict["hub"] as!字典以上是关于在 Swift 中动态存储和访问数据的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章