Home > database >  Decode html string from json
Decode html string from json

Time:12-22

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

  • Related