gpt4 book ai didi

ios - OpenWeather API 中为零

转载 作者:行者123 更新时间:2023-11-28 13:40:58 28 4
gpt4 key购买 nike

我刚开始学习 SwiftiOS,我的天气应用程序出现问题。我正在尝试获取天气数据并在控制台中打印,但仍然是零,我不知道可能出了什么问题。我试图更改模型,粘贴所有 url,但仍然为零。有时app发送数据没有应答,但有时是应答或没有发送,没有应答。在控制台中始终为零...

生成的模型类:

    import Foundation

class CurrentWeather : NSObject, NSCoding{


var base : String!
var clouds : Cloud!
var cod : Int!
var coord : Coord!
var dt : Int!
var id : Int!
var main : Main!
var name : String!
var sys : Sy!
var visibility : Int!
var weather : [Weather]!
var wind : Wind!


/**
* Instantiate the instance using the passed dictionary values to set the properties values
*/
init(fromDictionary dictionary: [String:Any]){
base = dictionary["base"] as? String
cod = dictionary["cod"] as? Int
dt = dictionary["dt"] as? Int
id = dictionary["id"] as? Int
name = dictionary["name"] as? String
visibility = dictionary["visibility"] as? Int
if let cloudsData = dictionary["clouds"] as? [String:Any]{
clouds = Cloud(fromDictionary: cloudsData)
}
if let coordData = dictionary["coord"] as? [String:Any]{
coord = Coord(fromDictionary: coordData)
}
if let mainData = dictionary["main"] as? [String:Any]{
main = Main(fromDictionary: mainData)
}
if let sysData = dictionary["sys"] as? [String:Any]{
sys = Sy(fromDictionary: sysData)
}
if let windData = dictionary["wind"] as? [String:Any]{
wind = Wind(fromDictionary: windData)
}
weather = [Weather]()
if let weatherArray = dictionary["weather"] as? [[String:Any]]{
for dic in weatherArray{
let value = Weather(fromDictionary: dic)
weather.append(value)
}
}
}

/**
* Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
*/
func toDictionary() -> [String:Any]
{
var dictionary = [String:Any]()
if base != nil{
dictionary["base"] = base
}
if cod != nil{
dictionary["cod"] = cod
}
if dt != nil{
dictionary["dt"] = dt
}
if id != nil{
dictionary["id"] = id
}
if name != nil{
dictionary["name"] = name
}
if visibility != nil{
dictionary["visibility"] = visibility
}
if clouds != nil{
dictionary["clouds"] = clouds.toDictionary()
}
if coord != nil{
dictionary["coord"] = coord.toDictionary()
}
if main != nil{
dictionary["main"] = main.toDictionary()
}
if sys != nil{
dictionary["sys"] = sys.toDictionary()
}
if wind != nil{
dictionary["wind"] = wind.toDictionary()
}
if weather != nil{
var dictionaryElements = [[String:Any]]()
for weatherElement in weather {
dictionaryElements.append(weatherElement.toDictionary())
}
dictionary["weather"] = dictionaryElements
}
return dictionary
}

/**
* NSCoding required initializer.
* Fills the data from the passed decoder
*/
@objc required init(coder aDecoder: NSCoder)
{
base = aDecoder.decodeObject(forKey: "base") as? String
clouds = aDecoder.decodeObject(forKey: "clouds") as? Cloud
cod = aDecoder.decodeObject(forKey: "cod") as? Int
coord = aDecoder.decodeObject(forKey: "coord") as? Coord
dt = aDecoder.decodeObject(forKey: "dt") as? Int
id = aDecoder.decodeObject(forKey: "id") as? Int
main = aDecoder.decodeObject(forKey: "main") as? Main
name = aDecoder.decodeObject(forKey: "name") as? String
sys = aDecoder.decodeObject(forKey: "sys") as? Sy
visibility = aDecoder.decodeObject(forKey: "visibility") as? Int
weather = aDecoder.decodeObject(forKey: "weather") as? [Weather]
wind = aDecoder.decodeObject(forKey: "wind") as? Wind
}

/**
* NSCoding required method.
* Encodes mode properties into the decoder
*/
@objc func encode(with aCoder: NSCoder)
{
if base != nil{
aCoder.encode(base, forKey: "base")
}
if clouds != nil{
aCoder.encode(clouds, forKey: "clouds")
}
if cod != nil{
aCoder.encode(cod, forKey: "cod")
}
if coord != nil{
aCoder.encode(coord, forKey: "coord")
}
if dt != nil{
aCoder.encode(dt, forKey: "dt")
}
if id != nil{
aCoder.encode(id, forKey: "id")
}
if main != nil{
aCoder.encode(main, forKey: "main")
}
if name != nil{
aCoder.encode(name, forKey: "name")
}
if sys != nil{
aCoder.encode(sys, forKey: "sys")
}
if visibility != nil{
aCoder.encode(visibility, forKey: "visibility")
}
if weather != nil{
aCoder.encode(weather, forKey: "weather")
}
if wind != nil{
aCoder.encode(wind, forKey: "wind")
}
}

}

