How can i decode this string
"<div id=\"readability-page-1\" class=\"page\">test<div>"
I receive this object from an api and i want to decode it into a struct:
{
"id": 5,
"title": "iOS and iPadOS 14: The MacStories Review",
"content": "<div id=\"readability-page-1\" class=\"page\">test<div>"
}
struct ArticleModel: Codable, Identifiable {
let id: Int
let title: String
let content: String
}
However this throws the error
debugDescription : "The given data was not valid JSON."
▿ underlyingError : Optional<Error>
- some : Error Domain=NSCocoaErrorDomain Code=3840 "Badly formed object around line 45, column 25." UserInfo={NSDebugDescription=Badly formed object around line 45, column 25., NSJSONSerializationErrorIndex=1437}
How can i escape the special characters " ?
I want to display the string in a view as an attributed string.
Testing via playground
import UIKit
let json = """
{
"id": 5,
"title": "iOS and iPadOS 14: The MacStories Review",
"content": "<div id=\"readability-page-1\" class=\"page\">test<div>"
}
"""
struct ArticleModel: Codable, Identifiable {
let id: Int
let title: String
let content: String
}
let jsonData = json.data(using: .utf8)!
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let article = try decoder.decode(ArticleModel.self, from: jsonData)
print(article)
CodePudding user response:
The JSON seems incorrect. There seems to be a missing "
at the end of the value of "content":
.
EDIT:
After your update, I took another look. You need to escape double quotes in a string. Weirdly enough, in this case (when the JSON is in a multi-line string), you need to escape the escaping character as well (i.e. \\
) to decode the JSON properly and get a string you can work with.
Example:
import UIKit
let json = """
{
"id": 5,
"title": "iOS and iPadOS 14: The MacStories Review",
"content": "<div id=\\"readability-page-1\\" class=\\"page\\">test<div>"
}
"""
struct ArticleModel: Codable, Identifiable {
let id: Int
let title: String
let content: String
}
let jsonData = json.data(using: .utf8)!
let article = try JSONDecoder().decode(ArticleModel.self, from: jsonData)
print(article) // ArticleModel(id: 5, title: "iOS and iPadOS 14: The MacStories Review", content: "<div id=\"readability-page-1\" class=\"page\">test<div>")
By the way, https://app.quicktype.io/ is a great tool to get decoders (and encoders) for your JSON.
CodePudding user response:
You can use single quotes to make the json look better, and it would still be a valid HTML
let realJson = "{\"id\": 5,\"title\": \"iOS and iPadOS 14: The MacStories Review\",\"content\": \"<div id='readability-page-1' class='page'>test<div>\"}"
func parseJson(for json: String?) -> ArticleModel? {
guard let json = json, let jsonData = json.data(using: .utf8) else { return nil }
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
guard let article = try? decoder.decode(ArticleModel.self, from: jsonData) else { return nil }
return article
}
let article = parseJson(for: realJson)
print(article?.id ?? 0)
struct ArticleModel: Codable, Identifiable {
let id: Int
let title: String
let content: String
}
Imo. For a more readable code, maybe having the JSON in a .txt file and reading it from there, would be better
Cheers