2015-07-21 82 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