1. ホーム
  2. json

[解決済み] SwiftでHTMLエンティティをデコードするには?

2022-07-03 02:28:22

質問

あるサイトからJSONファイルを取得しているのですが、受信した文字列の1つは、次のようになっています。

The Weeknd ‘King Of The Fall’ [Video Premiere] | @TheWeeknd | #SoPhi

のようなものはどのように変換すればよいのでしょうか? &#8216 のようなものを正しい文字に変換するにはどうしたらよいでしょうか?

XcodeのPlaygroundを作ってデモしてみました。

import UIKit

var error: NSError?
let blogUrl: NSURL = NSURL.URLWithString("http://sophisticatedignorance.net/api/get_recent_summary/")
let jsonData = NSData(contentsOfURL: blogUrl)

let dataDictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &error) as NSDictionary

var a = dataDictionary["posts"] as NSArray

println(a[0]["title"])

どのように解決するのですか?

この回答は Swift 5.2 および iOS 13.4 SDK 用に最後に修正されました。


ストレートな方法はないのですが、以下のように NSAttributedString マジックを使って、この処理をできるだけ簡単に行うことができます (この方法では、すべての HTML タグも除去してしまうので注意してください)。

以下のことを忘れないでください。 を初期化することを忘れないでください。 NSAttributedString メインスレッドのみから . 下のHTMLのパースにWebKitを使用しているため、このような要件があります。

// This is a[0]["title"] in your case
let htmlEncodedString = "The Weeknd <em>&#8216;King Of The Fall&#8217;</em>"

guard let data = htmlEncodedString.data(using: .utf8) else {
    return
}

let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
    .documentType: NSAttributedString.DocumentType.html,
    .characterEncoding: String.Encoding.utf8.rawValue
]

guard let attributedString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) else {
    return
}

// The Weeknd ‘King Of The Fall’
let decodedString = attributedString.string

extension String {

    init?(htmlEncodedString: String) {

        guard let data = htmlEncodedString.data(using: .utf8) else {
            return nil
        }

        let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
            .documentType: NSAttributedString.DocumentType.html,
            .characterEncoding: String.Encoding.utf8.rawValue
        ]

        guard let attributedString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) else {
            return nil
        }

        self.init(attributedString.string)

    }

}

let encodedString = "The Weeknd <em>&#8216;King Of The Fall&#8217;</em>"
let decodedString = String(htmlEncodedString: encodedString)