2016-03-06 45 views
1

從api獲取數據的同時,我可以得到響應例如產品數組或產生錯誤的字典。如何在swift中解析未知的json數據類型2

如果一切合適的API發送的產品陣列:

[ 
"Product1": 
{ 
name = "someting", 
price = 100, 
discount = 10%, 
images = [image1,image2] 
}, 
"Product2": 
{ 
name = "someting", 
price = 100, 
discount = 10%, 
images = [image1,image2] 
} 
] 

但是,如果某些錯誤發生它發送字典中的錯誤信息和代碼:

{ 
error_message = "message" 
error_code = 202 
} 

我正在使用此代碼將JSON數據轉換爲數組:

do { 
    let jsonDict = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray{ 
       //Some code.... 
    } catch let error as NSError { 
    print("JSON Error: \(error.localizedDescription)")  
} 

但如果我得到錯誤字典它崩潰。

問題: 1.如何知道接收到的數據是數組還是字典? 2.一些時間甚至鍵或值可以缺少這樣檢查的價值就變得非常冗長的代碼,如:

if let productsArray = jsonObject as? NSArray{ 
    if let product1 = productsArray[0] as? NSDictionary{ 
     if let imagesArray = product1["image"] as? NSArray{ 
      if let imageUrl = imagesArray[0] as? String{ 
       //Code .... 
      } 
     } 
    } 
} 

我讀到後衛關鍵字降低,如果條件,但我沒有明確的想法如何在這裏使用。

+0

過得好的JSON? - 你能看到http響應狀態碼嗎? –

+0

@thefredelement是的,我可以得到響應錯誤代碼,它是由我的服務器發送的特定於任何產品的請求,例如試圖獲取不可用的產品詳細信息。 –

+0

我會推薦從Github上下載SwiftyJSON庫,所以你不需要有10個嵌套層次的if-let's –

回答

2

問題1: 一個try catch,添加一個如果讓鑄造的對象的NSDictionary的NSArray或類似:

do { 
    let jsonObject = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) 
    if let jsonDict = jsonObject as? NSDictionary { 
     // Do smthg. 
    } 
    if let jsonArray = jsonObject as? NSArray { 
     // Do smthg. 
    } 
}catch { 
//... 
} 

對於問題2: 我認爲後衛不會幫你。它需要像其他語句中的return/break一樣使用smthg。如果你不想拋出你的方法,如果你的一個值不可用,你必須使用這個冗長的,如果讓代碼樣式。 也許在您的情況下,最佳做法是設置具有可選屬性的產品數據模型。

Class product { 
var name:String? 
var image:[NSData]? // maybe UIImage or smthg. 
var price:Int? 
var discount:Int? 

    init(jsonDic:NSDictionary){ 
// if it's not there it would be nil 
    self.name = jsonDic["name"] as? String 
    self.image = jsonDic["image"] as? NSArray 
    self.discount = jsonDic["discount"] as? Int 
    self.price = jsonDic["price"] as? Int 
    } 
} 

現在你可以載入你的數據這些模型沒有,如果讓等。 但是,如果你想讀這些值你要是讓瞭如果不爲零籤使用。 針對你的情況的init應該是這樣的: 一下添加到做catch塊,如果讓說明(?......作爲NSArray的// DO smthg)

for item in jsonArray { 
    guard let jsonDic = item as? NSDictionary else { return } 
// if you dont know every key you can just iterate through this dictionary 
    for (_,value) in jsonDic { 
     guard let jsonDicValues = value as? NSDictionary else { return } 
     productArray.append(Product(jsonDic: jsonDicValues) 
    } 
} 

正如我所說的,知道你得到了整個如果讓從模型中讀取的東西時不寫(閱讀JSON)

+0

好吧,稍微修改一下,如果讓它幫助我執行字典或數組部分 –

+0

是的,好吧,它是完全一樣的,bcz都不能變爲真(不爲零) –

+0

如果你給我例如while將數據存儲在數據模型產品中,因爲即使通過使用數據模型我也必須通過檢查 –

0

您可以捕捉到您的回覆。如果你的響應是類字典的話,如果你的響應是一個類數組,那麼將它分配爲字典else,把它分配給數組。祝你好運。

+0

我知道如何在Objective-C中做但是我沒有在swift中 –

1

你有幾件事會在這裏,一個,我會分析你的服務器的HTTP響應狀態代碼,如果你收到的資料表明你將有很好的數據

// In practical scenarios, this may be a range 
if statusCode != 200 { 
// Handle a scenario where you don't have good data. 
return 
} 

其次狀態代碼只嘗試處理數據,我警惕的響應,它看起來像你已經把它命名爲「數據」,例如:

guard let receivedData = data else { 
return 
} 

從這一點上,你可以使用receivedData不變。

Here'd我會嘗試使用NSJSONSeralization,像你一樣,但鑄造成一個斯威夫特字典,像這樣:

if let responseDictionary = try? NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? [String:AnyObject] { 

// Here you can try to access keys on the response 
// You can try things like 
let products = responseDictionary?["products"] as? [[String:AnyObject]] 

for product in products { 

    let productName = product["name"] as? String 

    if productName == nil { 
    continue 
    } 

    let newProduct = Product(name: productName) 
    // Do something with newly processed data 

} 

} 

我試圖將一般和還告訴你一個例子後衛。

1

首先我建議使用SwiftyJSON莢或類直接到您的Xcode,它的作品像一個魅力,你贏了不需要把東西放下來判斷你是否有字符串或字典或其他什麼。它是黃金。

一旦你有了你的JSON,你可以使用這個我創建的遞歸函數,它完全符合你的需要。它將任何Json變成一本字典。我主要用它來將數據保存到Firebase中,而無需解析所有內容。

已經導入SwiftyJSON到項目並添加導入SwiftyJSON您斯威夫特文件後就可以:

let json = JSON(value) // Value is the json structure you received from API. 
var myDictionary = [String:AnyObject]() 
myDictionary = json2dic(json) 

//JSON is created using the awesome SwiftyJSON pod 
func json2dic(j: JSON) -> [String:AnyObject] { 
    var post = [String:AnyObject]() 
    for (key, object) in j { 
     post[key] = object.stringValue 
     if object.stringValue == "" { 
      post[key] = json2dic(object) 
     } 
    } 
    return post 
}