Ios Swift 3/如何处理嵌套的NSD词典,因为;类型Any的值没有成员值“;
请不要将“任何类型的值没有成员值”标记为重复项。我不是问如何解决编译器错误 我的问题是:处理嵌套字典的最佳实践是什么?新的需求是贬低一切 我在Swift 2中的代码是:Ios Swift 3/如何处理嵌套的NSD词典,因为;类型Any的值没有成员值“;,ios,swift,Ios,Swift,请不要将“任何类型的值没有成员值”标记为重复项。我不是问如何解决编译器错误 我的问题是:处理嵌套字典的最佳实践是什么?新的需求是贬低一切 我在Swift 2中的代码是: if result != nil { let token = String((result.value(forKey: "credentials")?.value(forKey: "token"))!) let uid = String((result.value(forKey: "uid"))!)
if result != nil {
let token = String((result.value(forKey: "credentials")?.value(forKey: "token"))!)
let uid = String((result.value(forKey: "uid"))!)
let bio = String((result.value(forKey: "extra")?.value(forKey: "raw_info")?.value(forKey: "data")?.value(forKey: "bio"))!)
let followed_by = String((result.value(forKey: "extra")?.value(forKey: "raw_info")?.value(forKey: "data")?.value(forKey: "counts")?.value(forKey: "followed_by"))!)
let follows = String((result.value(forKey: "extra")?.value(forKey: "raw_info")?.value(forKey: "data")?.value(forKey: "counts")?.value(forKey: "follows"))!)
let media = String((result.value(forKey: "extra")?.value(forKey: "raw_info")?.value(forKey: "data")?.value(forKey: "counts")?.value(forKey: "media"))!)
let username = String((result.value(forKey: "user_info")?.value(forKey: "username"))!)
let image = String((result.value(forKey: "user_info")?.value(forKey: "image"))!)
self.saveAccount(token, uid: uid, bio: bio, followed_by: followed_by, follows: follows, media: media, username: username, image: image)
}
我知道出现错误是因为我需要从Swift 3开始向下广播。
但由于我查询的是嵌套字典,因此每一步都需要向下转换为AnyObject
,在10行代码内,我将转换为AnyObject
,大约50次。有些行有10亿个字符长
if result != nil {
let token = String(describing: (((result as! NSDictionary).value(forKey: "credentials") as AnyObject).value(forKey: "token"))!)
let uid = String(describing: ((result as! NSDictionary).value(forKey: "uid"))!)
let bio = String(describing: (((((result as! NSDictionary).value(forKey: "extra") as AnyObject).value(forKey: "raw_info") as AnyObject).value(forKey: "data") as AnyObject).value(forKey: "bio"))!)
let followed_by = String(describing: ((((((result as! NSDictionary).value(forKey: "extra") as AnyObject).value(forKey: "raw_info") as AnyObject).value(forKey: "data") as AnyObject).value(forKey: "counts") as AnyObject).value(forKey: "followed_by"))!)
let follows = String(describing: ((((((result as! NSDictionary).value(forKey: "extra") as AnyObject).value(forKey: "raw_info") as AnyObject).value(forKey: "data") as AnyObject).value(forKey: "counts") as AnyObject).value(forKey: "follows"))!)
let media = String(describing: ((((((result as! NSDictionary).value(forKey: "extra") as AnyObject).value(forKey: "raw_info") as AnyObject).value(forKey: "data") as AnyObject).value(forKey: "counts") as AnyObject).value(forKey: "media"))!)
let username = String(describing: (((result as! NSDictionary).value(forKey: "user_info") as AnyObject).value(forKey: "username"))!)
let image = String(describing: (((result as! NSDictionary).value(forKey: "user_info") as AnyObject).value(forKey: "image"))!)
self.saveAccount(token, uid: uid, bio: bio, followed_by: followed_by, follows: follows, media: media, username: username, image: image)
}
例如,让后面跟着
let followed_by =
String(describing: ((((((result as! NSDictionary)
.value(forKey: "extra") as AnyObject)
.value(forKey: "raw_info") as AnyObject)
.value(forKey: "data") as AnyObject)
.value(forKey: "counts") as AnyObject)
.value(forKey: "followed_by"))!)
我有另一个功能,我查询25+个对象,并向下搜索100次
我知道如何得到结果,但有没有更先进的方法来处理这种情况?或者至少让它看起来更具可读性?非常感谢你的帮助
PS:如果降级为
NSDictionary
或AnyObject
,没有任何区别,但因为我知道我降级的内容,我更喜欢将其降级为NSDictionary
,而不是AnyObject,首先是,其次是不要:不要在Swift中使用NSDictionary
。你扔掉了类型信息
是的,您必须向下转换中间对象,但始终是编译器可以安全使用的对象(SwiftDictionary
或Array
)
因为所有的中间对象显然都是字典,所以将它们强制转换为[String:Any]
下面是一个简短的例子。为清晰起见,使用了[String:Any]
的类型别名
typealias JSONDictionary = [String:Any]
这将提取extra
节点中的对象
if let result = result as? JSONDictionary {
let token = (result["credentials"] as! JSONDictionary)["token"] as! String
let uid = result["uid"] as! String
if let extra = result["extra"] as? JSONDictionary,
let rawInfo = extra ["raw_info"] as? JSONDictionary,
let data = rawInfo["data"] as? JSONDictionary {
let bio = data["bio"] as! String
if let counts = data["counts"] as! JSONDictionary{
let followed_by = counts["followed_by"] as! String
let follows = counts["follows"] as! String
let media = counts["media"] as! String
}
}
}
当然,这段代码没有经过测试,但您会对如何解析嵌套字典有一个印象。如果<代码>结果< /代码>是反序列化的,JSON考虑使用像SwiftjJSON这样的库。 首先,第二个<强>不要< /强>:不要在SWIFT中使用<代码> NSCORCHON/<代码>。你扔掉了类型信息
是的,您必须向下转换中间对象,但始终是编译器可以安全使用的对象(SwiftDictionary
或Array
)
因为所有的中间对象显然都是字典,所以将它们强制转换为[String:Any]
下面是一个简短的例子。为清晰起见,使用了[String:Any]
的类型别名
typealias JSONDictionary = [String:Any]
这将提取extra
节点中的对象
if let result = result as? JSONDictionary {
let token = (result["credentials"] as! JSONDictionary)["token"] as! String
let uid = result["uid"] as! String
if let extra = result["extra"] as? JSONDictionary,
let rawInfo = extra ["raw_info"] as? JSONDictionary,
let data = rawInfo["data"] as? JSONDictionary {
let bio = data["bio"] as! String
if let counts = data["counts"] as! JSONDictionary{
let followed_by = counts["followed_by"] as! String
let follows = counts["follows"] as! String
let media = counts["media"] as! String
}
}
}
当然,这段代码没有经过测试,但您会对如何解析嵌套字典有一个印象。如果<代码>结果被反序列化,JSON考虑使用像SwiftjJSON这样的库。 < P>你这样做的方式几乎是不可能阅读的,但这也不是你在SWIFT中使用字典的方式。
您使用NSDictionaries and value(forKey:)而不是切换到带Dictionary的swift Dictionaries(swift 3样式指南希望我们将其键入[String:AnyObject])有什么原因吗?您是在尝试访问NSDictionary的value(forKey:)功能,还是仅尝试获取result[“uuid”]的值
我要做的是为每个嵌套字典创建模型或结构。(这是JSON响应吗?)
如果我读对了,后面跟的是嵌套字典中的一个变量(不确定这是否正确)?例如,这是一个更深层的嵌套字典,但是你可以用自己的方法来处理它,你可以创建一个名为“Counts”的类
该类将具有属性,在您的例子中,这些属性类似于:followedBy(用户数组?-用户也可能具有自定义类,具有用户名和图像等属性)、followed(用户数组?)、media(无论这是什么类型的对象)-这些属性将由该字典初始化。soinit(dictionary:[String:AnyObject])
如果让followersDictArray=dictionary[“后跟”]as?[[String:AnyObject]]{
var=Array()
对于followersDict=followersDict数组{
如果let followers=UserModel(字典:followersDict){
followers.append(follower)
}
}
followerdby=跟随者
}
然后继续这样处理其余的属性
您将拥有一个名为Data的类,该类的属性类似于bio(idk这是什么类型,但假设为String?)和counts(属于对象类型counts.init(dictionary:),该数据类将由一个字典初始化,该字典将信息传递给这些属性
你可以像那样来解析数据
本质上,您需要嵌套字典的结构或类。您不希望所有这些都像!AnyObject一样。当您开始看到所有这些感叹号和((((((()()时)(当您尝试从JSON字典访问信息时,您应该将其视为您正在做一些非常错误的事情的警报
以您目前的方式执行此操作—您没有保护自己免受JSON响应错误的影响,其他人将无法读取您的代码
此外,决不能将snake-case用于swift变量名。
紧随其后的应该是你这样做几乎是不可能阅读的,但这也不是你在swift中使用词典的方式
您使用NSDictionary和value(forKey:)而不是切换到swift Dictionary with Dictionary(swift 3 style guide希望我们将其键入[String:AnyObject])有什么原因吗?您是在尝试访问NSDictionary的value(forKey:)功能,还是仅尝试获取结果[“uuid”]的值
我要做的是为每个嵌套字典创建模型或结构(这是JSON响应吗?)
如果我读对了,后面跟的是嵌套字典中的一个变量
if let result = result as? [String : Any] {
let token = (result["credentials"] as! [String:String])["token"]
let uid = result["uid"]
let data = (((result["extra"] as! [String : Any])["raw_info"] as! [String : Any])["data"] as! [String : Any])
let bio = data["bio"] as! String
let counts = data["counts"] as! [String:Int]
let followed_by = counts["followed_by"]
let follows = counts["follows"]
let media = counts["media"]
let userInfo = result["user_info"] as! [String : String]
let username = userInfo["username"]
let image = userInfo["image"]
// ...
}