在这里,我写了模型类,但是在if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [String:AnyObject] {
之后,它在if循环之后退出并且没有返回任何数据,任何人都可以帮我解决这个问题吗?
var relatedProductsModel : RelatedProductsViewed ?
var relatedProductsApi = "http://www.json-generator.com/api/json/get/ckagXVRLvS?indent=2"
这是我的视图加载代码
self.relatedProductsDownloadJsonWithUrl(relatedApi: relatedProductsApi)
这是我的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)!
}
}
答案 0 :(得分:-1)
您的API以root身份返回包含数组的JSON对象。将它转换为Dictionary of Dictionary应该可以工作:
if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? Array<[String:Any]>, let jsonDict = jsonObj.first {
self.relatedProductsModel = RelatedProductsViewed(dict: jsonDict)
.....
}
我知道要求是Swift 3,但在Swift 4中,Swift团队引入了Decodable协议来将json对象解码为结构/类。我用它来创建struct对象的数组。
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)
}
}