通过swift使用高德天气服务

调用高德免费的天气api可以返回json数据,经过解析后在iOS客户端上显示。

首先查看官网的文档。

使用说明

第一步,申请”web服务 API”密钥(Key);

第二步,拼接HTTP请求URL,第一步申请的Key需作为必填参数一同发送;

第三步,接收HTTP请求返回的数据(JSON或XML格式),解析数据。

为了尽可能简单化,这次使用的是web服务,而不是iOS sdk。

1.申请key

1.新建应用

2.点添加

3.这里注意选择的是web服务端


4.然后就能看到申请的key了


2.查看返回json数据

用户示例:
https://restapi.amap.com/v3/weather/weatherInfo?city=120118&key=<用户key>
https://restapi.amap.com/v3/weather/weatherInfo?city=120118&key=c96cd1437049382a4dbc1fb2aaea597c
点击上面链接就可在浏览器看到返回的json数据了。

3.Xcode下载并解析json

返回的天气参数可见官网,但为了简单只使用了四个返回参数

1.定义结构体
//省份、城市、天气和温度
struct Lives: Identifiable {
    var id = UUID()
    var province: String
    var city: String
    var weather: String
    var temperature: String

    //swift使用变量前必须初始化
    init(province: String, city: String, weather: String, temperature: String) {
        self.province = province
        self.city = city
        self.weather = weather
        self.temperature = temperature
    }
}
//映射
extension Lives: Codable {
    enum CodingKeys: String, CodingKey {
        case province
        case city
        case weather
        case temperature
    }
    
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)

        province = try values.decode(String.self, forKey: .province)
        city = try values.decode(String.self, forKey: .city)
        weather = try values.decode(String.self, forKey: .weather)
        temperature = try values.decode(String.self, forKey: .temperature)
    }
}

看起来应该是这样的


2.下载并解析
import Foundation

class Weather: Decodable, ObservableObject {
    @Published var lives: [Lives] = []

    //天气api的URL
    private static var gaodeURL = "https://restapi.amap.com/v3/weather/weatherInfo?city=120118&extensions=base&key=9762eb7dbdc2cde20a59f1ef8a590d28"
    
    //以下三条为了防止出现错误 Type 'Weather' does not conform to protocol 'Decodable'
    enum CodingKeys: CodingKey {
        case lives
    }
    required init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        lives = try values.decode([Lives].self, forKey: .lives)
    }
    init() {
    }
    
    //下载json
    func getJSON() {
        guard let gaodeUrl = URL(string: Self.gaodeURL) else {
            return
        }
        let request = URLRequest(url: gaodeUrl)
        let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) -> Void in

            if let error = error {
                print(error)
                return
            }

            //调用parseJson()来解析json
            if let data = data {
                DispatchQueue.main.async {
                    self.lives = self.parseJson(data: data)
                }
                
            }
        })
        //启动
        task.resume()
    }
    //解析json
    func parseJson(data: Data) -> [Lives] {

        let decoder = JSONDecoder()

        do {
            let loanStore = try decoder.decode(Weather.self, from: data)
            self.lives = loanStore.lives

        } catch {
            print(error)
        }

        return lives
    }
}

看起来应该是这样的


3.视图
//接收一个Lives类型数据并将其显示
struct SingleView: View {
    
    var loan: Lives
    
    var body: some View {
        HStack {
            //地理位置
            VStack(alignment: .leading) {
                Text(loan.province)
                Text(loan.city)
            }
            
            Spacer()
            
            //天气情况
            VStack {
                Text(loan.weather)
                Text("\(loan.temperature)°C")
            }
        }
        .foregroundColor(.white)
        .padding()
        .background(Color.green)
        .cornerRadius(6)
    }
}
//主视图
struct WeatherView: View {
    @ObservedObject var weather = Weather()
    
    var body: some View {
        NavigationView {
            ForEach(weather.lives) { item in
                SingleView(loan: item)
                    .padding()
            }
        }
        .onAppear() {
            self.weather.getJSON()
        }
    }
}

看起来应该是这样的


posted @ 2021-10-14 16:20  skypang  阅读(74)  评论(0)    收藏  举报  来源