Swift 中动态存储和访问数据的最佳方式
Best way to dynamically store and access data in Swift
我有一个应用程序,每次启动时(在初始屏幕内),它都会通过 API 端点从我的数据库中获取当前登录的用户数据。
JSON请求数据时希望返回给app的类型如下所示:
{
"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"
}
随着用户添加 services/updates 值,此数据库结构将不断变化。这是我的问题。有很多这样的问题都有相同的答案,使用 JSONDecoder
并将值推送到一个可观察的对象,可以通过创建它的实例或只是简单地分配它来访问整个应用程序获取对象时的值。我已经完成并正在使用:
classuserData
对象:
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 响应(无论是什么values/embedded json是否存在)一个对象并通过该对象在我的应用程序中访问这些数据值?
谢谢
因为您的响应中会有新的键值对,我认为您应该将响应存储为 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)
}
我有一个应用程序,每次启动时(在初始屏幕内),它都会通过 API 端点从我的数据库中获取当前登录的用户数据。 JSON请求数据时希望返回给app的类型如下所示:
{
"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"
}
随着用户添加 services/updates 值,此数据库结构将不断变化。这是我的问题。有很多这样的问题都有相同的答案,使用 JSONDecoder
并将值推送到一个可观察的对象,可以通过创建它的实例或只是简单地分配它来访问整个应用程序获取对象时的值。我已经完成并正在使用:
classuserData
对象:
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 响应(无论是什么values/embedded json是否存在)一个对象并通过该对象在我的应用程序中访问这些数据值?
谢谢
因为您的响应中会有新的键值对,我认为您应该将响应存储为 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)
}