I've getting an response from Alamofire.POST like a long JSON, and it look like this:
"name_srname": "AAA BBB",
"playerData": {
"userData": {
"waypointNumber": null,
"longitude": 33.333,
"latitude": 33.333,
"address": {
"street": "aaa",
"city": "aaaa",
"country": "EN",
"zipCode": "00-00"
},
"dataTracker": null
},
"userDetails": {
"level": 1,
"exp_amount": 21.161993612,
"points_amount": 90,
"items": {
"armor": "aa",
"weapon": "aa",
"ring": "aa",
"helmet": "aa"
},
"rawData": null,
"userCreateDate": "2021-03-10T12:00:00",
"userLastActivity": "2021-03-10T12:00:00",
"isActive": null
},
"lastWaypoint": [
{
"type": null,
"waypointNumber": "01",
"longitude": 33.333,
"latitude": 33.333,
"address": {
"street": "aa",
"city": "aa",
"country": "aa",
"zipCode": "00-00"
},
"addressRaw": "",
"lastWaypointCreate": "2021-03-10T07:00:00",
"lastWaypointBegin": "2021-03-10T07:00:00",
"inGeofenceRange": null
}
],
"GuildName": "Iaaaa",
"rankName": "aaaa",
"progress": 93,
"isReady": true,
"timeJoin": "2021-03-10T11:42:00.673"
Ok now when we know what we got just create a new Class to handle it, like in Android.
import Foundation
// MARK: - ClassElement
class ClassElement: Codable {
let nameSrname: String
let playerData: PlayerData
enum CodingKeys: String, CodingKey {
case nameSrname
case playerData
}
init(nameSrname: String, playerData: PlayerData) {
self.nameSrname = nameSrname
self.playerData = playerData
}
}
//
// To read values from URLs:
//
// let task = URLSession.shared.playerDataTask(with: url) { playerData, response, error in
// if let playerData = playerData {
// ...
// }
// }
// task.resume()
// MARK: - PlayerData
class PlayerData: Codable {
let userData: UserData
let userDetails: UserDetails
let lastWaypoint: [LastWaypoint]
let guildName, rankName: String
let progress: Int
let isReady: Bool
let timeJoin: String
enum CodingKeys: String, CodingKey {
case userData, userDetails, lastWaypoint
case guildName
case rankName, progress, isReady, timeJoin
}
init(userData: UserData, userDetails: UserDetails, lastWaypoint: [LastWaypoint], guildName: String, rankName: String, progress: Int, isReady: Bool, timeJoin: String) {
self.userData = userData
self.userDetails = userDetails
self.lastWaypoint = lastWaypoint
self.guildName = guildName
self.rankName = rankName
self.progress = progress
self.isReady = isReady
self.timeJoin = timeJoin
}
}
//
// To read values from URLs:
//
// let task = URLSession.shared.lastWaypointTask(with: url) { lastWaypoint, response, error in
// if let lastWaypoint = lastWaypoint {
// ...
// }
// }
// task.resume()
// MARK: - LastWaypoint
class LastWaypoint: Codable {
let type: JSONNull?
let waypointNumber: String
let longitude, latitude: Double
let address: Address
let addressRaw, lastWaypointCreate, lastWaypointBegin: String
let inGeofenceRange: JSONNull?
init(type: JSONNull?, waypointNumber: String, longitude: Double, latitude: Double, address: Address, addressRaw: String, lastWaypointCreate: String, lastWaypointBegin: String, inGeofenceRange: JSONNull?) {
self.type = type
self.waypointNumber = waypointNumber
self.longitude = longitude
self.latitude = latitude
self.address = address
self.addressRaw = addressRaw
self.lastWaypointCreate = lastWaypointCreate
self.lastWaypointBegin = lastWaypointBegin
self.inGeofenceRange = inGeofenceRange
}
}
//
// To read values from URLs:
//
// let task = URLSession.shared.addressTask(with: url) { address, response, error in
// if let address = address {
// ...
// }
// }
// task.resume()
// MARK: - Address
class Address: Codable {
let street, city, country, zipCode: String
init(street: String, city: String, country: String, zipCode: String) {
self.street = street
self.city = city
self.country = country
self.zipCode = zipCode
}
}
//
// To read values from URLs:
//
// let task = URLSession.shared.userDataTask(with: url) { userData, response, error in
// if let userData = userData {
// ...
// }
// }
// task.resume()
// MARK: - UserData
class UserData: Codable {
let waypointNumber: JSONNull?
let longitude: Double
let latitude: Int
let address: Address
let dataTracker: JSONNull?
init(waypointNumber: JSONNull?, longitude: Double, latitude: Int, address: Address, dataTracker: JSONNull?) {
self.waypointNumber = waypointNumber
self.longitude = longitude
self.latitude = latitude
self.address = address
self.dataTracker = dataTracker
}
}
//
// To read values from URLs:
//
// let task = URLSession.shared.userDetailsTask(with: url) { userDetails, response, error in
// if let userDetails = userDetails {
// ...
// }
// }
// task.resume()
// MARK: - UserDetails
class UserDetails: Codable {
let level: Int
let expAmount: Double
let pointsAmount: Int
let items: Items
let rawData: JSONNull?
let userCreateDate, userLastActivity: String
let isActive: JSONNull?
enum CodingKeys: String, CodingKey {
case level
case expAmount
case pointsAmount
case items, rawData, userCreateDate, userLastActivity, isActive
}
init(level: Int, expAmount: Double, pointsAmount: Int, items: Items, rawData: JSONNull?, userCreateDate: String, userLastActivity: String, isActive: JSONNull?) {
self.level = level
self.expAmount = expAmount
self.pointsAmount = pointsAmount
self.items = items
self.rawData = rawData
self.userCreateDate = userCreateDate
self.userLastActivity = userLastActivity
self.isActive = isActive
}
}
//
// To read values from URLs:
//
// let task = URLSession.shared.itemsTask(with: url) { items, response, error in
// if let items = items {
// ...
// }
// }
// task.resume()
// MARK: - Items
class Items: Codable {
let armor, weapon, ring, helmet: String
init(armor: String, weapon: String, ring: String, helmet: String) {
self.armor = armor
self.weapon = weapon
self.ring = ring
self.helmet = helmet
}
}
typealias Class = [ClassElement]
// MARK: - Helper functions for creating encoders and decoders
func newJSONDecoder() -> JSONDecoder {
let decoder = JSONDecoder()
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
decoder.dateDecodingStrategy = .iso8601
}
return decoder
}
func newJSONEncoder() -> JSONEncoder {
let encoder = JSONEncoder()
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
encoder.dateEncodingStrategy = .iso8601
}
return encoder
}
// MARK: - URLSession response handlers
extension URLSession {
fileprivate func codableTask<T: Codable>(with url: URL, completionHandler: @escaping (T?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
return self.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
completionHandler(nil, response, error)
return
}
completionHandler(try? newJSONDecoder().decode(T.self, from: data), response, nil)
}
}
func classTask(with url: URL, completionHandler: @escaping (Class?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
return self.codableTask(with: url, completionHandler: completionHandler)
}
}
// MARK: - Encode/decode helpers
class JSONNull: Codable, Hashable {
public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
return true
}
public var hashValue: Int {
return 0
}
public init() {}
public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encodeNil()
}
}
And in the next point I want to handle it with Alamofire, and I've a code like:
AF.request("URL", method: .post, parameters: parameters, encoding: JSONEncoding.default)
.responseJSON { response in
//print(response)
var statusCode = response.response?.statusCode
if (statusCode != 200){
self.view.makeToast("Something went wrong...");
} else{
// self.view.makeToast("It's ok");
if let classResponse = response.data {
do {
let response = try JSONDecoder().decode(ClassElement.self, from: classResponse)
print(response)
} catch {
print(error.localizedDescription)
}
}
}
}
And im getting error like "The data couldn't be read because it isn't in the correct format." Im new in Swift so im trying to use it like in a Android but I think I missunderstand something... Can someone help me? I just want to get every value from this response for example the response.playerData.userData.waypointNumber but I don't know how to receive it.
To close my old question. The problem why im getting the error was the fact, im getting the json list so my json parser will look like:
let response = try JSONDecoder().decode([ClassElement].self, from: classResponse)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.