这是开发中非常常见的使用场景。
首先,我们需要知道要获取的json是什么样的,有两种方式得知:
第一,查询API文档:
一般在网站API文档中会介绍,如下:

第二种,通过使用crul -H获取:
这种方法需要使用到终端,上图也介绍了这个方式,如下:
$ curl -H "Accept: application/json" https://icanhazdadjoke.com/
{
"id": "R7UfaahVfFd",
"joke": "My dog used to chase people on a bike a lot. It got so bad I had to take his bike away.",
"status": 200
}
在我们知晓获取的JSON的格式之后,我们开始敲代码,首先头文件需要添加import Combine,完整头文件如下:
import SwiftUI
import Combine
然后,我们需要新建一个结构体来解读存放JSON格式的内容。以上面获取的为例,此JSON每条数据有三个元素组成:
id:需要注意这里的id是字符串类型。但是有的id是UUID类型。- joke:很显然这是字符串类型。
- status:整数类型。
然后我们写如下结构体(需要注意类型千万不能写错,不然会解码错误):
//如果获取的JSON文件中含有多条,我们也打算存放到一个数组中,这里需要加上Identifiable
struct Joke: Codable {
var id: String
var joke: String
var status: Int
}
然后我们用刚写好的Joke类型创建一个变量来获取和存储解码后的数据,内容全是空或0(你也可以根据需要添加合适的占位词)。并且出于方便,我直接写到视图的结构体中。
需要注意的是,演示中每次只获取了一条数据,我们可以使用单独的一个变量存放,每次刷新。但是平时我们更常使用数组来存放,如果这里使用数组存放的话,赋值的时候记得使用append而不是=。如果获取的JSON本身就包含好多条数据,那么还是用=。
@State private var jokes: Joke = Joke(id: "", joke: "", status: 0)
然后就是写一个函数来获取、解码和存储JSON数据了(由于需要使用上面我们新建的变量,所以要把这个函数和变量放在同一个struct或者class中),如下:
func getJoke() {
//设置需要获取的网址
let url = URL(string: "https://icanhazdadjoke.com/")!
//请求网址
var urlRequest = URLRequest(url:url)
//请求获取的类型是application/json(也就是JSON类型)
urlRequest.addValue("application/json",forHTTPHeaderField: "Accept")
//检查获取到的数据
URLSession.shared.dataTask(with: urlRequest) { data, response, error in
do {
//将数据赋值给jokeDate,并且判断数据不为空的话
if let jokeData = data {
//设置解码器为JSONDecoder()
let decoder = JSONDecoder()
//按照我们之前创建的Joke结构体的数据结构解码获取到的数据(如果我们打算放到数组中,给这里的Joke加个中括号)
let decodedData = try decoder.decode(Joke.self, from: jokeData)
//为了防止数据过多,加载时间过长,这里使用异步加载
DispatchQueue.main.async {
//将解码后的数据赋值给之前准备好的空变量
self.jokes = decodedData
}
} else {
//如果数据是空的,在控制台输出下面的文本
print("No data")
}
} catch {
print(error)
}
}.resume()
}
下面列出完整代码:
import SwiftUI
import Combine
struct Joke: Codable {
var id: String
var joke: String
var status: Int
}
struct ContentView: View {
//来获取和存储解码后的数据的Joke数据类型的变量
@State private var jokes: Joke = Joke(id: "", joke: "", status: 0)
var body: some View {
VStack {
Button("获取") {
getJoke()
}
VStack(alignment: .leading) {
Text(jokes.joke)
}
.onAppear(perform: {
//界面出现的时候加载数据
getJoke()
})
}
}
func getJoke() {
//设置需要获取的网址
let url = URL(string: "https://icanhazdadjoke.com/")!
//请求网址
var urlRequest = URLRequest(url:url)
//请求获取的类型是application/json(也就是JSON类型)
urlRequest.addValue("application/json",forHTTPHeaderField: "Accept")
//检查获取到的数据
URLSession.shared.dataTask(with: urlRequest) { data, response, error in
do {
//将数据赋值给jokeDate,并且判断数据不为空的话
if let jokeData = data {
//设置解码器为JSONDecoder()
let decoder = JSONDecoder()
//按照我们之前创建的Joke结构体的数据结构解码获取到的数据(如果我们打算放到数组中,给这里的Joke加个中括号)
let decodedData = try decoder.decode(Joke.self, from: jokeData)
//为了防止数据过多,加载时间过长,这里使用异步加载
DispatchQueue.main.async {
//将解码后的数据赋值给之前准备好的空变量
self.jokes = decodedData
}
} else {
//如果数据是空的,在控制台输出下面的文本
print("No data")
}
} catch {
print(error)
}
}.resume()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
这里是为了方便演示,所以写在一起了。一般情况下,我们需要新建一个swift文件来存放struct、请求获取和解码部分的代码。
希望能帮到有需要的人~
本文详细介绍了在iOS应用中如何获取并解析JSON数据。首先,可以通过查询API文档或使用curl命令获取JSON格式的数据。然后,定义一个结构体来匹配JSON的字段类型,如`Joke`结构体。接着,使用`URLSession`进行网络请求,通过`JSONDecoder`解码数据,并更新视图中的状态。最后,提供了完整的Swift代码示例,包括获取、解码和显示JSON数据的过程。

554

被折叠的 条评论
为什么被折叠?



