Mikhail Tseitlin
Mikhail Tseitlin

Reputation: 109

Why I can't create Array<[String : Any]>? Work with Alamofire (Swift)

I created a model that will take all the data. Unfortunately I was ordered to work with Alamofire. But for some reason, an array of arrayOfItem is not created. What could be the reason?

This is value of 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)
        }
    }
}

Edited: add my model:

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
   }
}

Upvotes: 0

Views: 136

Answers (2)

PGDev
PGDev

Reputation: 24341

Actual JSON is contained in value not in . So use:

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

I'll be able to debug more if you add the JSON you're getting in value.

Like you said value is of type Data, you can simply get all the data using the Information type you created, i.e.

if let data = dataResponse.data {
    let information = try? JSONDecoder().decode(Information.self, from: value)
    print(information)
}

Upvotes: 0

Shehata Gamal
Shehata Gamal

Reputation: 100503

Accordifnong to the 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  
}

Your top root is a dictionary not an array

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

also it's better to use 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)
        }
    } 
}

Upvotes: 1

Related Questions