How to decode a JSON property with different types? [duplicate] The Next CEO of Stack OverflowWhat Is Preventing My Conversion From String to Int When Decoding Using Swift 4’s Codable?Read JSON object with variable which is int and/or stringHow do you find out the type of an object (in Swift)?Swift: Print variable with different types (enum) from JSON in for-loopSafely turning a JSON string into an objectHow do I format a Microsoft JSON date?Can comments be used in JSON?How can I pretty-print JSON in a shell script?What is the correct JSON content type?How do I test for an empty JavaScript object?Why does Google prepend while(1); to their JSON responses?How can I pretty-print JSON using JavaScript?Parse JSON in JavaScript?How do I POST JSON data with Curl from a terminal/commandline to Test Spring REST?
How to start emacs in "nothing" mode (`fundamental-mode`)
I believe this to be a fraud - hired, then asked to cash check and send cash as Bitcoin
Make solar eclipses exceedingly rare, but still have new moons
Can you replace a racial trait cantrip when leveling up?
Preparing Indesign booklet with .psd graphics for print
WOW air has ceased operation, can I get my tickets refunded?
What is the result of assigning to std::vector<T>::begin()?
Elegant way to replace substring in a regex with optional groups in Python?
What benefits would be gained by using human laborers instead of drones in deep sea mining?
How do I reset passwords on multiple websites easily?
How did people program for Consoles with multiple CPUs?
Why do professional authors make "consistency" mistakes? And how to avoid them?
How to count occurrences of text in a file?
How to avoid supervisors with prejudiced views?
Why didn't Khan get resurrected in the Genesis Explosion?
What does "Its cash flow is deeply negative" mean?
Written every which way
Why does standard notation not preserve intervals (visually)
Are there any limitations on attacking while grappling?
What happened in Rome, when the western empire "fell"?
Geometry problem - areas of triangles (contest math)
Unreliable Magic - Is it worth it?
Return the Closest Prime Number
In excess I'm lethal
How to decode a JSON property with different types? [duplicate]
The Next CEO of Stack OverflowWhat Is Preventing My Conversion From String to Int When Decoding Using Swift 4’s Codable?Read JSON object with variable which is int and/or stringHow do you find out the type of an object (in Swift)?Swift: Print variable with different types (enum) from JSON in for-loopSafely turning a JSON string into an objectHow do I format a Microsoft JSON date?Can comments be used in JSON?How can I pretty-print JSON in a shell script?What is the correct JSON content type?How do I test for an empty JavaScript object?Why does Google prepend while(1); to their JSON responses?How can I pretty-print JSON using JavaScript?Parse JSON in JavaScript?How do I POST JSON data with Curl from a terminal/commandline to Test Spring REST?
This question already has an answer here:
What Is Preventing My Conversion From String to Int When Decoding Using Swift 4’s Codable?
1 answer
I have a JSON
"tvShow":
"id": 5348,
"name": "Supernatural",
"permalink": "supernatural",
"url": "http://www.episodate.com/tv-show/supernatural",
"description": "Supernatural is an American fantasy horror television series created by Eric Kripke. It was first broadcast on September 13, 2005, on The WB and subsequently became part of successor The CW's lineup. Starring Jared Padalecki as Sam Winchester and Jensen Ackles as Dean Winchester, the series follows the two brothers as they hunt demons, ghosts, monsters, and other supernatural beings in the world. The series is produced by Warner Bros. Television, in association with Wonderland Sound and Vision. Along with Kripke, executive producers have been McG, Robert Singer, Phil Sgriccia, Sera Gamble, Jeremy Carver, John Shiban, Ben Edlund and Adam Glass. Former executive producer and director Kim Manners died of lung cancer during production of the fourth season.<br>The series is filmed in Vancouver, British Columbia and surrounding areas and was in development for nearly ten years, as creator Kripke spent several years unsuccessfully pitching it. The pilot was viewed by an estimated 5.69 million viewers, and the ratings of the first four episodes prompted The WB to pick up the series for a full season. Originally, Kripke planned the series for three seasons but later expanded it to five. The fifth season concluded the series' main storyline, and Kripke departed the series as showrunner. The series has continued on for several more seasons with Sera Gamble and Jeremy Carver assuming the role of showrunner.",
"description_source": "http://en.wikipedia.org/wiki/Supernatural_(U.S._TV_series)#Spin-off_series",
"start_date": "2005-09-13",
"end_date": null,
"country": "US",
"status": "Running",
"runtime": 60,
"network": "The CW",
"youtube_link": "6ZlnmAWL59I",
"image_path": "https://static.episodate.com/images/tv-show/full/5348.jpg",
"image_thumbnail_path": "https://static.episodate.com/images/tv-show/thumbnail/5348.jpg",
"rating": "9.6747",
"rating_count": "249",
"countdown": null
The value of rating
in different serials is Int
("rating": 0) or String
("rating": "9.6747").
I am parsing JSON with Codable/Decodable protocols:
struct DetailModel : Decodable
var id : Int?
var name : String?
var permalink : String?
var url : String?
var description : String
var description_source : String?
var start_date : String?
var end_date : String?
var country : String?
var status : String?
var runtime : Int?
var network : String?
var youtube_link : String?
var image_path : String?
var image_thumbnail_path : String?
var rating: String
var rating_count : String?
var countdown : String?
var genres : [String]?
var pictures : [String]?
var episodes : [EpisodesModel]?
If rating == String, my code work and I have all the variables from JSON, but if rating == Int, all is nil
. What should I do to parse all the types of variable rating
at once Int
and String
?
My decodable function:
func searchSerialDetail(id: Int, completion: @escaping (DetailModel?) -> Void)
let parameters: [String: Any] = ["q": id]
Alamofire.request(DetailNetworkLayer.url, method: .get, parameters: parameters).response (jsonResponse) in
if let jsonValue = jsonResponse.data
let jsonDecoder = JSONDecoder()
let detail = try? jsonDecoder.decode(DetailModel.self, from: jsonValue)
completion(detail)
Thank you.
json swift alamofire swift4 decodable
marked as duplicate by Dávid Pásztor, Community♦ May 25 '18 at 12:35
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
This question already has an answer here:
What Is Preventing My Conversion From String to Int When Decoding Using Swift 4’s Codable?
1 answer
I have a JSON
"tvShow":
"id": 5348,
"name": "Supernatural",
"permalink": "supernatural",
"url": "http://www.episodate.com/tv-show/supernatural",
"description": "Supernatural is an American fantasy horror television series created by Eric Kripke. It was first broadcast on September 13, 2005, on The WB and subsequently became part of successor The CW's lineup. Starring Jared Padalecki as Sam Winchester and Jensen Ackles as Dean Winchester, the series follows the two brothers as they hunt demons, ghosts, monsters, and other supernatural beings in the world. The series is produced by Warner Bros. Television, in association with Wonderland Sound and Vision. Along with Kripke, executive producers have been McG, Robert Singer, Phil Sgriccia, Sera Gamble, Jeremy Carver, John Shiban, Ben Edlund and Adam Glass. Former executive producer and director Kim Manners died of lung cancer during production of the fourth season.<br>The series is filmed in Vancouver, British Columbia and surrounding areas and was in development for nearly ten years, as creator Kripke spent several years unsuccessfully pitching it. The pilot was viewed by an estimated 5.69 million viewers, and the ratings of the first four episodes prompted The WB to pick up the series for a full season. Originally, Kripke planned the series for three seasons but later expanded it to five. The fifth season concluded the series' main storyline, and Kripke departed the series as showrunner. The series has continued on for several more seasons with Sera Gamble and Jeremy Carver assuming the role of showrunner.",
"description_source": "http://en.wikipedia.org/wiki/Supernatural_(U.S._TV_series)#Spin-off_series",
"start_date": "2005-09-13",
"end_date": null,
"country": "US",
"status": "Running",
"runtime": 60,
"network": "The CW",
"youtube_link": "6ZlnmAWL59I",
"image_path": "https://static.episodate.com/images/tv-show/full/5348.jpg",
"image_thumbnail_path": "https://static.episodate.com/images/tv-show/thumbnail/5348.jpg",
"rating": "9.6747",
"rating_count": "249",
"countdown": null
The value of rating
in different serials is Int
("rating": 0) or String
("rating": "9.6747").
I am parsing JSON with Codable/Decodable protocols:
struct DetailModel : Decodable
var id : Int?
var name : String?
var permalink : String?
var url : String?
var description : String
var description_source : String?
var start_date : String?
var end_date : String?
var country : String?
var status : String?
var runtime : Int?
var network : String?
var youtube_link : String?
var image_path : String?
var image_thumbnail_path : String?
var rating: String
var rating_count : String?
var countdown : String?
var genres : [String]?
var pictures : [String]?
var episodes : [EpisodesModel]?
If rating == String, my code work and I have all the variables from JSON, but if rating == Int, all is nil
. What should I do to parse all the types of variable rating
at once Int
and String
?
My decodable function:
func searchSerialDetail(id: Int, completion: @escaping (DetailModel?) -> Void)
let parameters: [String: Any] = ["q": id]
Alamofire.request(DetailNetworkLayer.url, method: .get, parameters: parameters).response (jsonResponse) in
if let jsonValue = jsonResponse.data
let jsonDecoder = JSONDecoder()
let detail = try? jsonDecoder.decode(DetailModel.self, from: jsonValue)
completion(detail)
Thank you.
json swift alamofire swift4 decodable
marked as duplicate by Dávid Pásztor, Community♦ May 25 '18 at 12:35
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
1
Why are almost all ofDetailModel
s properties optional? Only make them optional if they might not be present in the JSON. Moreover, makerating
aDouble
and create a custominit(from:)
method as explained in the linked Q&A to handle the conversion fromString
toDouble
. Also don't useresponseJSON
and don't mixJSONSerialization
andJSONDecoder
, simply takeresponse
fromAlamofire
asData
and parse that directly withJSONDecoder
. With your current code you're parsing the JSON twice for no reason.
– Dávid Pásztor
May 25 '18 at 10:05
No you didn't follow along the answer provided there. You should first go through the whole answer. Then you will understand what to implement for your case. You just scrolled through the answer and picked the first example. But the first example doesn't really solve that problem at all. Read the whole answer.
– nayem
May 25 '18 at 11:45
thank you guys, I solved this problem in several ways :)
– alpha corrado
May 25 '18 at 12:35
add a comment |
This question already has an answer here:
What Is Preventing My Conversion From String to Int When Decoding Using Swift 4’s Codable?
1 answer
I have a JSON
"tvShow":
"id": 5348,
"name": "Supernatural",
"permalink": "supernatural",
"url": "http://www.episodate.com/tv-show/supernatural",
"description": "Supernatural is an American fantasy horror television series created by Eric Kripke. It was first broadcast on September 13, 2005, on The WB and subsequently became part of successor The CW's lineup. Starring Jared Padalecki as Sam Winchester and Jensen Ackles as Dean Winchester, the series follows the two brothers as they hunt demons, ghosts, monsters, and other supernatural beings in the world. The series is produced by Warner Bros. Television, in association with Wonderland Sound and Vision. Along with Kripke, executive producers have been McG, Robert Singer, Phil Sgriccia, Sera Gamble, Jeremy Carver, John Shiban, Ben Edlund and Adam Glass. Former executive producer and director Kim Manners died of lung cancer during production of the fourth season.<br>The series is filmed in Vancouver, British Columbia and surrounding areas and was in development for nearly ten years, as creator Kripke spent several years unsuccessfully pitching it. The pilot was viewed by an estimated 5.69 million viewers, and the ratings of the first four episodes prompted The WB to pick up the series for a full season. Originally, Kripke planned the series for three seasons but later expanded it to five. The fifth season concluded the series' main storyline, and Kripke departed the series as showrunner. The series has continued on for several more seasons with Sera Gamble and Jeremy Carver assuming the role of showrunner.",
"description_source": "http://en.wikipedia.org/wiki/Supernatural_(U.S._TV_series)#Spin-off_series",
"start_date": "2005-09-13",
"end_date": null,
"country": "US",
"status": "Running",
"runtime": 60,
"network": "The CW",
"youtube_link": "6ZlnmAWL59I",
"image_path": "https://static.episodate.com/images/tv-show/full/5348.jpg",
"image_thumbnail_path": "https://static.episodate.com/images/tv-show/thumbnail/5348.jpg",
"rating": "9.6747",
"rating_count": "249",
"countdown": null
The value of rating
in different serials is Int
("rating": 0) or String
("rating": "9.6747").
I am parsing JSON with Codable/Decodable protocols:
struct DetailModel : Decodable
var id : Int?
var name : String?
var permalink : String?
var url : String?
var description : String
var description_source : String?
var start_date : String?
var end_date : String?
var country : String?
var status : String?
var runtime : Int?
var network : String?
var youtube_link : String?
var image_path : String?
var image_thumbnail_path : String?
var rating: String
var rating_count : String?
var countdown : String?
var genres : [String]?
var pictures : [String]?
var episodes : [EpisodesModel]?
If rating == String, my code work and I have all the variables from JSON, but if rating == Int, all is nil
. What should I do to parse all the types of variable rating
at once Int
and String
?
My decodable function:
func searchSerialDetail(id: Int, completion: @escaping (DetailModel?) -> Void)
let parameters: [String: Any] = ["q": id]
Alamofire.request(DetailNetworkLayer.url, method: .get, parameters: parameters).response (jsonResponse) in
if let jsonValue = jsonResponse.data
let jsonDecoder = JSONDecoder()
let detail = try? jsonDecoder.decode(DetailModel.self, from: jsonValue)
completion(detail)
Thank you.
json swift alamofire swift4 decodable
This question already has an answer here:
What Is Preventing My Conversion From String to Int When Decoding Using Swift 4’s Codable?
1 answer
I have a JSON
"tvShow":
"id": 5348,
"name": "Supernatural",
"permalink": "supernatural",
"url": "http://www.episodate.com/tv-show/supernatural",
"description": "Supernatural is an American fantasy horror television series created by Eric Kripke. It was first broadcast on September 13, 2005, on The WB and subsequently became part of successor The CW's lineup. Starring Jared Padalecki as Sam Winchester and Jensen Ackles as Dean Winchester, the series follows the two brothers as they hunt demons, ghosts, monsters, and other supernatural beings in the world. The series is produced by Warner Bros. Television, in association with Wonderland Sound and Vision. Along with Kripke, executive producers have been McG, Robert Singer, Phil Sgriccia, Sera Gamble, Jeremy Carver, John Shiban, Ben Edlund and Adam Glass. Former executive producer and director Kim Manners died of lung cancer during production of the fourth season.<br>The series is filmed in Vancouver, British Columbia and surrounding areas and was in development for nearly ten years, as creator Kripke spent several years unsuccessfully pitching it. The pilot was viewed by an estimated 5.69 million viewers, and the ratings of the first four episodes prompted The WB to pick up the series for a full season. Originally, Kripke planned the series for three seasons but later expanded it to five. The fifth season concluded the series' main storyline, and Kripke departed the series as showrunner. The series has continued on for several more seasons with Sera Gamble and Jeremy Carver assuming the role of showrunner.",
"description_source": "http://en.wikipedia.org/wiki/Supernatural_(U.S._TV_series)#Spin-off_series",
"start_date": "2005-09-13",
"end_date": null,
"country": "US",
"status": "Running",
"runtime": 60,
"network": "The CW",
"youtube_link": "6ZlnmAWL59I",
"image_path": "https://static.episodate.com/images/tv-show/full/5348.jpg",
"image_thumbnail_path": "https://static.episodate.com/images/tv-show/thumbnail/5348.jpg",
"rating": "9.6747",
"rating_count": "249",
"countdown": null
The value of rating
in different serials is Int
("rating": 0) or String
("rating": "9.6747").
I am parsing JSON with Codable/Decodable protocols:
struct DetailModel : Decodable
var id : Int?
var name : String?
var permalink : String?
var url : String?
var description : String
var description_source : String?
var start_date : String?
var end_date : String?
var country : String?
var status : String?
var runtime : Int?
var network : String?
var youtube_link : String?
var image_path : String?
var image_thumbnail_path : String?
var rating: String
var rating_count : String?
var countdown : String?
var genres : [String]?
var pictures : [String]?
var episodes : [EpisodesModel]?
If rating == String, my code work and I have all the variables from JSON, but if rating == Int, all is nil
. What should I do to parse all the types of variable rating
at once Int
and String
?
My decodable function:
func searchSerialDetail(id: Int, completion: @escaping (DetailModel?) -> Void)
let parameters: [String: Any] = ["q": id]
Alamofire.request(DetailNetworkLayer.url, method: .get, parameters: parameters).response (jsonResponse) in
if let jsonValue = jsonResponse.data
let jsonDecoder = JSONDecoder()
let detail = try? jsonDecoder.decode(DetailModel.self, from: jsonValue)
completion(detail)
Thank you.
This question already has an answer here:
What Is Preventing My Conversion From String to Int When Decoding Using Swift 4’s Codable?
1 answer
json swift alamofire swift4 decodable
json swift alamofire swift4 decodable
edited May 25 '18 at 12:57
alpha corrado
asked May 25 '18 at 9:44
alpha corradoalpha corrado
135
135
marked as duplicate by Dávid Pásztor, Community♦ May 25 '18 at 12:35
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by Dávid Pásztor, Community♦ May 25 '18 at 12:35
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
1
Why are almost all ofDetailModel
s properties optional? Only make them optional if they might not be present in the JSON. Moreover, makerating
aDouble
and create a custominit(from:)
method as explained in the linked Q&A to handle the conversion fromString
toDouble
. Also don't useresponseJSON
and don't mixJSONSerialization
andJSONDecoder
, simply takeresponse
fromAlamofire
asData
and parse that directly withJSONDecoder
. With your current code you're parsing the JSON twice for no reason.
– Dávid Pásztor
May 25 '18 at 10:05
No you didn't follow along the answer provided there. You should first go through the whole answer. Then you will understand what to implement for your case. You just scrolled through the answer and picked the first example. But the first example doesn't really solve that problem at all. Read the whole answer.
– nayem
May 25 '18 at 11:45
thank you guys, I solved this problem in several ways :)
– alpha corrado
May 25 '18 at 12:35
add a comment |
1
Why are almost all ofDetailModel
s properties optional? Only make them optional if they might not be present in the JSON. Moreover, makerating
aDouble
and create a custominit(from:)
method as explained in the linked Q&A to handle the conversion fromString
toDouble
. Also don't useresponseJSON
and don't mixJSONSerialization
andJSONDecoder
, simply takeresponse
fromAlamofire
asData
and parse that directly withJSONDecoder
. With your current code you're parsing the JSON twice for no reason.
– Dávid Pásztor
May 25 '18 at 10:05
No you didn't follow along the answer provided there. You should first go through the whole answer. Then you will understand what to implement for your case. You just scrolled through the answer and picked the first example. But the first example doesn't really solve that problem at all. Read the whole answer.
– nayem
May 25 '18 at 11:45
thank you guys, I solved this problem in several ways :)
– alpha corrado
May 25 '18 at 12:35
1
1
Why are almost all of
DetailModel
s properties optional? Only make them optional if they might not be present in the JSON. Moreover, make rating
a Double
and create a custom init(from:)
method as explained in the linked Q&A to handle the conversion from String
to Double
. Also don't use responseJSON
and don't mix JSONSerialization
and JSONDecoder
, simply take response
from Alamofire
as Data
and parse that directly with JSONDecoder
. With your current code you're parsing the JSON twice for no reason.– Dávid Pásztor
May 25 '18 at 10:05
Why are almost all of
DetailModel
s properties optional? Only make them optional if they might not be present in the JSON. Moreover, make rating
a Double
and create a custom init(from:)
method as explained in the linked Q&A to handle the conversion from String
to Double
. Also don't use responseJSON
and don't mix JSONSerialization
and JSONDecoder
, simply take response
from Alamofire
as Data
and parse that directly with JSONDecoder
. With your current code you're parsing the JSON twice for no reason.– Dávid Pásztor
May 25 '18 at 10:05
No you didn't follow along the answer provided there. You should first go through the whole answer. Then you will understand what to implement for your case. You just scrolled through the answer and picked the first example. But the first example doesn't really solve that problem at all. Read the whole answer.
– nayem
May 25 '18 at 11:45
No you didn't follow along the answer provided there. You should first go through the whole answer. Then you will understand what to implement for your case. You just scrolled through the answer and picked the first example. But the first example doesn't really solve that problem at all. Read the whole answer.
– nayem
May 25 '18 at 11:45
thank you guys, I solved this problem in several ways :)
– alpha corrado
May 25 '18 at 12:35
thank you guys, I solved this problem in several ways :)
– alpha corrado
May 25 '18 at 12:35
add a comment |
1 Answer
1
active
oldest
votes
You will have to implement your own func encode(to encoder: Encoder) throws
and init(from decoder: Decoder) throws
which are both properties of the Codable
protocol. Then change your rating
variable into an enum
Which would look like this:
enum Rating: Codable
case int(Int)
case string(String)
func encode(to encoder: Encoder) throws
var container = encoder.singleValueContainer()
switch self
case .int(let v): try container.encode(v)
case .string(let v): try container.encode(v)
init(from decoder: Decoder) throws
let value = try decoder.singleValueContainer()
if let v = try? value.decode(Int.self)
self = .int(v)
return
else if let v = try? value.decode(String.self)
self = .string(v)
return
throw Rating.ParseError.notRecognizedType(value)
enum ParseError: Error
case notRecognizedType(Any)
Then on your DetailModel
just change rating: String
to rating: Rating
This works, I have tested with these JSON strings.
// int rating
"rating": 200,
"bro": "Success"
// string rating
"rating": "200",
"bro": "Success"
Edit: I've found a better swiftier way of implementing init(from decoder: Decoder) throws
, which produces a better error message, by using this you can now omit the ParseError
enum.
init(from decoder: Decoder) throws
let value = try decoder.singleValueContainer()
do
self = .int(try value.decode(Int.self))
catch DecodingError.typeMismatch
self = .string(try value.decode(String.self))
Thank you, that solved my problem!!!
– alpha corrado
May 25 '18 at 11:19
Upvotes for this guy :D
– alpha corrado
May 25 '18 at 11:19
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You will have to implement your own func encode(to encoder: Encoder) throws
and init(from decoder: Decoder) throws
which are both properties of the Codable
protocol. Then change your rating
variable into an enum
Which would look like this:
enum Rating: Codable
case int(Int)
case string(String)
func encode(to encoder: Encoder) throws
var container = encoder.singleValueContainer()
switch self
case .int(let v): try container.encode(v)
case .string(let v): try container.encode(v)
init(from decoder: Decoder) throws
let value = try decoder.singleValueContainer()
if let v = try? value.decode(Int.self)
self = .int(v)
return
else if let v = try? value.decode(String.self)
self = .string(v)
return
throw Rating.ParseError.notRecognizedType(value)
enum ParseError: Error
case notRecognizedType(Any)
Then on your DetailModel
just change rating: String
to rating: Rating
This works, I have tested with these JSON strings.
// int rating
"rating": 200,
"bro": "Success"
// string rating
"rating": "200",
"bro": "Success"
Edit: I've found a better swiftier way of implementing init(from decoder: Decoder) throws
, which produces a better error message, by using this you can now omit the ParseError
enum.
init(from decoder: Decoder) throws
let value = try decoder.singleValueContainer()
do
self = .int(try value.decode(Int.self))
catch DecodingError.typeMismatch
self = .string(try value.decode(String.self))
Thank you, that solved my problem!!!
– alpha corrado
May 25 '18 at 11:19
Upvotes for this guy :D
– alpha corrado
May 25 '18 at 11:19
add a comment |
You will have to implement your own func encode(to encoder: Encoder) throws
and init(from decoder: Decoder) throws
which are both properties of the Codable
protocol. Then change your rating
variable into an enum
Which would look like this:
enum Rating: Codable
case int(Int)
case string(String)
func encode(to encoder: Encoder) throws
var container = encoder.singleValueContainer()
switch self
case .int(let v): try container.encode(v)
case .string(let v): try container.encode(v)
init(from decoder: Decoder) throws
let value = try decoder.singleValueContainer()
if let v = try? value.decode(Int.self)
self = .int(v)
return
else if let v = try? value.decode(String.self)
self = .string(v)
return
throw Rating.ParseError.notRecognizedType(value)
enum ParseError: Error
case notRecognizedType(Any)
Then on your DetailModel
just change rating: String
to rating: Rating
This works, I have tested with these JSON strings.
// int rating
"rating": 200,
"bro": "Success"
// string rating
"rating": "200",
"bro": "Success"
Edit: I've found a better swiftier way of implementing init(from decoder: Decoder) throws
, which produces a better error message, by using this you can now omit the ParseError
enum.
init(from decoder: Decoder) throws
let value = try decoder.singleValueContainer()
do
self = .int(try value.decode(Int.self))
catch DecodingError.typeMismatch
self = .string(try value.decode(String.self))
Thank you, that solved my problem!!!
– alpha corrado
May 25 '18 at 11:19
Upvotes for this guy :D
– alpha corrado
May 25 '18 at 11:19
add a comment |
You will have to implement your own func encode(to encoder: Encoder) throws
and init(from decoder: Decoder) throws
which are both properties of the Codable
protocol. Then change your rating
variable into an enum
Which would look like this:
enum Rating: Codable
case int(Int)
case string(String)
func encode(to encoder: Encoder) throws
var container = encoder.singleValueContainer()
switch self
case .int(let v): try container.encode(v)
case .string(let v): try container.encode(v)
init(from decoder: Decoder) throws
let value = try decoder.singleValueContainer()
if let v = try? value.decode(Int.self)
self = .int(v)
return
else if let v = try? value.decode(String.self)
self = .string(v)
return
throw Rating.ParseError.notRecognizedType(value)
enum ParseError: Error
case notRecognizedType(Any)
Then on your DetailModel
just change rating: String
to rating: Rating
This works, I have tested with these JSON strings.
// int rating
"rating": 200,
"bro": "Success"
// string rating
"rating": "200",
"bro": "Success"
Edit: I've found a better swiftier way of implementing init(from decoder: Decoder) throws
, which produces a better error message, by using this you can now omit the ParseError
enum.
init(from decoder: Decoder) throws
let value = try decoder.singleValueContainer()
do
self = .int(try value.decode(Int.self))
catch DecodingError.typeMismatch
self = .string(try value.decode(String.self))
You will have to implement your own func encode(to encoder: Encoder) throws
and init(from decoder: Decoder) throws
which are both properties of the Codable
protocol. Then change your rating
variable into an enum
Which would look like this:
enum Rating: Codable
case int(Int)
case string(String)
func encode(to encoder: Encoder) throws
var container = encoder.singleValueContainer()
switch self
case .int(let v): try container.encode(v)
case .string(let v): try container.encode(v)
init(from decoder: Decoder) throws
let value = try decoder.singleValueContainer()
if let v = try? value.decode(Int.self)
self = .int(v)
return
else if let v = try? value.decode(String.self)
self = .string(v)
return
throw Rating.ParseError.notRecognizedType(value)
enum ParseError: Error
case notRecognizedType(Any)
Then on your DetailModel
just change rating: String
to rating: Rating
This works, I have tested with these JSON strings.
// int rating
"rating": 200,
"bro": "Success"
// string rating
"rating": "200",
"bro": "Success"
Edit: I've found a better swiftier way of implementing init(from decoder: Decoder) throws
, which produces a better error message, by using this you can now omit the ParseError
enum.
init(from decoder: Decoder) throws
let value = try decoder.singleValueContainer()
do
self = .int(try value.decode(Int.self))
catch DecodingError.typeMismatch
self = .string(try value.decode(String.self))
edited May 26 '18 at 9:36
answered May 25 '18 at 10:43
Zonily JameZonily Jame
1,68611229
1,68611229
Thank you, that solved my problem!!!
– alpha corrado
May 25 '18 at 11:19
Upvotes for this guy :D
– alpha corrado
May 25 '18 at 11:19
add a comment |
Thank you, that solved my problem!!!
– alpha corrado
May 25 '18 at 11:19
Upvotes for this guy :D
– alpha corrado
May 25 '18 at 11:19
Thank you, that solved my problem!!!
– alpha corrado
May 25 '18 at 11:19
Thank you, that solved my problem!!!
– alpha corrado
May 25 '18 at 11:19
Upvotes for this guy :D
– alpha corrado
May 25 '18 at 11:19
Upvotes for this guy :D
– alpha corrado
May 25 '18 at 11:19
add a comment |
1
Why are almost all of
DetailModel
s properties optional? Only make them optional if they might not be present in the JSON. Moreover, makerating
aDouble
and create a custominit(from:)
method as explained in the linked Q&A to handle the conversion fromString
toDouble
. Also don't useresponseJSON
and don't mixJSONSerialization
andJSONDecoder
, simply takeresponse
fromAlamofire
asData
and parse that directly withJSONDecoder
. With your current code you're parsing the JSON twice for no reason.– Dávid Pásztor
May 25 '18 at 10:05
No you didn't follow along the answer provided there. You should first go through the whole answer. Then you will understand what to implement for your case. You just scrolled through the answer and picked the first example. But the first example doesn't really solve that problem at all. Read the whole answer.
– nayem
May 25 '18 at 11:45
thank you guys, I solved this problem in several ways :)
– alpha corrado
May 25 '18 at 12:35