iOS网络请求(Networking)及处理 Json

Posted 北冥鱼_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS网络请求(Networking)及处理 Json相关的知识,希望对你有一定的参考价值。

我们知道,空格不是 URL 中的有效字符, 除此,还有许多其它特殊字符也不是,例如 < 或 > 符号。因此对特殊字符必须进行转义,即 URL 编码。

例如,我们可以将空格编码为 + 号或字符序列 %20。

幸运的是,String 类现在已经可以进行这种编码了。 因此,我们只需添加一些代码就可以完成 URL 转码:

func iTunesURL(searchText: String) -> URL {
let encodedText = searchText.addingPercentEncoding(
withAllowedCharacters: CharacterSet.urlQueryAllowed)! // Add this
let urlString = String(
format: “https://itunes.apple.com/search?term=%@”,
encodedText) // Change this
let url = URL(string: urlString)
return url!
}

以上代码调用 addingPercentEncoding(withAllowedCharacters:) 方法,创建一个新字符串,其中的所有的特殊字符被转码。我们使用这个新字符串进行网络请求。

URL: ‘https://itunes.apple.com/search?term=pokemon%20go’

空格被转码为 %20。% 表示转义字符,20 是空格的 UTF-8 值。这里我们还可以尝试转码带有其它特殊字符(例如 # 和 * 甚至 Emoji)的 url,看看会发生什么。

解析 JSON 准备工作

从 Swift 4 开始,Codable 可以解析 JSON 了。

还记得如何使用 PropertyListDecoder 解码支持 Codable 协议的 plist 数据,以读取和保存清单中的数据吗? 好吧,属性列表并不是 Codable 支持的唯一开箱即用格式——它也支持 JSON!

为了让我们的 app 能够将 JSON 数据直接读入相关数据结构,我们需要将它设置为遵守 Codable 协议。

比如 SearchResult.swift:

class ResultArray: Codable {
var resultCount = 0
var results = SearchResult
}

class SearchResult: Codable {
var artistName: String? = “”
var trackName: String? = “”

var name: String {
return trackName ?? “”
}
}

解析 JSON

SearchViewController.swift:

func performStoreRequest(with url: URL) -> Data? { // Change to Data?
do {
return try Data(contentsOf:url) // Change this line
} catch {
. . .
}
}

func parse(data: Data) -> [SearchResult] {
do {
let decoder = JSONDecoder()
let result = try decoder.decode(
ResultArray.self, from: data)
return result.results
} catch {
print(“JSON Error: (error)”)
return []
}
}

我们使用 JSONDecoder 对象将来自服务器的响应数据转换为临时 ResultArray 对象,我们可以从中提取 results 属性。

处理 Json,优化如下:

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
if !searchBar.text!.isEmpty {
. . .
print(“URL: ‘(url)’”)
if let data = performStoreRequest(with: url) { // Modified
let results = parse(data: data) // New line
print(“Got results: (results)”) // New line
}
tableView.reloadData()
}
}

以上打印出的只是对象,没有显示对象内容。接下来我们继续优化,打印更多详细信息。

打印对象内容信息

修改 SearchResult.swift,令其遵守 CustomStringConvertible 协议:

class SearchResult: Codable, CustomStringConvertible {

CustomStringConvertible 协议允许对象具有自定义字符串表示形式。即,该协议允许对象具有描述对象及其属性的自定义字符串。

修改 SearchResult 类:

var description: String {
return “\\nResult - Name: (name), Artist Name: (artistName ?? “None”)”
}

注意上面代码中 ?? 运算符,它被称为空合( nil-coalescing)运算符。意思是,如果变量有值,则返回该变量,如果没有,则返回 ?? 运算符右侧的值作为默认值。

比如:

let username = loginName ?? “Guest”
loginName 表示为可选性,如果loginName 为空,则使用默认名称 Guest

再次打印,详细信息出来了:

URL: ‘https://itunes.apple.com/search?term=Metallica’
Got results: [
Result - Name: Enter Sandman, Artist Name: Metallica,
Result - Name: Nothing Else Matters, Artist Name: Metallica,
Result - Name: The Unforgiven, Artist Name: Metallica,
. . .

以上是关于iOS网络请求(Networking)及处理 Json的主要内容,如果未能解决你的问题,请参考以下文章

iOS网络操作与AFNetworking

iOS开发之AFNetworking 3.0.4使用

计算机网络Stanford CS144 Lab0 : networking warmup 学习记录

iOS AFNetWorking中block执行完后再执行其它操作

21-K8S Basic-网络插件体系及flannel基础

Redis单线程为何可以处理大量请求?