气象服务:


import Foundation

class WeatherSerice {

let weatherAPIKey: String
let weatherBaseURL: URL?

init(APIKey: String) {

self.weatherAPIKey = APIKey
weatherBaseURL = URL(string: "https://api.openweathermap.org/data/2.5/weather?")
}

func getCurrentWeather(city: String, completion: @escaping (CurrentWeather?) -> Void) {

if let weatherURL = URL(string: "\(weatherBaseURL!)q=\(city)&appid=\(weatherAPIKey)") {

let networkProcessor = NetworkProcessor(url: weatherURL)
networkProcessor.downloadJSONFromURL({(jsonDictionary) in

if let currentWeatherDictionary = jsonDictionary?["currently"] as?
[String : Any] {
let currentWeather = CurrentWeather(fromDictionary: currentWeatherDictionary)
completion(currentWeather)
} else {
completion(nil)
}
})
}
}
}

UIViewController 的一部分:

  let weatherService = WeatherSerice(APIKey: "52e6ff60bba8613b4850e065dcd3d0ac")
weatherService.getCurrentWeather(city: "London") {
(currentWeather) in

print (currentWeather)
}

最佳答案

拜托,请放弃 NSCoding 以支持 Codable,你将摆脱所有丑陋的样板代码

struct WeatherData : Decodable {
let coord : Coordinate
let cod, visibility, id : Int
let name : String
let base : String
let weather : [Weather]
let clouds: Clouds
let sys : Sys
let main : Main
let wind : Wind
let dt : Date
}

struct Coordinate : Decodable {
let lat, lon : Double
}

struct Weather : Decodable {
let id : Int
let icon : String
let main : MainEnum
let description: String
}

struct Sys : Decodable {
let type, id : Int
let sunrise, sunset : Date
let message : Double
let country : String
}

struct Main : Decodable {
let temp, tempMin, tempMax : Double
let pressure, humidity : Int
}

struct Wind : Decodable {
let speed : Double
let deg : Int
let gust : Double?
}

struct Clouds: Decodable {
let all: Int
}

enum MainEnum: String, Decodable {
case clear = "Clear"
case clouds = "Clouds"
case rain = "Rain"
}

如您所见,日期被解码为 DateWeather 中的 main 值被解码为枚举。


我不知道 API NetworkProcessor 所以我用传统的 URLSession 替换了它。添加的 URLComponents 提供正确的 URL 编码,例如,如果 city 包含空格字符

import Foundation

class WeatherSerice {

let weatherAPIKey: String
let weatherBase = "https://api.openweathermap.org/data/2.5/weather"

init(APIKey: String) {

self.weatherAPIKey = APIKey
}

func getCurrentWeather(city: String, completion: @escaping (WeatherData?) -> Void) {

var urlComponents = URLComponents(string: weatherBase)!
let queryItems = [URLQueryItem(name: "q", value: city),
URLQueryItem(name: "appid", value: weatherAPIKey)]
urlComponents.queryItems = queryItems

if let weatherURL = urlComponents.url {

let task = URLSession.shared.dataTask(with: weatherURL) { (data, response, error) in

if let error = error { print(error); completion(nil) }

do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .secondsSince1970
let result = try decoder.decode(WeatherData.self, from: data!)
completion(result)
} catch {
print(error)
completion(nil)
}
}
task.resume()
}
}
}

我建议也使用 Swift 5 中新的 Result 类型来返回错误。

    func getCurrentWeather(city: String, completion: @escaping (Result<WeatherData,Error>) -> Void) {

var urlComponents = URLComponents(string: weatherBase)!
let queryItems = [URLQueryItem(name: "q", value: city),
URLQueryItem(name: "appid", value: weatherAPIKey)]
urlComponents.queryItems = queryItems

if let weatherURL = urlComponents.url {

let task = URLSession.shared.dataTask(with: weatherURL) { (data, response, error) in

if let error = error { completion(.failure(error)) }

do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .secondsSince1970
let result = try decoder.decode(WeatherData.self, from: data!)
completion(.success(result))
} catch {
completion(.failure(error))
}
}
task.resume()
}

并使用它

weatherService.getCurrentWeather(city: "London") { result in
switch result {
case .success(let result): print(result)
case .failure(let error): print(error)
}
}

关于ios - OpenWeather API 中为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56038832/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com