Swift 3 JSON 数组到字典

Swift 3 JSON Array to Dictionary

我有一个来自 Alamofire 和 Swifty 的 JSON 结果JSON,我正在尝试从中创建一个字典来创建一个数组

JSON 结果

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)

        }

    }

然后我设置了一个名为 'FeedPost' 的简单 class,它将存储 JSON 响应中的每个元素(这是 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
    }

}

我需要以某种方式循环遍历 JSON 以创建要传递给 FeedPost 的字典,然后在请求期间将每个 FeedPost 添加到另一个名为 Posts 的数组。以 'p_' 开头的字符串我想用作 postid

对于 Alamofire 响应,您使用的是 SwiftyJSON,对于您的 FeedPost init,您使用的是 swift 本机字典。所以我建议您使用 SwiftyJSON 或 swift 的原生类型。因为你已经用字典添加了 init,所以我用原生类型回答你的问题。

  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)

    }

}

注意: swift 3 中 JSON 的正确字典表示法是 [String: Any] 而不是 [String: AnyObject] 因此请更改您的初始参数postData 的类型为 [String: Any].

以下是可用于您的案例的代码,此代码是从 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
        }
    }

解析JSON数组会是这样

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

我在 Playgrounds 中使用本地 JSON 文件进行了尝试,代码是这样的。

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:))