【问题标题】:How to parse json data include page number by codable in Swift 4 and Alamofire如何在 Swift 4 和 Alamofire 中通过可编码解析 json 数据包括页码
【发布时间】:2019-06-20 16:51:46
【问题描述】:

我是 Swift 的新手,我很困惑通过使用 Codable 来获取数据而不是使用 SwiftyJson。 格式 Json 数据类型如下:

    {
  "current_page": 1,
  "total_page": 407,
  "new_entries": [
    {
      "id": 10174,
      "title": "Hello",
      "description": "Hello",
      "categories": "women",
      "image": "imagelink",
      "url": "urllink",
      "date": "time",
      "is_favorite": false
    },
    {
      "id": 9237,
      "title": "hi",
      "description": "hi",
      "categories": "skincare",
      "image": "imagelink",
      "url": "url",
      "date": "time",
      "is_favorite": false
    },

那么我如何获取条目并解码并保存为可编码的,如

let decoder = JSONDecoder()

            do {
                let feed = try decoder.decode(Feed.self, from: jsonData)
                print(feed.title)
            } catch {
                print(error.localizedDescription)
            }

我停在下面,不知道如何将 json["new_entries"] 转换为字符串类型和解码。

    Alamofire.request("https://abc.jp/api/category/women_all/?page=1", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in
        debugPrint(response)

        if let JSON = response.result.value as? NSDictionary {
            GlobalVariables.sharedManager.pageCurr = JSON["current_page"] as? Int
            GlobalVariables.sharedManager.pageTotal = JSON["total_page"] as? Int

            if let entries = JSON["new_entries"] as? NSArray{

                for entry in entries {

                    if let entry = entry as? NSDictionary {

                        for (key, value) in entry {
                            print("\(key) - \(value)")
                        }
                    }
                }
            }
        }

我的提要结构

struct Feed: Codable {

    enum CodingKeys: String, CodingKey {
        case id
        case title
        case description
        case categories
        case image
        case url
        case date
        case favorite = "is_favorite"
    }

    let id: Int
    let title: String
    let description: String
    let categories: String
    let image: String
    let url: String
    let date: String
    let favorite: Bool
}

非常感谢。

【问题讨论】:

  • Feed 是如何定义的?
  • 谢谢你,我会编辑我的帖子

标签: ios swift codable


【解决方案1】:

你需要

struct Root: Codable {
    let currentPage, totalPage: Int
    let newEntries: [Feed]

}

struct Feed: Codable {
    let id: Int
    let title, description, categories, image: String
    let url, date: String
}

Alamofire.request("https://abc.jp/api/category/women_all/?page=1", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseData { response in
      debugPrint(response)
      guard let data = response.data else { return } 
        do { 
            let de = JSONDecoder()
            de.keyDecodingStrategy = .convertFromSnakeCase
            let res = try de.decode(Root.self, from: data) 
            print(res.currentPage)
            print(res.totalPage)
            print(res.newEntries)
        }
        catch { 
            print(error)
        }
}

正确的json

{
    "current_page": 1,
    "total_page": 407,
    "new_entries": [
    {
    "id": 10174,
    "title": "Hello",
    "description": "Hello",
    "categories": "women",
    "image": "imagelink",
    "url": "urllink",
    "date": "time",
    "is_favorite": false
    },
    {
    "id": 9237,
    "title": "hi",
    "description": "hi",
    "categories": "skincare",
    "image": "imagelink",
    "url": "url",
    "date": "time",
    "is_favorite": false
    }]
}

【讨论】:

  • 亲爱的@Sh_Khan,非常感谢你帮助我,但我得到了这样的错误:'dataCorrupted(Swift.DecodingError.Context(codingPath:[],debugDescription:“给定的数据不是有效的 JSON。”,基础错误:可选(错误域 = NSCocoaErrorDomain 代码 = 3840“JSON 文本未以数组或对象开头,并且允许未设置片段的选项。” UserInfo={NSDebugDescription=JSON 文本未以数组或对象开头,并且允许未设置片段的选项。})))'
  • 似乎响应对 codable 无效,您的代码中是否有任何内容或 for -loop 触发器???
  • 对不起,我的 url 链接出错了^^你现在是我的老板 :)) 非常感谢
【解决方案2】:

我添加了一个新的主结构

struct Main: Codable {
  let currentPage: Int
  let totalPage: Int
  let feeds: [Feed]

  enum CodingKeys: String, CodingKey {
    case currentPage = "current_page"
    case totalPage = "total_page"
    case feeds = "new_entries"
  }

}

然后使用该结构进行解码

let decoder = JSONDecoder()
do {
  let result = try decoder.decode(Main.self, from: jsonData)
  print(result.currentPage)
} catch {
  print(error)
}

或以 alamofire 为例

Alamofire.request("https://abc.jp/api/category/women_all/?page=1", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseData { response in
  guard let data = response.data else { return } 
  do { 
    let decoder = JSONDecoder()
    let result = try decoder.decode(Main.self, from: data)
    GlobalVariables.sharedManager.pageCurr = result.currentPage
    GlobalVariables.sharedManager.pageTotal = result.totalPage
    for feed in result.feeds {
      print(feed.id)
      //etc
    }
  } catch {
     print(error)
     // other error handling
  }

【讨论】:

  • 感谢@Joakim Danielson,您的代码也很有效!感谢您的帮助
猜你喜欢
  • 2023-04-02
  • 2018-06-28
  • 1970-01-01
  • 1970-01-01
  • 2018-09-05
  • 2019-04-26
  • 2019-10-11
  • 2020-08-15
  • 1970-01-01
相关资源
最近更新 更多