JSON

Swift JSON教程:使用JSON(2)

字号+ 作者:H5之家 来源:H5之家 2017-05-15 18:00 我要评论( )

然后,将 optional 初始化方法换成下面的初始化方法。当 JSON 参数中包含有空值时,这个初始化方法会抛出一个上面定义的错误。 public init(json: [String: Any]) throws { //1 guard let container = json[im:name

然后,将 optional 初始化方法换成下面的初始化方法。当 JSON 参数中包含有空值时,这个初始化方法会抛出一个上面定义的错误。

public init(json: [String: Any]) throws { //1 guard let container = json["im:name"] as? [String: Any], let name = container["label"] as? String else { throw SerializationError.missing("name") } guard let id = json["id"] as? [String: Any], let link = id["label"] as? String else { throw SerializationError.missing("link") } //2 self.name = name self.link = link }

这里,我们为每个属性使用一个单独的 guard 语句。当传入的 JSON 参数中包含无效的值时,抛出一个该属性未找到的错误。

最后,如果没有任何异常发生,我们填充属性,返回有效的实例对象。

打开主 playground 将这 2 句:

let app = App(json: firstApp) print(app ?? "Failed to initialize")

替换为:

do { let app = try App(json: firstApp) print(app) } catch let error { print(error) }

这里需要使用 do-catch 块。如果初始化成功,我们不需要担心 app 会出现控制。如果初始化失败,我们会得到一个有用的错误信息,而不是一个空对象。

要查看初始化失败的效果,请将 App(json: firstApp) 换成 App(json: [:])。

用 Gloss 解析 JSON

你已经体验了如果将 JSON 解析成自己的模型对象,接下来我们来尝试另一种解析方法。

为了保持美观、大方,我们创建一个新的 playground 叫做 Gloss.playground。然后,将 topapps.json 拷贝到 Resources 目录,将 DataManager.swift 拷贝到 Source。

将 Gloss 集成到项目中

将 Gloss 集成到项目或 playground 中很简单:

  • 从 这里 下载 Gloss 源代码 zip 包。
  • 解压缩,然后将 Gloss-master/Sources 文件夹拖到 playround 的 Source 目录。
  • 项目导航器看起来是这个样子:

    https://koenig-media.raywenderlich.com/uploads/2017/01/Screen-Shot-2017-01-16-at-12.56.00-AM-411x500.png’ width=’300’/>

    这就好了!下载可以在我们的 playground 中使用 Gloss 了,这是一种“简单”的 JSON 解析方法!

    将 JSON 映射为对象

    首先,必须定义模型对象和 JSON 对象的映射方式。

    模型对象必须实现 Decodeable 协议,这个协议允许它们从 JSON 进行解码。要实现这个协议,需要实现 init?(json: JSON) 初始化方法。

    注意:打开 Gloss.swift。在 Decodable 协议中,如果用 +左键点击 JSON 查看它的定义,你会看到它仅仅是在同一个文件中被定义为 [String: Any] 的别名。

    TopApps

    TopApps 模型用于表示顶级对象,它只包含一个键值对:

    { "feed": { ... } }

    创建一个新的 Swift 文件,名为 TopApps.swift,保存到 playground 的 Sources 文件夹下。编辑它的代码为:

    public struct TopApps: Decodable { // 1 public let feed: Feed? // 2 public init?(json: JSON) { feed = "feed" <~~ json } }

    首先要定义模型所用到的属性。这里我们只有一个属性。先别管 Feed 报出的异常,我们会在后面定义 Feed 模型类。

    为了实现 Decodable 协议,TopApps 必须实现 optional 的初始化方法。

    可能 <~~ 运算符有点陌生。它是 Encode 运算符,在 Gloss 的 Operators.swift 文件中定义。因为 Feed 也是一个 Decodable 类型,Gloss 可以把编码工作交给这个对象。

    Feed

    Feed 对象和顶级对象很像。它有两个键值对,但由于我们只对上榜的 25 个 app 感兴趣,因此 author 对象其实是没有必要处理的。

    { "author": { ... }, "entry": [ ... ] }

    新建一个 Swift 文件,名为 Feed.swift,保存到 Sources 文件夹下:

    public struct Feed: Decodable { public let entries: [App]? public init?(json: JSON) { entries = "entry" <~~ json } } App

    App 是最后一个模型对象,它表示一个 app 对象:

    { "im:name": { "label": "Game of War - Fire Age" }, "id": { "label": "https://itunes.apple.com/us/app/game-of-war-fire-age/id667728512?mt=8&uo=2", ... }, ... }

    新建 App.swift 文件,保存到 Sources 文件夹下,编辑它的代码为:

    public struct App: Decodable { // 1 public let name: String public let link: String public init?(json: JSON) { // 2 guard let container: JSON = "im:name" <~~ json, let id: JSON = "id" <~~ json else { return nil } guard let name: String = "label" <~~ container, let link: String = "label" <~~ id else { return nil } self.name = name self.link = link } }

    Feed 和 TopApps 都使用 optional 属性。但当我们确定 JSON 中某个值肯定存在时,可以用非 optional 的属性。

    我们并不需要为 JSON 的每个成员都创建一个模型对象。例如,这里就没有为 in:name 和 id 创建模型对象。当我们使用非可空对象和嵌套对象时,一定要进行非空校验。

    现在模型类已经准备好了,我们该让 Gloss 干活了!

    打开 playground 文件,将它的内容替换为:

    import UIKit import PlaygroundSupport PlaygroundPage.current.needsIndefiniteExecution = true URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil) DataManager.getTopAppsDataFromFileWithSuccess { (data) -> Void in // 1 var json: Any do { json = try JSONSerialization.jsonObject(with: data) } catch { print(error) PlaygroundPage.current.finishExecution() } guard let dictionary = json as? [String: Any] else { PlaygroundPage.current.finishExecution() } // 2 guard let topApps = TopApps(json: dictionary) else { print("Error initializing object") PlaygroundPage.current.finishExecution() } // 3 guard let firstItem = topApps.feed?.entries?.first else { print("No such item") PlaygroundPage.current.finishExecution() } print(firstItem) PlaygroundPage.current.finishExecution() }
  • 首先和之前一样,调用 JSONSerialization 反序列化数据。
  • 然后,用这个 JSON 对象创建一个 TopApps。
  • 最后,调用我们创建的模型对象的 feed 属性的 entries 属性,获得第一个 app.
  • 这就是全部我们需要做的工作!

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • JSON教程、使用手册

      JSON教程、使用手册

      2017-05-16 17:04

    • Swift JSON 教程:使用 JSON

      Swift JSON 教程:使用 JSON

      2017-05-15 17:03

    • ABAP 中JSON格式的变换与解析

      ABAP 中JSON格式的变换与解析

      2017-05-14 16:02

    • JSONObject使用方法详解

      JSONObject使用方法详解

      2017-05-14 14:00

    网友点评