HTMLをより自在にStringに変換したい！HTMLテンプレートを使ってみよう

# はじめに 
APIからテキスト情報を受け取り、画面に表示することは本当に日常のようなことだと思いますが、
以下のようにHTML様式で情報を受け取る時はどうすれば良いでしょうか。  
簡単な方法からHTMLテンプレートを使ったより柔軟なテキスト変換を調べてみましょう。

```html 
"おはようございます。<br>\r\nテストで作ってます<br>蒸し暑いですな。</u>\r\n<br>\r\n<b>助けてください</b><br><br>\r\n\r\n<br><br>\r\n<p style=\"color:red;\">うああああああああ</p><br>"
```
# 実用例
```swift 
import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var testLabel: UILabel!
    
    let originText = "おはようございます。<br>\r\nテストで作ってます<br>蒸し暑いですな。</u>\r\n<br>\r\n<b>助けてください</b><br><br>\r\n\r\n<br><br>\r\n<p style=\"color:red;\">うああああああああ</p><br>"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        testLabel.text = originText
    }
}
``` 
(originTextはAPIから受け取ってるテキストだと考えてください)   
仮に上のようなコードがあると考えてみましょう。このままでビルドすると下のようになります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3484291/bd0d1e2e-f5ad-60a8-2ee1-82a73b7d67ef.png" width="200">
一瞬見てもよろしくないですね。このHTMLタグを単純に消すだけではなく、
タグで設定されてるスタイルを適用するには一応Stringをextensionしましょう。 
```swift 
extension String {
    var htmlToAttributedString: NSMutableAttributedString? {
        guard let data = data(using: .utf8) else { return nil }
        do {
            return try NSMutableAttributedString(data: data,
                                                 options: [.documentType: NSMutableAttributedString.DocumentType.html,
                                                           .characterEncoding: String.Encoding.utf8.rawValue],
                                                           documentAttributes: nil)
        } catch {
            return nil
        }
    }
}

// ViewDidLoad
override func viewDidLoad() {
        super.viewDidLoad()
        let attributedText = originText.htmlToAttributedString
        //testLabel.textではなく、attributedTextであることに注意
        testLabel.attributedText = attributedText
    }
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3484291/44b915ad-dd7c-c2a3-bc35-38e069620df5.png" width="200">   


上記のようにHTML文が綺麗に変わったことを確認できます。
ですが、まだサイズが小さくて読みにくい問題が残ってます。
これを解決するうちに、黒いテキストの色も青に変えてみましょう。　
```swift 
override func viewDidLoad() {
        super.viewDidLoad()
        let attributedText = originText.htmlToAttributedString
        //addAttributeで属性を追加
        attributedText?.addAttribute(.font, value: UIFont(name: "HiraginoSans-W3", size: 20)!, range: NSRange(location: 0, length: attributedText?.length ?? 0))
        attributedText?.addAttribute(.foregroundColor, value: UIColor(ciColor: .blue), range: NSRange(location: 0, length: attributedText?.length ?? 0))

        testLabel.attributedText = attributedText
    }
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3484291/d17fd791-7bbf-f03e-8ddb-4bc5e0e063c5.png" width="200">　　　
こうすると赤文字も青になり、原文HTMLのボルドタグも適用されなくなる問題があります。
私はこれを直すためにHTML Templateを使いました。
実用例を見ましょう。
# HTML Templateを使った実用例
```swift 
class ViewController: UIViewController {
    @IBOutlet weak var testLabel: UILabel!
    
    let originText = "おはようございます。<br>\r\nテストで作ってます<br>蒸し暑いですな。</u>\r\n<br>\r\n<b>助けてください</b><br><br>\r\n\r\n<br><br>\r\n<p style=\"color:red;\">うああああああああ</p><br>"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let attributedText = originText.htmlToAttributedStringWithAttributes(font: UIFont(name: "HiraginoSans-W3", size: 20)!, color: UIColor(ciColor: .blue))
        testLabel.attributedText = attributedText
    }
}
```
```swift
extension String {
    func htmlToAttributedStringWithAttributes(font: UIFont, color: UIColor) -> NSMutableAttributedString? {
            let htmlTemplate = """
            <!doctype html>
            <html>
              <head>
                <style>
                  body {
                    font-family: \(font.fontName);
                    font-size: \(font.pointSize)px;
                    color: \(color.hexString);
                  }
                </style>
              </head>
              <body>
                \(self)
              </body>
            </html>
            """

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

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

            return try? NSMutableAttributedString(data: data, options: options, documentAttributes: nil)
        }
}
```
```swift 
extension UIColor {
    var hexString: String {
        let components = self.cgColor.components!
        let r = components[0]
        let g = components[1]
        let b = components[2]
        let a = components[3]
        let hexString = String(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)), lroundf(Float(b * 255)))
        return hexString
    }
}
```
本文がhtmlTemplateのbodyとなり、
使いたいfontの種類や、大きさ、色はhtmlTemplate中のstyleになるようにしました。
こうするとdataは完全なHTML文となり、これを変換することができるようになります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3484291/6e03ccc3-38a3-c550-2a5f-4d562f3ad5e5.png" width="200">
もちろん、普通のテキストを受け取り、Storyboardやコードでテキストを表示することが一番ですが、
不可避にこのようにHTML形式のテキストを受け取らないといけない状況が来た時はぜひ使ってみてください。   
より良い方法がありますと、コメントで教えてください！ 
あなたの心優しいコメントがニュービ開発者に力となります。  
長い文読んでくださってありがとうございました。