无法读取数据,因为它的格式不正确。 Swift 5
The data couldn’t be read because it isn’t in the correct format. Swift 5
我正在尝试解码来自 https://swapi.dev/ 的数据。我使用响应代码 200 正确地得到了 json,但解码器无法读取数据,因为格式不正确。我尝试了很多不同的方式。我正在尝试获取有关人民的信息。
这是我的代码:
模型文件
struct people: Codable {
let count: Int
let next: String?
let previous: String?
let results: [result]
}
struct result: Codable{
let name: String
let height: Int
let mass: Int
let hair_color: String
let skin_color: String
let eye_color: String
let birth_year: String
let gender: String
let homeworld: String
let films: [String]
let species: [String]
let vehicles: [String]
let starships: [String]
let created: String
let edited: String
let url: String
}
struct APIError: Codable {
let detail: String
}
网络服务
typealias OnApiSucces = (people) -> Void
typealias OnApiError = (String) -> Void
struct ApiService {
static let shared = ApiService()
let URL_BASE = "https://swapi.dev/api"
let URL_PEOPLE = "/people"
let session = URLSession(configuration: .default)
func getResults(onSuccess: @escaping OnApiSucces, onError: @escaping OnApiError) {
let url = URL(string: "\(URL_BASE)\(URL_PEOPLE)")!
var request = URLRequest(url: url)
request.httpMethod = "GET" // GET, PUT, POST, DELETE for some different api
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = session.dataTask(with: request) { (data, response, error) in
if let error = error {
onError(error.localizedDescription)
return
}
guard let data = data, let response = response as? HTTPURLResponse else {
onError("Invalid data or response")
return
}
do{
if response.statusCode == 200 {
print("Code is \(response.statusCode)")
let results = try JSONDecoder().decode(people.self, from: data)
onSuccess(results)
} else {
let err = try JSONDecoder().decode(APIError.self, from: data)
print("Code is \(response.statusCode)")
onError(err.detail)
}
}
catch {
onError(error.localizedDescription)
}
}
task.resume()
}
}
** 在 ViewController**
上获取数据
func getResults() {
ApiService.shared.getResults { (people) in
self.results = people.results
} onError: { (error) in
debugPrint(error.description)
}
}
首先,无法读取您的数据,因为 height
和 mass
在星球大战 API 中表示为 String
,而您将它们表示为 Int
在你的 Codable
结构中。
此外,尝试将 CodingKeys
添加到您的 Codable
结构中,以便您的结构遵守命名约定(特别是关于您的 attribute_color
变体),例如
struct result: Codable{
let name: String
let height: String
let mass: String
let hairColor: String // changed from hair_color
let skinColor: String
let eyeColor: String
let birthYear: String
let gender: String
let homeworld: String
let films: [String]
let species: [String]
let vehicles: [String]
let starships: [String]
let created: String
let edited: String
let url: String
enums CodingKeys: String, CodingKey {
case name = "name"
case height = "height"
case mass = "mass"
case hairColor = "hair_color"
case skinColor = "skin_color"
case eyeColor = "eye_color"
case birthYear = "birth_year"
case gender = "gender"
case homeworld = "homeworld"
case films = "films"
case species = "species"
case vehicles = "vehicles"
case starships = "starships"
case created = "created"
case edited = "edited"
case url = "url"
}
}
我正在尝试解码来自 https://swapi.dev/ 的数据。我使用响应代码 200 正确地得到了 json,但解码器无法读取数据,因为格式不正确。我尝试了很多不同的方式。我正在尝试获取有关人民的信息。
这是我的代码:
模型文件
struct people: Codable {
let count: Int
let next: String?
let previous: String?
let results: [result]
}
struct result: Codable{
let name: String
let height: Int
let mass: Int
let hair_color: String
let skin_color: String
let eye_color: String
let birth_year: String
let gender: String
let homeworld: String
let films: [String]
let species: [String]
let vehicles: [String]
let starships: [String]
let created: String
let edited: String
let url: String
}
struct APIError: Codable {
let detail: String
}
网络服务
typealias OnApiSucces = (people) -> Void
typealias OnApiError = (String) -> Void
struct ApiService {
static let shared = ApiService()
let URL_BASE = "https://swapi.dev/api"
let URL_PEOPLE = "/people"
let session = URLSession(configuration: .default)
func getResults(onSuccess: @escaping OnApiSucces, onError: @escaping OnApiError) {
let url = URL(string: "\(URL_BASE)\(URL_PEOPLE)")!
var request = URLRequest(url: url)
request.httpMethod = "GET" // GET, PUT, POST, DELETE for some different api
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = session.dataTask(with: request) { (data, response, error) in
if let error = error {
onError(error.localizedDescription)
return
}
guard let data = data, let response = response as? HTTPURLResponse else {
onError("Invalid data or response")
return
}
do{
if response.statusCode == 200 {
print("Code is \(response.statusCode)")
let results = try JSONDecoder().decode(people.self, from: data)
onSuccess(results)
} else {
let err = try JSONDecoder().decode(APIError.self, from: data)
print("Code is \(response.statusCode)")
onError(err.detail)
}
}
catch {
onError(error.localizedDescription)
}
}
task.resume()
}
}
** 在 ViewController**
上获取数据 func getResults() {
ApiService.shared.getResults { (people) in
self.results = people.results
} onError: { (error) in
debugPrint(error.description)
}
}
首先,无法读取您的数据,因为 height
和 mass
在星球大战 API 中表示为 String
,而您将它们表示为 Int
在你的 Codable
结构中。
此外,尝试将 CodingKeys
添加到您的 Codable
结构中,以便您的结构遵守命名约定(特别是关于您的 attribute_color
变体),例如
struct result: Codable{
let name: String
let height: String
let mass: String
let hairColor: String // changed from hair_color
let skinColor: String
let eyeColor: String
let birthYear: String
let gender: String
let homeworld: String
let films: [String]
let species: [String]
let vehicles: [String]
let starships: [String]
let created: String
let edited: String
let url: String
enums CodingKeys: String, CodingKey {
case name = "name"
case height = "height"
case mass = "mass"
case hairColor = "hair_color"
case skinColor = "skin_color"
case eyeColor = "eye_color"
case birthYear = "birth_year"
case gender = "gender"
case homeworld = "homeworld"
case films = "films"
case species = "species"
case vehicles = "vehicles"
case starships = "starships"
case created = "created"
case edited = "edited"
case url = "url"
}
}