Chad
Chad

Reputation: 163

Swift 3 JSON Array to Dictionary

I have a JSON result from Alamofire and SwiftyJSON and am trying to create a dictionary from it to create an array

JSON Result

JSON: [
  {
    "p_589b6a49a0bfd" : {
      "path" : "\/uploads\/588fa43eba3c9\/588fa43eba3c9_1486580297.jpg",
      "likes" : "0",
      "userid" : "588fa43eba3c9",
      "caption" : "Bae",
      "comments" : "0",
      "date" : "1486580297"
    }
  },
  {
    "p_589b7f1c540f1" : {
      "path" : "\/uploads\/588fa43eba3c9\/588fa43eba3c9_1486585628.jpg",
      "likes" : "0",
      "userid" : "588fa43eba3c9",
      "caption" : "Hot stuff bitch ",
      "comments" : "0",
      "date" : "1486585628"
    }
  }
]

Request/Response

Alamofire.request(BASE_URL + "index.php/feed/build", method: .get, headers: headers).responseJSON { response in

        switch response.result {

        case .success(let value):
            let json = JSON(value)
            print("JSON: \(json)")

        case .failure(let error):
            print(error)

        }

    }

I have then set up a simple class called 'FeedPost' which will store each of the elements in JSON response (this is the function in the FeedPost class)

init(postid: String, postData: Dictionary<String, AnyObject>) {

    self._postid = postid

    if let caption = postData["caption"] as? String {
        self._caption = caption
    }

    if let path = postData["path"] as? String {
        self._path = path
    }

    if let likes = postData["likes"] as? Int {
        self._likes = likes
    }

    if let comments = postData["comments"] as? Int {
        self._comments = comments
    }

    if let userid = postData["userid"] as? String {
        self._userid = userid
    }

    if let date = postData["date"] as? String {
        self._date = date
    }

}

I need to somehow cycle through the JSON to create a dictionary to pass to FeedPost then add each FeedPost to another array called Posts during the request. The string that starts with 'p_' I want to use as the postid

Upvotes: 1

Views: 6623

Answers (2)

Adnan Aftab
Adnan Aftab

Reputation: 14477

Below is the code which can be used for your case, This code is copied from playgrounds.

import UIKit

typealias JSONDictionary = [String: AnyObject]

    class Post {
        let id: String
        let userId: String?
        let date: Double?
        let caption: String?
        let comments: Double?
        let likes: Double?
        let path: String?

        init?(with dictionary: JSONDictionary) {
            guard let postId = dictionary.keys.first, let postInfo = dictionary[postId] as? JSONDictionary  else { return nil }

            self.id = postId
            self.userId = postInfo["userid"] as? String
            self.date = postInfo["date"] as? Double
            self.caption = postInfo["caption"] as? String
            self.comments = postInfo["comments"] as? Double
            self.likes = postInfo["likes"] as? Double
            self.path = postInfo["path"] as? String
        }
    }

Parsing JSON array will be like this.

case .success(let value):
    let jsonArray = value["JSON"] as? [JSONDictionary]
    let posts = jsonArray?.flatMap(Post.init(with:))
    print("Posts \(posts)"
case .failure: break

I have tried this using a local JSON file in a Playgrounds & code was something like this.

let url = Bundle.main.url(forResource: "data", withExtension: "json")
let data = try! Data(contentsOf: url!)

let jsonArray = try! JSONSerialization.jsonObject(with: data , options: .allowFragments) as? [JSONDictionary]
let posts = jsonArray?.flatMap(Post.init(with:))

Upvotes: 1

Nirav D
Nirav D

Reputation: 72410

With Alamofire response you have used SwiftyJSON and with your FeedPost init you are using swift native dictionary. So I'm suggesting you to either work with SwiftyJSON or with swift's native type. Since you have already added init with dictionary I'm answering your answer with native type.

  Alamofire.request(BASE_URL + "index.php/feed/build", method: .get, headers: headers).responseJSON { response in

    switch response.result {

    case .success(let value):
        If let dic = value as? [String: Any],
           let array = DIC["JSON"] as? [[String: Any]] {
               for item in array {
                    for (key, value) in item {
                          If let subDic = value as?  [String: Any] {
                                let obj =  FeedPost(postid: key, postData: subDic)
                          }
                    }
               }
        }
        print("JSON: \(json)")

    case .failure(let error):
        print(error)

    }

}

Note: Correct Dictionary notation for JSON in swift 3 is [String: Any] not [String: AnyObject] so change your init parameter postData's type to [String: Any].

Upvotes: 3

Related Questions