JSON

Swift JSON教程:使用JSON

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

2017-1-15 更新说明:本教程由 Luke Parham 更新为 Xcode 8.2 和 Swift 3。原文作者是 Attila Hegeds。 JavaScript Object Notation,简称 JSON,是一种常用的和

> 软件编程 > Swift >

Swift JSON教程:使用JSON 2017-05-12 17:27 出处:清屏网 人气: 

2017-1-15 更新说明:本教程由 Luke Parham 更新为 Xcode 8.2 和 Swift 3。原文作者是 Attila Hegedüs。

JavaScript Object Notation,简称 JSON,是一种常用的和 web 服务进行数据传输的方式。它易于使用和阅读,因此使用者众多。

以下列 JSON 为例:

[ { "person": { "name": "Dani", "age": "24" } }, { "person": { "name": "Ray", "age": "70" } } ]

在 O-C 中,解析这段 JSON 非常简单:

NSArray *json = [NSJSONSerialization JSONObjectWithData:JSONData options:kNilOptions error:nil]; NSString *age = json[0][@"person"][@"age"]; NSLog(@"Dani's age is %@", age);

在 Swift 中,要解析这段 JSON 就相当麻烦了,因为 Swift 有 optional 和类型安全的限制:

var json: [Any]? do { json = try JSONSerialization.jsonObject(with: data) } catch { print(error) } guard let item = json?.first as? [String: Any], let person = item["person"] as? [String: Any], let age = person["age"] as? Int else { return }

由于 guard 语句的存在,我们摆脱了厄运金字塔代码,但仍然需要些大量重复的代码才能访问 JSON 字符串中的数据。

在这篇 Swift JSON 教程里,我们一开始会用 Swift 的原生方法来解析 JSON——不使用任何第三方库。这实际上是苹果推荐的做法,因为 Swift 内置的工具在大部分场景下都够我们用了。

但是,就像每个人都会偶尔发出叛逆的声音,你也可以阅读本教程的下半部分,学习如何用 Gloss 框架节省你的时间。

注意:Gloss 只是众多 JSON 框架之一,但它却是一个好的设计模式的例子,我们会很好地证明这一点。

我们会用这两种方式对一个 JSON 文件进行解析,这个文件列出了美国 App 商店中上榜“25 个最流行的 app”的应用。

开始

因为学习 JSON 并不需要用户界面,因此我们所有的练习都是在 playground 中进行的。请在 这里 下载开始项目。

打开 Swift.playground 。

注意:你可能发现 playground 的项目导航器是关闭的。如果是这样,请用 command+1 打开它。

开始项目中有几个源文件和资源文件,这是为了将你的注意力集中在用 Swift 解析 JSON 的主题上来。看一下项目结构,以了解大概的内容:

  • Resources 文件夹中包含了你要解析的示例 JSON 文件。

  • topapps.json: 包含了 JSON 字符串。
  • Sources 文件夹中包含在主 playground 代码中能够调用的其它 Swift 源文件。将这些源文件放在 Sources 文件夹中是为了让你的 playground 干净、可读行更高。

  • App.swift:一个简单的 Swift 结构,代表了 app。
  • DataManager.swift: 负责网络或本地数据的抓取。在本教程中我们会用这个文件中的方法来加载 JSON 数据。
  • 你可以浏览一下 playground 中内容,再继续后面的内容!

    原生 Swift JSON 解析

    看完示例的 JSON 文件之后,我们可以来解析它并打印出排名第一的 app 是什么!

    使用 optional 的初始化方法

    首先,打开 App.swift。里面有一个简单的模型对象,定义了一个初始化方法,使用一个名字和一个链接作为初始化参数。

    这个 JSON 文件的 entry 下面有一个对象数组,每个对象都代表了一个 App 对象。

    根据这个结构,我们要在原来的初始化方法下面新增一个 optional 的初始化方法。

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

    这个初始化方法使用一个 [String:Any] 字典作为参数,这个字典用 JSON 数据来构造。这是可以的,有效的 JSON 要么是数组要么是单个值,但是我们已经确定它就是一个字典。

    然后,用 guard-let 语法去解析 JSON,取出其中的 name 和 link 值。

    最后,如果所有值都不为空,则填充模型对象的属性并返回模型。

    创建好模型之后,在项目导航器中点击 TopApps-Starter,打开主 playground 文件。

    首先,在 getTopAppsDataFromFileWithSuccess 方法的 success 块中添加 guard 语句:

    guard let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else { PlaygroundPage.current.finishExecution() }

    这里,我们用 jsonObject(with:options:) 方法将 JSON 字符串转换为 JSON 对象。

    然后,我们进行第一步解析,获得代表第一个 App 的 JSON 对象。

    guard let feed = json?["feed"] as? [String: Any], let apps = feed["entry"] as? [[String: Any]], let firstApp = apps.first else { PlaygroundPage.current.finishExecution() }

    这一步,我们首先取得最外层的 feed 对象,它的 entry 键中包含了 app 数组。

    最后,调用我们早先写好的 optional 的初始化函数获得排名第一的 app:

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

    运行 app,控制台输出如下:

    App(name: "Game of War - Fire Age", link: "https://itunes.apple.com/us/app/game-of-war-fire-age/id667728512?mt=8&uo=2")

    好了—— “Game of War – Fire Age” 就是在这个 JSON 文件中排名第一的 app。

    使用能够抛出异常的初始化方法

    在初始化失败时返回一个 nil 而不是实例对象,并不能告诉我们到底发生了什么错误。

    打开 App.swift ,定义一个错误枚举。

    enum SerializationError: Error { case missing(String) }

     

    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

    网友点评
    "