【问题标题】:Attempt to insert non-property list object with JSON Array尝试使用 JSON 数组插入非属性列表对象
【发布时间】:2020-07-17 05:01:35
【问题描述】:

基本上,我已经正确解析了我的数据。但是,当我尝试访问数据时。它声称我正在尝试将非属性列表对象插入到 UserDefaults 数组中。我如何能够以某种方式将其转换为属性列表对象?或者我如何能够将 JSON 数组存储为字符串?

var status = UserDefaults.standard.array(forKey: "status") ?? []
struct Response: Codable {
        let weather: [MyResult]
    }
    struct MyResult: Codable {
        let main: String
    }
func getData(from url:String) {
        
        URLSession.shared.dataTask(with: URL(string:url)!, completionHandler: {
            data, response, error in
            guard let data = data, error == nil else {
                print("Something went wrong")
                return
            }
            // have data
            var result: Response?
            do {
                result = try JSONDecoder().decode(Response.self, from: data)
            } catch {
                print(error.localizedDescription)
            }
            guard let json = result else {
                return
            }
            print(type(of: json.weather)) // Array
            
            UserDefaults.standard.set(json.weather, forKey: "status") // Here is the error
            print(status)
            }).resume()
    }

编辑:当我打印状态时,什么都没有。

func getData(from url:String) {
        
        URLSession.shared.dataTask(with: URL(string:url)!, completionHandler: {
            data, response, error in
            guard let data = data, error == nil else {
                print("Something went wrong")
                return
            }
            // have data
            var result: Response?
            do {
                result = try JSONDecoder().decode(Response.self, from: data)
            } catch {
                print(error.localizedDescription)
            }
            guard let json = result else {
                return
            }
            print(type(of: json.weather)) // Array
            do {
                 // Store it with
                let data = try JSONEncoder().encode(json.weather)
                UserDefaults.standard.set(data, forKey: "status")
                

                //  Read it
                if let data = UserDefaults.standard.data(forKey:"status") {
                  let res = try JSONDecoder().decode([MyResult].self,from:data)
                }
            }
            catch {
               print(error)
            }
            print(status)
            }).resume()
    }

【问题讨论】:

  • 您正在存储MyResult 的数组。这不是 JSON。您需要将其编码回来。并且永远不要打印像"Something went wrong" 这样无意义的文字字符串,而不是实际的error。并且在 Codable 捕获块打印始终 error 而不是 error.localizedDescription

标签: json swift


【解决方案1】:

你需要

do {
     // Store it with  
    let data = try JSONEncoder().encode(json.weather)
    UserDefaults.standard.set(data, forKey: "status")

    //  Read it 
    if let data = UserDefaults.standard.data(forKey:"status") {
      let res = try JSONDecoder().decode([MyResult].self,from:data)
    }  
}
catch {
   print(error)
}

【讨论】:

  • 我已经尝试过这段代码并不断得到相同的控制台“尝试插入非属性列表对象”响应。
【解决方案2】:

保持变量的命名唯一,以免混淆或混淆。这是为您整理的代码。

func getData(from url: String) {
    URLSession.shared.dataTask(with: URL(string: url)!) { data, _, error in
        guard let data = data else {
            if let error = error { print(error) }
            return
        }
        do {
            let response = try JSONDecoder().decode(Response.self, from: data)
            print("got response: \(response)")
            let dataToStore = try JSONEncoder().encode(response.weather)
            UserDefaults.standard.set(dataToStore, forKey: "status") // set data to userdefaults
            guard let dataRetrieved = UserDefaults.standard.data(forKey: "status") else { return } // retrieve back weather
            let weather = try JSONDecoder().decode([MyResult].self, from: dataRetrieved)
            print("got weather from user defaults: \(weather)")
        } catch {
            print(error.localizedDescription)
        }
    }.resume()
}

【讨论】:

  • 这没有为关键“状态”设置任何内容我尝试将其打印到下一行,但由于某种原因它只是显示为 nil。我只是想返回多云,下雨等。它不应该这么复杂。
  • 显示你尝试了什么?如果您完全尝试了上面的代码,它应该可以工作。从上面的代码中打印responseweather 时你得到了什么?
  • 所以我尝试了上面的确切代码,当我打印出 UserDefualts 的状态时,我不断得到我提供的默认值。在您的打印语句“从用户那里获得天气......”它打印出数组就好了。但是,它将我的用户默认设置为不同的值,这给我带来了麻烦。当我打印出响应时,我得到了一系列天气,其中“主要”是晴天等。我只是不明白为什么我的 UserDefault 没有在这里正确设置。
  • 我认为您没有以正确的格式设置 UserDefaults,它需要是 Data 类型并且对于打印,您必须完全按照我在上面的代码中所做的操作do 块中的最后 3 行。如果您更正设置和检索的格式,您应该没问题。
猜你喜欢
  • 1970-01-01
  • 2014-06-04
  • 1970-01-01
  • 2021-11-08
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多