【问题标题】:How to parse complex data using alamofire object mapper?如何使用 alamofire 对象映射器解析复杂数据?
【发布时间】:2017-07-05 09:38:43
【问题描述】:

我正在尝试使用 Alamofire 对象映射器解析 JOSN 数据..完成了基本的事情,但遇到了复杂的事情,例如

1.如何访问“settings_data”中的值? (这是访问嵌套对象的最佳方式)

2.我可以在哪里定义 .GET、.POST 方法类型以及我们应该在哪里传递参数?就像我们写的正常的 alamofire 请求一样

  Alamofire.request(url, method: .get, parameters: nil, encoding: JSONEncoding.default)
            .responseJSON { response in

有什么好的方法可以达到同样的效果吗?

JOSN 回应

{
    "err": 0,
    "result": [{
        "id": 71930,
        "account_id": 40869,
        "status": "enabled",
        "settings_data": {
            "time_format": "12h",
            "timezone": "US/Pacific",
            "fingerprint_versions": {
                "browser.browser-js": 1
            },
            "integrations": {
                "jira": {},
                "datadog": {},
                "bitbucket": {},
                "github": {},
                "trello": {
                    "board_id": "xxx",
                    "enabled": true,
                    "access_token_user_id": 1234,
                    "list_id": "xxxxx"
                },
                "slack": {
                    "channel_id": "xxxx",
                    "enabled": true,
                    "access_token_user_id": "xx"
                },
                "webhook": {},
                "victorops": {},
                "asana": {},
                "pivotal": {},
                "campfire": {},
                "sprintly": {},
                "pagerduty": {},
                "hipchat": {},
                "email": {
                    "enabled": true
                },
                "flowdock": {}
            }
        },
        "date_created": 1468068105,
        "date_modified": 1493409629,
        "name": "Android_ParentApp"
    }, {
        "id": 71931,
        "account_id": 40869,
        "status": "enabled",
        "settings_data": {
            "time_format": "12h",
            "timezone": "US/Pacific",
            "fingerprint_versions": {
                "browser.browser-js": 1
            },
            "integrations": {
                "jira": {},
                "datadog": {},
                "bitbucket": {},
                "github": {},
                "trello": {
                    "board_id": "xxxx",
                    "enabled": true,
                    "access_token_user_id": 1234,
                    "list_id": "xxxxx"
                },
                "slack": {
                    "channel_id": "xxxxx",
                    "enabled": true,
                    "access_token_user_id": "xxx"
                },
                "webhook": {},
                "victorops": {},
                "asana": {},
                "pivotal": {},
                "campfire": {},
                "sprintly": {},
                "pagerduty": {},
                "hipchat": {},
                "email": {
                    "enabled": true
                },
                "flowdock": {}
            }
        },
        "date_created": 1468068142,
        "date_modified": 1493409658,
        "name": "Android_TeacherApp"
    }]
}

模型类 - Project.swift

import Foundation
import ObjectMapper

class Project: NSObject, Mappable {

    var projectId: Int?
    var accountId: Int?
    var dateCreated: Int?
    var dateModified: Int?
    var name: String?
    var status: String?

    override init() {
        super.init()
    }

    convenience required init?(map: Map) {
        self.init()
    }

    func mapping(map: Map) {
        projectId <- map["id"]
        accountId <- map["account_id"]
        dateCreated <- map["date_created"]
        dateModified <- map["date_modified"]
        name <- map["name"]
        status <- map["status"]
    }
}

ViewController.swift

import UIKit
import Alamofire
import AlamofireObjectMapper

class ViewController: UIViewController {

    var projects:[Project] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        fetchData()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func fetchData(){
        UIApplication.shared.isNetworkActivityIndicatorVisible = true
        let apiUrl = "https://raw.githubusercontent.com/javalnanda/AlamofireObjectMapperSample/master/AOMsample.json"
        Alamofire.request(apiUrl).validate().responseArray(keyPath: "result") { (response: DataResponse<[Project]>) in
            UIApplication.shared.isNetworkActivityIndicatorVisible = false
            switch response.result {
            case .success:
                print(response.result)
                self.projects = response.result.value ?? []
               // print("sss \(self.projects)")

                for project in self.projects {
                    print(  project.name ?? "")
                }
            case .failure(let error):
                print(error)
            }
        }
    }

}

【问题讨论】:

标签: ios swift alamofire objectmapper


【解决方案1】:

实现这些类型的复杂 json 的最佳方法是将每个子类别拆分为不同的对象,并使它们符合可映射的协议。然后解析该函数​​内的值。请参阅解析了 time_format 和 timezone 的 SettingsModel 示例。您可以像这样实现其余的类

    import Foundation
    import ObjectMapper

    class Project: NSObject, Mappable {

        var projectId: Int?
        var accountId: Int?
        var dateCreated: Int?
        var dateModified: Int?
        var name: String?
        var status: String?
        var settings: SettingsModel?
        override init() {
            super.init()
        }

        convenience required init?(map: Map) {
            self.init()
        }

        func mapping(map: Map) {
            projectId <- map["id"]
            accountId <- map["account_id"]
            dateCreated <- map["date_created"]
            dateModified <- map["date_modified"]
            name <- map["name"]
            status <- map["status"]
            settings <- map["settings_data"]
        }
    }


import UIKit
import ObjectMapper

class SettingsModel: NSObject,Mappable {

     var time_format:String?
     var timezone:String?

     override init() {
        super.init()
    }

    convenience required init?(map: Map) {
        self.init()
    }

    func mapping(map: Map) {
       time_format <- map["time_format"]
       timezone <- map["timezone"]
}
}

如果你不想创建新对象,你可以像这样解析

func mapping(map: Map) {
                projectId <- map["id"]
                accountId <- map["account_id"]
                dateCreated <- map["date_created"]
                dateModified <- map["date_modified"]
                name <- map["name"]
                status <- map["status"]
                time_format <- map["settings_data.time_format"]
                timezone <- map["settings_data.timezone"]

            }

【讨论】:

  • 感谢您的帮助...我有疑问我们是否需要为每个对象创建这样多个类..如果我们有 50 个这样的 API,每个 50 个不同的对象像上面那样?这种场景有更好的架构吗?
  • 如果您不想创建对象,那么您的响应对象将变得非常非常大,并且很难管理。分离每个实体是一种更模块化的实现方式。如果你不想创建对象,你可以解析像 timezone 这样的值
  • 我已经用后面的方法更新了答案,请检查
  • 谢谢 Arvind..你能指导一下我们应该在哪里写 .GET 和 .POST 方法吗?
  • 很抱歉我没有找到你。能不能说的详细点?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-15
  • 1970-01-01
  • 2019-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-22
相关资源
最近更新 更多