2015-07-21 69 views
3

我在Swift 1.2中使用NSJSONSerialization来解析从API响应返回的一些json。用AnyObject初始化Swift类?来自NSJSONSerialization

var err: NSError? 
let opts = NSJSONReadingOptions.AllowFragments 
let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(jsonData!, options: opts, error: &err) 

解析的json的提供方式为AnyObject?。我想用这个可选项来初始化一个可以在应用程序中用作模型数据的类对象。

class Alerts { 
    let type: String 
    let date: String 
    let description: String 
    let expires: String 
    let message: String 

    init(json: AnyObject) { 
     if let 
     jsonDict = json as? [String: AnyObject], 
     alertsArray = jsonDict["alerts"] as? [AnyObject], 
     alertsDict = alertsArray[0] as? [String: AnyObject], 
     type = alertsDict["type"] as? String, 
     date = alertsDict["date"] as? String, 
     description = alertsDict["description"] as? String, 
     expires = alertsDict["expires"] as? String, 
     message = alertsDict["message"] as? String 
     { 
      self.type = type 
      self.date = date 
      self.description = description 
      self.expires = expires 
      self.message = message 
     } 
     else 
     { 
      self.type = "err" 
      self.date = "err" 
      self.description = "err" 
      self.expires = "err" 
      self.message = "err" 
     } 
    } 
} 

// example of creating a data model from the json 
let alerts = Alerts(json: json!) 
alerts.type 
alerts.date 
alerts.description 
alerts.expires 
alerts.message 

由于NSJSONSerialization返回一个可选的,我必须检查每个值类型的存在,因为我提取JSON数据。正如你在上面的代码中看到的那样,我使用了Swift 1.2改进的可选绑定来清理init方法。如果没有使用第三方库,我还有什么可以做的类模型(enums,structs,type aliases),使其更具可读性?我应该使用struct作为模型数据而不是class?是否可以使用enumstruct来创建自定义类型来表示json对象?

+0

我知道你提到你不想使用第三方库,但我真的觉得你应该看看SwiftyJSON。它检查你的一切,并给你一个嵌套的字典。就我个人而言,我将使用这种方法将JSON映射到使用Structs的swift模型,在init中分配数据并嵌套Structs,从“Root()”开始嵌套,然后从那里开始下载。 – Cole

+0

@Cole我知道SwiftyJSON和Argo,但我不想依赖它们。尽管使用'struct'代替swift模型可能是个好主意。 – wigging

回答

0

因此,如果不使用第三方库,if let树通常是您已经显示的最佳做法。为了帮助您稍后走下去,可能会在JSON中将您的对象层次结构重新创建为Swift中的Struct模型。例如:

var json = JSON(JSONData.sharedjson.jsonRaw!) 
var mongoIdTest = json["resultset"]["account"]["mongoId"].string 

struct Root { 
    var timestamp: Int? 
    var resultset = ResultSet() 

    init() { 
     self.timestamp = json["timestamp"].int 
     println(json) 
    } 

} 

struct ResultSet { 
    var alert: String? 

    var account = Account() 
    var customer = Customer() 

    init() { 

    } 


} 

struct Account { 
    var mongoId: String? 

    init() { 
     mongoId = json["resultset"]["account"]["mongoId"].string 
    } 
} 

struct Locations { 

} 

struct Customer { 
    var account: String? 
    var address: String? 
    var id: String? 
    var loginId: String? 
    var mongoId: String? 
    var name: String? 

    var opco = Opco() 

    init() { 
     account = json["resultset"]["customer"]["account"].string 
     address = json["resultset"]["customer"]["address"].string 
     id = json["resultset"]["customer"]["id"].string 
     loginId = json["resultset"]["customer"]["loginId"].string 
     mongoId = json["resultset"]["customer"]["mongoId"].string 
     name = json["resultset"]["customer"]["name"].string 
    } 

} 

struct Opco { 
    var id: String? 
    var phone: String? 
    var cutOffTime: String? 
    var name: String? 
    var payerId: String? 

    init() { 
     id = json["resultset"]["customer"]["opco"]["id"].string 
     phone = json["resultset"]["customer"]["opco"]["phone"].string 
     cutOffTime = json["resultset"]["customer"]["opco"]["cutOffTime"].string 
     name = json["resultset"]["customer"]["opco"]["name"].string 
     payerId = json["resultset"]["customer"]["opco"]["payerId"].string 
    } 
} 

这样,您仍然可以使用自动填充和点符号来浏览您的层次结构。

编辑:我有一个来自我工作过的实际项目的数据结构添加到答案,希望这会给出一个更好的主意。请记住,我正在使用SwiftyJSON来拨打JSON()

编辑2:

这是我发现越来越JSON信息为斯威夫特字典,而无需使用其他一些库的方法。我不确定是否有另一种方法可以在不使用第三方库的情况下更轻松地完成。

var urlToRequest = "https://EXAMPLE.com/api/account.login?username=MY_USERNAME&password=Hunter2" 

if let json = NSData(contentsOfURL: NSURL(string: urlToRequest)!) { 

    // Parse JSON to Dictionary 
    var error: NSError? 
    let boardsDictionary = NSJSONSerialization.JSONObjectWithData(json, options: NSJSONReadingOptions.MutableContainers, error: &error) as? Dictionary<String, AnyObject> 
    fulljson = boardsDictionary 

    // Display all keys and values 
    println("Keys in User Data:") 
    for (key, value) in boardsDictionary! { 
     println("\(key)-------\(value)") 
    } 

    println(fulljson?["resultset"]) 
} 
else { 
    println("Test JSON nil: No Connection?") 
} 

该字典将作为您的Structs的输入。

+0

可以详细说明通过使用'struct'作为对象层次结构的含义吗? – wigging

+0

请参阅我编辑的答案,了解真实世界的示例 – Cole

+0

您仍在使用第三方库SwiftyJSON。正如我的问题所述,我想避免使用其他人的库来解析json。 – wigging