Ios 无法解析swift 3中的json数据?

Ios 无法解析swift 3中的json数据?,ios,json,parsing,swift3,Ios,Json,Parsing,Swift3,在这里,我编写了模型类,如果让jsonObj=try JSONSerialization.jsonObject(with:data!)作为?[String:AnyObject]{在这一行之后,它正在退出if循环,并且没有返回任何数据。有人能帮我解决这个问题吗 var relatedProductsModel : RelatedProductsViewed ? var relatedProductsApi = "http://www.json-generator.com/api/json/ge

在这里,我编写了模型类,如果让jsonObj=try JSONSerialization.jsonObject(with:data!)作为?[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)!
    }
}

您的API返回的JSON对象的根为数组。将其强制转换为字典的数组应该可以:

if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? Array<[String:Any]>, let jsonDict = jsonObj.first {
 self.relatedProductsModel = RelatedProductsViewed(dict: jsonDict)
 .....
}
如果让jsonObj=try JSONSerialization.jsonObject(使用:data!)作为数组,那么首先让jsonDict=jsonObj{
self.relatedProductsModel=relatedProductsView(dict:jsonDict)
.....
}
我知道这是Swift 3的要求,但在Swift 4中,Swift团队引入了将json对象解码为结构/类的协议。我用它创建了一个结构对象数组

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)
    }
}
struct-relatedProducts视图{
让productId:Int
让productName:String
让productSku:String
让产品价格:Int
让productsCount:Int
let relatedProducts:[相关产品]
}
扩展相关产品视图:可解码{
init(来自解码器:解码器)抛出{
let container=try decoder.container(keyedBy:RelatedProductsViewedKeys.self)
让productId=try container.decode(Int.self,forKey:.productId)
让productName=try container.decode(String.self,forKey:.productName)
让productSku=try container.decode(String.self,forKey:.productSku)
让productPrice=try container.decode(Int.self,forKey:.productPrice)
让ProductScont=try container.decode(Int.self,forKey:.ProductScont)
let relatedProducts=try container.decode([relatedProducts].self,forKey:.relatedProducts)
self.init(productId:productId,productName:productName,productSku:productSku,productPrice:productPrice,ProductScont:ProductScont,relatedProducts:relatedProducts)
}
枚举相关产品可视键:字符串、编码键{
case productId=“产品\u id”
case productName=“产品名称”
case productSku=“产品\u sku”
案例productPrice=“产品价格”
案例productsCount=“相关产品数量”
案例相关产品=“相关产品”
}
}
结构相关产品{
让relatedProductId:Int
let relatedProductPosition:Int
let relatedProductStatus:Int
让relatedProductUrl:URL
让relatedProductName:String
让imageUrl:URL
让relatedProductSku:字符串
let relatedProductPrice:Int
}
扩展相关产品:可解码{
init(来自解码器:解码器)抛出{
let container=try decoder.container(keyedBy:RelatedProductsKeys.self)
让relatedProductId=try container.decode(Int.self,forKey:.relatedProductId)
让relatedProductPosition=try container.decode(Int.self,forKey:.relatedProductPosition)
让relatedProductStatus=try container.decode(Int.self,forKey:.relatedProductStatus)
让relatedProductUrl=尝试container.decode(URL.self,forKey:.relatedProductUrl)
让relatedProductName=尝试container.decode(String.self,forKey:.relatedProductName)
让imageUrl=try container.decode(URL.self,forKey:.imageUrl)
让relatedProductSku=尝试container.decode(String.self,forKey:.relatedProductSku)
让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)
}
枚举相关产品密钥:字符串,编码键{
案例相关产品id=“相关产品id”
案例相关产品位置=“相关产品位置”
案例相关产品状态=“相关产品状态”
case-relatedProductUrl=“相关产品\u url”
case-relatedProductName=“相关产品名称”
case imageUrl=“image\u url”
案例相关产品sku=“相关产品”
案例相关产品价格=“相关产品价格”
}
}
类ViewController:UIViewController{
重写func viewDidLoad(){
super.viewDidLoad()
RelatedProductsVM()。下载JsonWithURL(“http://www.json-generator.com/api/json/get/ckagXVRLvS?indent=2")
}
}
类相关产品支持向量机{
var RelatedProductsView:[RelatedProductsView]?
func下载JsonWithURL(relatedApi:String){
打印(相关API)
guard let url=url(字符串:relatedApi)else{
回来
}
让task=URLSession.shared.dataTask(带:url){[weak self](数据、响应、错误)在
守卫让strongSelf=self-else{
回来
}
保护错误==nil,让数据=data else{
打印(错误!)
回来
}
strongSelf.relatedProductsViewed=strongSelf.productsViewedFrom(数据)
}
task.resume()
}
func ProductsView from(u-data:data)->[RelatedProductsView]{
返回try?JSONDecoder().decode(Array.self,from:data)
}
}

在您的链接问题中有答案。请学习阅读JSON。
{}
是字典,
[]
是数组。非常简单。你有没有读过建议的no i am now@vadianThank working@vadian@vadian:您能否将dupe目标直接指向,而不是指向它当前指向的已删除问题?在Swift 3+中,JSON字典是
[String:Any]
@vadian:yes。编辑答案,谢谢。