为什么我不能创建Array <[String:Any]>?使用Alamofire(Swift)

时间:2019-05-24 10:43:42

标签: json swift api alamofire

我创建了一个将获取所有数据的模型。 不幸的是,我被命令与Alamofire合作。 但是由于某种原因,未创建arrayOfItem数组。可能是什么原因?

这是value中的case .success(let value)here

func fetchData(from url: String) {

    guard let url = URL(string: url) else { return }

    request(url).validate().responseJSON { (dataResponse) in

        switch dataResponse.result {
        case .success(let value):
           // try to print --- value have data! 
            guard let arrayOfItem = value as? Array<[String : Any]> else { return }
           // try to print --- arrayOfItem is EMPTY!
            }
        case .failure(let error):
            print(error)
        }
    }
}

编辑:添加我的模型:

import Foundation

public struct Information: Decodable {

let copyright : String?
let numResults : Int?
let results : [Output]?
let status : String?

init(dict: [String: Any]) {

    let copyright = dict["copyright"] as? String
    let numResults = dict["numResults"] as? Int
    let results = dict["results"] as? [Output]
    let status = dict["status"] as? String

    self.copyright = copyright
    self.numResults = numResults
    self.results = results
    self.status = status
    }
}

import Foundation

public struct Output: Decodable {

let abstractField : String?
let adxKeywords : String?
let assetId : Int?
let byline : String?
let column : String?
let countType : String?
let desFacet : [String]?
let emailCount : Int?
let etaId : Int?
let geoFacet : [String]?
let id : Int?
let media : [Media]?
let nytdsection : String?
let orgFacet : String?
let perFacet : String?
let publishedDate : String?
let section : String?
let source : String?
let subsection : String?
let title : String?
let type : String?
let updated : String?
let uri : String?
let url : String?

init(dict: [String : Any]) {

    let abstractField = dict["abstractField"] as? String
    let adxKeywords = dict["adxKeywords"] as? String
    let assetId = dict["assetId"] as? Int
    let byline = dict["byline"] as? String
    let column = dict["column"] as? String
    let countType = dict["countType"] as? String
    let desFacet = dict["desFacet"] as? [String]
    let emailCount = dict["emailCount"] as? Int
    let etaId = dict["etaId"] as? Int
    let geoFacet = dict["geoFacet"] as? [String]
    let id = dict["id"] as? Int
    let media = dict[""] as? [Media]
    let nytdsection = dict["nytdsection"] as? String
    let orgFacet = dict["orgFacet"] as? String
    let perFacet = dict["perFacet"] as? String
    let publishedDate = dict["publishedDate"] as? String
    let section = dict["section"] as? String
    let source = dict["source"] as? String
    let subsection = dict["subsection"] as? String
    let title = dict["title"] as? String
    let type = dict["type"] as? String
    let updated = dict["updated"] as? String
    let uri = dict["uri"] as? String
    let url = dict["url"] as? String

    self.abstractField = abstractField
    self.adxKeywords = adxKeywords
    self.assetId = assetId
    self.byline = byline
    self.column = column
    self.countType = countType
    self.desFacet = desFacet
    self.emailCount = emailCount
    self.etaId = etaId
    self.geoFacet = geoFacet
    self.id = id
    self.media = media
    self.nytdsection = nytdsection
    self.orgFacet = orgFacet
    self.perFacet = perFacet
    self.publishedDate = publishedDate
    self.section = section
    self.source = source
    self.subsection = subsection
    self.title = title
    self.type = type
    self.updated = updated
    self.uri = uri
    self.url = url
    }
}
import Foundation

public struct Media: Decodable {

let approvedForSyndication : Bool?
let caption : String?
let copyright : String?
let mediaMetadata : [MediaMetadata]?
let subtype : String?
let type : String?

init(dict: [String: Any]) {
    let approvedForSyndication = dict["approvedForSyndication"] as? Bool
    let caption = dict["caption"] as? String
    let copyright = dict["copyright"] as? String
    let mediaMetadata = dict["mediaMetadata"] as? [MediaMetadata]
    let subtype = dict["subtype"] as? String
    let type = dict["type"] as? String

    self.approvedForSyndication = approvedForSyndication
    self.caption = caption
    self.copyright = copyright
    self.mediaMetadata = mediaMetadata
    self.subtype = subtype
    self.type = type

    }

}
import Foundation

public struct MediaMetadata: Decodable {

let format : String?
let height : Int?
let url : String?
let width : Int?

init(dict: [String: Any]) {
    let format = dict["format"] as? String
    let height = dict["height"] as? Int
    let url = dict["url"] as? String
    let width = dict["width"] as? Int

    self.format = format
    self.height = height
    self.url = url
    self.width = width
   }
}

2 个答案:

答案 0 :(得分:1)

符合json https://github.com/nytimes/public_api_specs/blob/master/most_popular_api/most_popular_api_v2.md

{   <<<< top root dictionary 
  "status":"OK",
  "copyright":"Copyright (c) 2010 The New York Times Company.  All Rights Reserved.",
  "num_results":94,
  "results":[{}]  <<<<< it's an array of dictionaries  
}

您的最高根是字典,而不是数组

if let res = value as? [String: Any], let results = res["results"] as? [[String: Any]] {
    print(results)
 }

最好使用Codable


Alamofire.request(URL(string:"urlStr")!, method: .get, parameters: [:], encoding: URLEncoding.default, headers: [:]).responseData { response in


    if response.result.isSuccess {

        guard let data = response.data else { return }

        do {

         let res = try JSONDecoder().decode(Information.self, from: data)
         print(res.results) 
        }
        catch {

            print(error)
        }
    } 
}

答案 1 :(得分:0)

实际JSON包含在value中,而不包含在中。因此使用:

guard let value = value as? [String : Any] else { return }
let arrayOfItem = value["result"] as? [[String : Any]]
print(arrayOfItem)

如果您添加JSON中获得的value,我将能够进行更多调试。

就像您说的value类型为Data一样,您可以简单地使用创建的Information类型(即

)获取所有数据
if let data = dataResponse.data {
    let information = try? JSONDecoder().decode(Information.self, from: value)
    print(information)
}