SwiftUI——获取网站api中的JSON,并且显示其中的文本

这是开发中非常常见的使用场景。

首先,我们需要知道要获取的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每条数据有三个元素组成:

  1. id:需要注意这里的id是字符串类型。但是有的id是UUID类型。
  2. joke:很显然这是字符串类型。
  3. 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、请求获取和解码部分的代码。

希望能帮到有需要的人~

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值