URLSession 类型不匹配错误
URLSession Type Mismatch Error
我在尝试使用 Swift jSon 解码器解析 json 时收到类型不匹配错误。
我只是找不到正常解析它的方法。
错误:
typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath:
[CodingKeys(stringValue: "data", intValue: nil),
CodingKeys(stringValue: "itemArr", intValue: nil),
CodingKeys(stringValue: "price", intValue: nil)], debugDescription:
"Expected to decode String but found a number instead.",
underlyingError:
nil))
解码器代码:
func getDealDetails(id : String ,completion : @escaping ()->())
{
let jsonUrl = "https://androidtest.inmanage.com/api/1.0/android/getDeal_\(id).txt"
guard let url = URL(string: jsonUrl) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data else { return }
do
{
let deal = try JSONDecoder().decode(ResultDetails.self, from: data)
AppManager.shared.dealToShow = deal.data.itemArr
}catch
{
print("There's an error: \(error)")
}
completion()
}.resume()
}
}
和类:
第一个:
class ResultDetails : Decodable
{
let data : DataDetails
init(data : DataDetails) {
self.data = data
}
}
第二个:
class DataDetails : Decodable
{
let itemArr: ItemArr
init(itemArr: ItemArr) {
self.itemArr = itemArr
}
}
第三个:
class ItemArr : Decodable
{
let id, title, price, description: String
let image: String
let optionsToShow: Int
let gps: Gps
let website, phone: String
init(id: String, title: String, price: String, description: String, image: String, optionsToShow: Int, gps: Gps, website: String, phone: String) {
self.id = id
self.title = title
self.price = price
self.description = description
self.image = image
self.optionsToShow = optionsToShow
self.gps = gps
self.website = website
self.phone = phone
}
我想我在过去 6 个小时里尝试了所有方法来修复它,请帮忙!
编辑:
我放错了第三个class。现在是正确的
是的,你有一个错误
let price: Int
应该是 let price: String
因为它串在 Json "price": "896"
--> String
Int 示例 "optionsToShow":1
--> 这是 Int
这是您可以使用的完整代码
import Foundation
struct ResultDetails: Codable {
let data: DataDetails
}
struct DataDetails: Codable {
let itemArr: ItemArr
}
struct ItemArr: Codable {
let id, title, price, description: String
let image: String
let optionsToShow: Int
let gps: Gps
let website, phone: String
}
struct Gps: Codable {
let lat, lon: String
}
// MARK: Convenience initializers
extension ResultDetails {
init(data: Data) throws {
self = try JSONDecoder().decode(ResultDetails.self, from: data)
}
init(_ json: String, using encoding: String.Encoding = .utf8) throws {
guard let data = json.data(using: encoding) else {
throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
}
try self.init(data: data)
}
func jsonData() throws -> Data {
return try JSONEncoder().encode(self)
}
func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
return String(data: try self.jsonData(), encoding: encoding)
}
}
报错信息有误。根据 JSON link 和你的 类 它应该是
CodingKeys(stringValue: "price", intValue: nil)], debugDescription:
Expected to decode Int but found a string/data instead.,
但是它会告诉你到底出了什么问题:键 price
的值是 String
而不是 Int
.
你必须仔细阅读JSON。格式非常简单。比如所有在双引号里都是String
,有没有例外。
你的数据结构太复杂了。使用结构并删除初始值设定项。顺便说一下,ItemsArr
与 ItemArr
有错别字,而且没有密钥 orderNum
.
密钥image
可以被解码为URL。这就够了
struct ResultDetails : Decodable {
let data : DataDetails
}
struct DataDetails : Decodable {
let itemArr: ItemArr
}
struct ItemArr : Decodable {
let id, title: String
let price: String
let image: URL
// let orderNum: Int
}
仅当您要映射键时才指定 CodingKeys
。在您的情况下,您甚至可以省略 CodingKeys
,而是使用 convertFromSnakeCase
策略。
decoder.keyDecodingStrategy = .convertFromSnakeCase
我在尝试使用 Swift jSon 解码器解析 json 时收到类型不匹配错误。
我只是找不到正常解析它的方法。
错误:
typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath:
[CodingKeys(stringValue: "data", intValue: nil),
CodingKeys(stringValue: "itemArr", intValue: nil),
CodingKeys(stringValue: "price", intValue: nil)], debugDescription:
"Expected to decode String but found a number instead.",
underlyingError:
nil))
解码器代码:
func getDealDetails(id : String ,completion : @escaping ()->())
{
let jsonUrl = "https://androidtest.inmanage.com/api/1.0/android/getDeal_\(id).txt"
guard let url = URL(string: jsonUrl) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data else { return }
do
{
let deal = try JSONDecoder().decode(ResultDetails.self, from: data)
AppManager.shared.dealToShow = deal.data.itemArr
}catch
{
print("There's an error: \(error)")
}
completion()
}.resume()
}
}
和类:
第一个:
class ResultDetails : Decodable
{
let data : DataDetails
init(data : DataDetails) {
self.data = data
}
}
第二个:
class DataDetails : Decodable
{
let itemArr: ItemArr
init(itemArr: ItemArr) {
self.itemArr = itemArr
}
}
第三个:
class ItemArr : Decodable
{
let id, title, price, description: String
let image: String
let optionsToShow: Int
let gps: Gps
let website, phone: String
init(id: String, title: String, price: String, description: String, image: String, optionsToShow: Int, gps: Gps, website: String, phone: String) {
self.id = id
self.title = title
self.price = price
self.description = description
self.image = image
self.optionsToShow = optionsToShow
self.gps = gps
self.website = website
self.phone = phone
}
我想我在过去 6 个小时里尝试了所有方法来修复它,请帮忙!
编辑:
我放错了第三个class。现在是正确的
是的,你有一个错误
let price: Int
应该是 let price: String
因为它串在 Json "price": "896"
--> String
Int 示例 "optionsToShow":1
--> 这是 Int
这是您可以使用的完整代码
import Foundation
struct ResultDetails: Codable {
let data: DataDetails
}
struct DataDetails: Codable {
let itemArr: ItemArr
}
struct ItemArr: Codable {
let id, title, price, description: String
let image: String
let optionsToShow: Int
let gps: Gps
let website, phone: String
}
struct Gps: Codable {
let lat, lon: String
}
// MARK: Convenience initializers
extension ResultDetails {
init(data: Data) throws {
self = try JSONDecoder().decode(ResultDetails.self, from: data)
}
init(_ json: String, using encoding: String.Encoding = .utf8) throws {
guard let data = json.data(using: encoding) else {
throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
}
try self.init(data: data)
}
func jsonData() throws -> Data {
return try JSONEncoder().encode(self)
}
func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
return String(data: try self.jsonData(), encoding: encoding)
}
}
报错信息有误。根据 JSON link 和你的 类 它应该是
CodingKeys(stringValue: "price", intValue: nil)], debugDescription: Expected to decode Int but found a string/data instead.,
但是它会告诉你到底出了什么问题:键 price
的值是 String
而不是 Int
.
你必须仔细阅读JSON。格式非常简单。比如所有在双引号里都是String
,有没有例外。
你的数据结构太复杂了。使用结构并删除初始值设定项。顺便说一下,ItemsArr
与 ItemArr
有错别字,而且没有密钥 orderNum
.
密钥image
可以被解码为URL。这就够了
struct ResultDetails : Decodable {
let data : DataDetails
}
struct DataDetails : Decodable {
let itemArr: ItemArr
}
struct ItemArr : Decodable {
let id, title: String
let price: String
let image: URL
// let orderNum: Int
}
仅当您要映射键时才指定 CodingKeys
。在您的情况下,您甚至可以省略 CodingKeys
,而是使用 convertFromSnakeCase
策略。
decoder.keyDecodingStrategy = .convertFromSnakeCase