由于数据格式不正确,因此无法读取。尝试解析下面给出的JSON。将数据对象也包含在struct中时抛出错误
我的JSON
{
"status": 200,
"message": "Logged in successfully.",
"error_message": [],
"data": {
"id": "179",
"home_address": "Optiquall Pune Maharashtra India",
"user_login": "mukti.thakor@optiquall.com",
"first_name": "mukti",
"last_name": "thakor",
"email": "mukti.thakor@optiquall.com",
"phone_number": "",
"timezone": "Asia/Calcutta",
"is_google_authenticated": "1",
"is_facebook_authenticated": "1",
"image_url": "",
"active_trip_id": "0",
"journey_type": "",
"trip_identifier": "",
"trip_author": "",
"token_info": {
"access_token": "e692f28b8ffe16e683540e7b2d42286a47cbe7fb",
"expires_in": "3600",
"token_type": "Bearer",
"scope": null,
"refresh_token": "8512b001e35eb69c7d3b45e20138bf91b210bafb"
}
},
"notification_count": 0
}
我的代码
let decoder = JSONDecoder()
//decoder.keyDecodingStrategy = .convertFromSnakeCase
do{
let succeResponse = try decoder.decode(successResponse.self, from: data!)
print(succeResponse.data)
} catch let error as Error{
print(error.localizedDescription)
}
struct SuccessResponse: Codable {
var status:Int?
var message:String?
var errorMessage:[Int]? = []
//var developerMessage:String?
var notificationCount:Int?
var data:data
private enum CodingKeys : String, CodingKey {
case status = "status", message = "message", notificationCount = "notification_count", errorMessage = "error_message", data = "data"
}
}
struct Data: Codable {
var id:Int?
var homeAddress:String?
var userLogin:String?
var firstName:String?
var lastName:String?
var email:String?
var phoneNumber:String?
var timezone:String?
var isGoogleAuthenticated:String?
var isFacebookAuthenticated:String?
var imageUrl:String?
var activeTripId:String?
var journeyType:String?
var tripIdentifier:String?
var tripAuthor:String?
var tokenInfo:tokenInfo
private enum CodingKeys : String, CodingKey {
case id = "id", homeAddress = "home_address", userLogin = "user_login", firstName = "first_name", lastName = "last_name", email = "email", phoneNumber = "phone_number", timezone = "timezone", isGoogleAuthenticated = "is_google_authenticated",isFacebookAuthenticated = "is_facebook_authenticated", imageUrl = "image_url", activeTripId = "active_trip_id", journeyType = "journey_type", tripIdentifier = "trip_identifier" , tripAuthor = "trip_author", tokenInfo = "token_info"
}
}
struct TokenInfo: Codable {
var accessToken:String?
var expiresIn:String?
var tokenType:String?
var scope:Bool?
var refreshToken:String?
private enum CodingKeys : String, CodingKey {
case accessToken = "access_token", expiresIn = "expires_in", tokenType = "token_type", scope = "scope", refreshToken = "refresh_token"
}
}
答案 0 :(得分:2)
替换
var id:Int?
使用
var id:String?
答案 1 :(得分:1)
首先,如DecodingError
catch块中的注释从不print(error)
所述。始终id
以获得此综合错误消息:
typeMismatch(Swift.Int,Swift.DecodingError.Context(codingPath:[CodingKeys(stringValue:“ data”,intValue:nil),CodingKeys(stringValue:“ id”,intValue:nil)],debugDescription:“预期解码Int,但是找到了一个字符串/数据。”,underlyingError:nil))
它告诉您结构data
中键id
的值( [CodingKeys(stringValue:“ data”,intValue:nil),CodingKeys(stringValue:“ id”, intValue:nil)] )是一个字符串(找到了一个字符串 /数据),而不是预期用于解码 Int 。
因此,按照Sh_Khan的回答中的建议,将String
声明为status
。
这是一种能够解码成功案例和失败案例的解决方案。
根对象根据Response
中的值被解码为具有相关值的枚举。
其他更改:
UserData
和scope
let
除外)都声明为非可选。如果收到错误消息,则仅将受影响的类型更改为可选类型。convertFromSnakeCase
)。enum Response : Decodable {
case success(Int, Int, String, UserData)
case failure(Int, Int, String, [String:String])
private enum CodingKeys : String, CodingKey {
case status = "status", message = "message", notificationCount = "notificationCount", errorMessage = "errorMessage", data = "data"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let status = try container.decode(Int.self, forKey: .status)
let notificationCount = try container.decode(Int.self, forKey: .notificationCount)
let message = try container.decode(String.self, forKey: .message)
if status == 200 {
let userData = try container.decode(UserData.self, forKey: .data)
self = .success(status, notificationCount, message, userData)
} else {
let errorMessage = try container.decode([String:String].self, forKey: .errorMessage)
self = .failure(status, notificationCount, message, errorMessage)
}
}
}
struct UserData : Decodable {
let id, homeAddress, userLogin, firstName, lastName, email, phoneNumber, timezone : String
let isGoogleAuthenticated, isFacebookAuthenticated, imageUrl, activeTripId, journeyType, tripIdentifier, tripAuthor : String
let tokenInfo : TokenInfo
}
struct TokenInfo : Decodable {
let accessToken, expiresIn, tokenType, refreshToken : String
let scope : String?
}
策略结构:
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
let response = try decoder.decode(Response.self, from: data!)
switch response {
case let .success(status, notificationCount, message, userData): print(status, notificationCount, message, userData)
case let .failure(status, notificationCount, message, errorMessage): print(status, notificationCount, message, errorMessage)
}
} catch {
print(error)
}
用法:
ProgrammingError: No results