ios - Swift 3/自 "Value of type Any has no member value"以来如何处理嵌套的 NSDictionaries

标签 ios swift

请不要将“Any 类型的值没有成员值”标记为重复项。我不是问如何解决编译器错误。

我的问题是:处理嵌套字典的最佳做法是什么,因为新的需要向下转换所有内容?

我在 Swift 2 中的代码是:

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

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:如果向下转换为 NSDictionaryAnyObject 没有任何区别,但因为我知道什么我正在向下转换,我更喜欢将它转换为 NSDictionary 而不是 AnyObject

最佳答案

我猜这是因为 Swift 试图在确定性方面犯错,这使得处理 NSDictionary 数据有点棘手。

没有看到'result'的实际结构很难优化,但这里有一个尝试:

假设数据结构类似于:

let result = [
    "credentials": [
        "token": "token"
    ],
    "uid": "uid",
    "extra": [
        "raw_info": [
            "data": [
                "bio": "bio",
                "counts": [
                    "followed_by": 100,
                    "follows": 100,
                    "media": 100
                ]
            ]
        ]
    ],
    "user_info": [
        "username": "username",
        "image": "image"
    ]
] as [String : Any]

此代码可以将其“解析”为变量(在 playground 中测试):

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"]

    // ...
}

如果知道“extra”的结构,代码可能会更简洁。

关于ios - Swift 3/自 "Value of type Any has no member value"以来如何处理嵌套的 NSDictionaries,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40179538/

相关文章:

iphone - 暂时阻止 UITableViewCell 被回收

ios - XCUIApplication : How to set a custom core location

ios - MacCatalyst 的条件 Pod 链接

ios - 将 gif 添加到 UIImageView

arrays - didSet 没有在每次突变时都被调用吗?

ios - iPhone 7 上未收到 GCM 推送

objective-c - Objective-C : Displaying Array Elements

ios - 如何在 Sprite 套件中制作水平选择器 View 来选择不同的角色?

swift - 快速获取触摸的各种坐标

ios - 如何减小行间距?