【问题标题】:How to represent a dictionary in Swift with nested types from JSON如何用来自 JSON 的嵌套类型在 Swift 中表示字典
【发布时间】:2016-06-30 19:27:41
【问题描述】:

假设我正在解析 JSON,需要将其转换为 Swift 字典。如果您在下面注意到,该类型是相当嵌套的。有一个帐户键,其值是另一个映射,具有嵌套数组等。我看过很多建议 AnyObject?或任何?这样做的正确方法是什么?一个完整的例子会很棒。我正在使用 Alamofire / SwiftyJSON。谢谢!

    {
        "id": "20o2k2jlkja08a08",
        "username": "catlover",
        "accounts": {
            "verified_email": "false",
            "identities": [{
                "network": "facebook",
                "token": "alkdjlaksjsak",
                "avatar": "avatarUrl"
            }, {
                "network": "twitter",
                "token": "alkdjlaksjsak",
                "avatar": "avatarUrl"
            }]
        },
        "followers": "100",
        "following": "20"
    }

【问题讨论】:

  • 最好的方法是创建一个模型类/结构来映射到该 JSON 并且可以使用字典进行初始化。

标签: json swift dictionary


【解决方案1】:

我建议您查看 ObjectMapperAlamofireObjectMapper 框架,它们都可以在 Cocoapods 上找到。有了它们,从 JSON 映射到 Swift 的对象真的很容易。

首先,定义 JSON 如何映射到您的对象:

import ObjectMapper

class User: Mappable {
    var id: String?
    var username: String?
    var accounts: UserAccount?
    var followers: Int?
    var following: Int?

    required init?(_ map: Map) { /* validate your JSON, etc */ }

    func mapping(map: Map) {
        self.id         <- map["id"]
        self.username   <- map["username"]
        self.accounts   <- map["accounts"]
        self.followers  <- map["followers"]
        self.following  <- map["following"]
    }
}

class UserAccount: Mappable {
    var verifiedEmail: Bool?
    var identities: [UserIdentity]?

    required init?(_ map: Map) { }

    func mapping(map: Map) {
        self.verifiedEmail  <- map["verified_email"]
        self.identities     <- map["identities"]
    }
}

class UserIdentity: Mappable {
    var network: String?
    var token: String?
    var avatar: NSURL?

    required init?(_ map: Map) { }

    func mapping(map: Map) {
        self.network    <- map["network"]
        self.token      <- map["token"]
        self.avatar     <- (map["avatar"], URLTransform())
    }
}

用法:

Alamofire.request(.GET, url)
    .responseObject { (response: Response<User, NSError>) in
        let user = response.result.value

        // Get the url to the user's avatar
        let avatarURL = user?.accounts?.identities?.first?.avatar
    }

如果你想避免所有这些?,只需给你的属性一个默认值。当然,这只有在保证属性存在于您的 JSON 中时才有意义:

class User: Mappable {
    var id = ""
    var username = ""
    var accounts = UserAccount()
    var followers = 0
    var following = 0

    ...
}

【讨论】:

  • 谢谢!
  • 我猜你可以称它为“映射运算符”。它不是标准的 Swift 运算符,而是由ObjectMapper 框架定义的自定义运算符
【解决方案2】:

您必须将 JSON 文档 Array/Dictionary 加工成您自己的类结构。像这样的...

public class Identity
{
    public var network: String
    public var token: String
    public var avatarURI: NSURL
}

public class Account
{
    public var verifiedEmail: Bool
    public var identities: [Identity]
}

public class Profile
{
    public var profileID: String
    public var userName: String
    public var accounts: [Account]
    public var followers: Int
    public var following: Int
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    • 2020-04-16
    • 2021-07-18
    • 1970-01-01
    • 2019-04-21
    • 2015-08-25
    • 1970-01-01
    相关资源
    最近更新 更多