我需要在API调用之外定义的 var 对象中初始化JSONDecoder的结果。
apiService.GETAPI(url: apiStr, completion: {(success, result) in
if(success) {
let apiResponse = result.value as! NSDictionary
let data = apiResponse.value(forKey: "data") as! NSDictionary
do {
let profileData = try JSONSerialization.data(withJSONObject: data.value(forKey: "profile"), options: .prettyPrinted)
print(profileData)
let profile = try JSONDecoder().decode(Profile.self, from: profileData)
print(profile.name)
}
catch {
print("json error: \(error.localizedDescription)")
}
}
completion(success)
})
但我无法这样做。这是我的Profile Codable结构
struct Profile : Codable {
var id : Int
var name : String
var member_id : Int
var category_id : Int
var membership_id : Int
var information : String
var city : String
var love_count : Int
var vendor_price : String
var locality_name : String
var phone : [String]
var address : [Address]?
var status : Int?
var managed_by_wmg : Int?
}
怎么做。我需要它是var,因为我需要执行操作并稍后在其他代码中访问它。
答案 0 :(得分:0)
正如我们已经在您的问题的评论中讨论的那样,您需要在闭包之外声明Profile
类型的变量。
现在问题变成了"How to change Profile struct, so I can declare variable of it?"
为此你有几个选择。我将列出它们并评论选择哪个以及为什么。
选项1
将默认值添加到Profile
struct的所有变量中,如下所示:var id : Int = 0
,以便稍后可以使用var profile: Profile?
声明它。使用此解决方案,您需要以对业务逻辑有意义的方式了解您期望的对象及其默认值。对于字符串或""
整数,此类默认值的示例为0
。这可能看起来不错,但它们是更好的解决方案。
选项2
将Profile
的所有变量设为可选,如下所示:var id : Int?
。这听起来可能很奇怪,但却是处理服务器数据的最佳解决方案。所以这种方法有几个好处:
nil
但是,使用此方法存在一个缺点:某些属性与您的逻辑永远不会是nil
将具有nil
初始值。因此,您需要添加验证以展开可空属性。
选项3 向变量类型添加显式解包,var id : Int!
。请注意,这也会将nil
作为初始值添加到您的属性中,但会告诉编译器,在每次使用它们时,它们都不会是nil
。我个人不推荐这种方法,因为如果没有从服务器收到变量,或者解析失败,或者其他意外情况发生,那么你的应用程序将会崩溃found nil while unwrapping optional value
。作为参考,您可能已经注意到所有IBOutlets
都是以这种方式定义的。
说了这么多,我建议你选择最适合服务器通信的选项2 ,但选择权是你的!
快乐的编码。
答案 1 :(得分:0)
我找到了两个问题的解决方案。感谢@ dvp.petrov。
解决方案1 var profile : Profile!
非常方便,但如果这不是一个可选变量并且必须在许多地方使用,那就很难了。每次都必须进行大量检查并打开包装。当一个人必须在非常少的地方使用它时,这很容易使用
解决方案2:创建一个init函数,为所有变量提供默认值,然后您可以创建var profile : Profile()
。这样您的对象就不会是nil
,并且可以在某些地方使用它。
struct Profile : Codable {
var id : Int
var name : String
var member_id : Int
init() {
self.id = 0
self.name = ""
self.member_id = 0
}