用AnyObject初始化Swift类?来自NSJSONSerialization
问题描述:
我在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
?是否可以使用enum
或struct
来创建自定义类型来表示json对象?
答
因此,如果不使用第三方库,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的输入。
我知道你提到你不想使用第三方库,但我真的觉得你应该看看SwiftyJSON。它检查你的一切,并给你一个嵌套的字典。就我个人而言,我将使用这种方法将JSON映射到使用Structs的swift模型,在init中分配数据并嵌套Structs,从“Root()”开始嵌套,然后从那里开始下载。 – Cole
@Cole我知道SwiftyJSON和Argo,但我不想依赖它们。尽管使用'struct'代替swift模型可能是个好主意。 – wigging