2017-10-12 5 views
0

ここで私はモデルクラスを書いていましたが、if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [String:AnyObject] {の後に、ループから抜け出していて、データを返さない人は誰でもこの問題を解決する方法を教えてくれますか?ここjsonデータを迅速に解析することができませんでしたか?

var relatedProductsModel : RelatedProductsViewed ? 
var relatedProductsApi = "http://www.json-generator.com/api/json/get/ckagXVRLvS?indent=2" 

は、私の見解は、負荷コードここ

self.relatedProductsDownloadJsonWithUrl(relatedApi: relatedProductsApi) 

をやっているあなたのAPIは、ルートとして配列をJSONオブジェクトを返すデータに

func relatedProductsDownloadJsonWithUrl(relatedApi: String){ 
     print(relatedApi) 
     let url = URL(string: relatedApi)! 
     let task = URLSession.shared.dataTask(with: url) { (data, response, error) in 
      if error != nil { print(error!); return } 
      do { 
       if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [String:AnyObject] { 
        self.relatedProductsModel = RelatedProductsViewed(dict: jsonObj as [String : AnyObject]) 
        DispatchQueue.main.async { 
         print(self.relatedProductsModel) 
        } 
       } 
      } catch { 
       print(error) 
      } 
     } 
     task.resume() 
    } 
struct RelatedProductsViewed { 

    let productId : Int 
    let productName : String 
    let productSku : String 
    let productPrice : Int 
    let productsCount : Int 
    var relatedProducts = [RelatedProducts]() 

    init(dict : [String:Any]) { 
     if let arr = dict["related_products"] as? [[String: AnyObject]]{ 
      var filterArr = [RelatedProducts]() 
      for obj in arr { 
       filterArr.append(RelatedProducts(dict: obj)!) 
      } 
      self.relatedProducts = filterArr 
     } else { 
      self.relatedProducts = [RelatedProducts]() 
     } 
     self.productId = (dict["product_id"] as? Int)! 
     self.productName = (dict["product_name"] as? String)! 
     self.productSku = (dict["product_sku"] as? String)! 
     self.productPrice = (dict["product_price"] as? Int)! 
     self.productsCount = (dict["related_products_count"] as? Int)! 
    } 
} 
+2

** **リンク先の質問には回答があります。 JSONを読んでください。 '{}'は辞書です、 '[]'は配列です。それは超簡単。提案された[Swift 3でJSONを正しく解析する](https://stackoverflow.com/questions/39423367/correctly-parsing-json-in-swift-3) – vadian

+0

いいえ私は今@vadianを読んでいます –

+0

ありがとうございました@vadian –

答えて

-1

を取得するための私のJSON関数です。辞書の配列にキャストすると、動作するはずです:

if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? Array<[String:Any]>, let jsonDict = jsonObj.first { 
self.relatedProductsModel = RelatedProductsViewed(dict: jsonDict) 
..... 
} 

を私は要件がスウィフト3のためではなくスウィフト4スウィフトのチームである知っている構造体/クラスにJSONオブジェクトをデコードするDecodableプロトコルを導入しています。私はあなたの構造体オブジェクトの配列を作成するために使用しました。

struct RelatedProductsViewed { 
    let productId : Int 
    let productName : String 
    let productSku : String 
    let productPrice : Int 
    let productsCount : Int 
    let relatedProducts:[RelatedProducts] 
} 

extension RelatedProductsViewed:Decodable { 
    init(from decoder: Decoder) throws { 
     let container = try decoder.container(keyedBy: RelatedProductsViewedKeys.self) 
     let productId = try container.decode(Int.self, forKey: .productId) 
     let productName = try container.decode(String.self, forKey: .productName) 
     let productSku = try container.decode(String.self, forKey: .productSku) 
     let productPrice = try container.decode(Int.self, forKey: .productPrice) 
     let productsCount = try container.decode(Int.self, forKey: .productsCount) 
     let relatedProducts = try container.decode([RelatedProducts].self, forKey: .relatedProducts) 

     self.init(productId: productId, productName: productName, productSku: productSku, productPrice: productPrice, productsCount: productsCount, relatedProducts: relatedProducts) 
    } 

    enum RelatedProductsViewedKeys: String, CodingKey { 
     case productId = "product_id" 
     case productName = "product_name" 
     case productSku = "product_sku" 
     case productPrice = "product_price" 
     case productsCount = "related_produts_count" 
     case relatedProducts = "related_produts" 
    } 
} 

struct RelatedProducts { 
    let relatedProductId:Int 
    let relatedProductPosition:Int 
    let relatedProductStatus:Int 
    let relatedProductUrl:URL 
    let relatedProductName:String 
    let imageUrl:URL 
    let relatedProductSku:String 
    let relatedProductPrice:Int 
} 

extension RelatedProducts:Decodable { 

    init(from decoder: Decoder) throws { 
     let container = try decoder.container(keyedBy: RelatedProductsKeys.self) 
     let relatedProductId = try container.decode(Int.self, forKey: .relatedProductId) 
     let relatedProductPosition = try container.decode(Int.self, forKey: .relatedProductPosition) 
     let relatedProductStatus = try container.decode(Int.self, forKey: .relatedProductStatus) 
     let relatedProductUrl = try container.decode(URL.self, forKey: .relatedProductUrl) 
     let relatedProductName = try container.decode(String.self, forKey: .relatedProductName) 
     let imageUrl = try container.decode(URL.self, forKey: .imageUrl) 
     let relatedProductSku = try container.decode(String.self, forKey: .relatedProductSku) 
     let relatedProductPrice = try container.decode(Int.self, forKey: .relatedProductPrice) 
     self.init(relatedProductId: relatedProductId, relatedProductPosition: relatedProductPosition, relatedProductStatus: relatedProductStatus, relatedProductUrl: relatedProductUrl, relatedProductName: relatedProductName, imageUrl: imageUrl, relatedProductSku: relatedProductSku, relatedProductPrice: relatedProductPrice) 
    } 

    enum RelatedProductsKeys: String, CodingKey { 
     case relatedProductId = "related_product_id" 
     case relatedProductPosition = "related_product_position" 
     case relatedProductStatus = "related_product_status" 
     case relatedProductUrl = "related_product_url" 
     case relatedProductName = "related_product_name" 
     case imageUrl = "image_url" 
     case relatedProductSku = "related_product_sku" 
     case relatedProductPrice = "related_product_price" 
    } 
} 

class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     RelatedProductsVM().downloadJsonWithUrl("http://www.json-generator.com/api/json/get/ckagXVRLvS?indent=2") 
    } 


} 

class RelatedProductsVM { 
    var relatedProductsViewed:[RelatedProductsViewed]? 

    func downloadJsonWithUrl(_ relatedApi: String) { 
     print(relatedApi) 
     guard let url = URL(string: relatedApi) else { 
      return 
     } 

     let task = URLSession.shared.dataTask(with: url) {[weak self] (data, response, error) in 
      guard let strongSelf = self else { 
       return 
      } 
      guard error == nil, let data = data else { 
       print(error!) 
       return 
      } 
      strongSelf.relatedProductsViewed = strongSelf.productsViewedFrom(data) 
     } 
     task.resume() 
    } 

    func productsViewedFrom(_ data:Data) -> [RelatedProductsViewed]? { 
     return try? JSONDecoder().decode(Array<RelatedProductsViewed>.self, from: data) 
    } 
} 
+0

スウィフト3+でJSON辞書は '[String:Any]' – vadian

+0

@vadian:yesです。答えを編集して、ありがとう。 –