33
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Swift その2Advent Calendar 2016

Day 9

Swift で Markdown をレンダリングしたい時どうしたか

Last updated at Posted at 2016-12-10

Swift その2 Advent Calendar 2016 9日目です!

Swift と言いつつ iOS と JavaScript の話がメインになってしまいました :pray: :bow:

ピーちゃん

ピーちゃんという、 esa.io の iOS クライアントアプリを作っていて、そこで Markdown をアプリ上で表示しています。
その時どうやって Markdown をレンダリングしていったかやり方を書いていきます。

Swift で Markdown

Swift で Markdown をレンダリングしたい時は以下の方法があるかと思います。

  1. Markdown を自力で Parse して、記法に応じたフォントサイズや太さなどを設定し表示
  2. SimonFairbairn/SwiftyMarkdown などライブラリを使用
  3. WebView で JavaScript を使い表示

1 は厳しいというか面倒、2 も何か制限がありあそうだしこれ使っておけば安心というデファクトスタンダードというほどではない。
3 は JS の Markdown ライブラリも豊富にあり良さそう、ということで WebView に Markdown を渡す方式にしました。

WebView で Markdown を表示

  1. Markdown をレンダリングするための html/js をローカルに用意する
  2. WebView がその html を読み込む
  3. html の読み込みが完了したら Markdown を js に渡す
  4. js が Markdown を解釈しレンダリングする

の手順で読み込んでいきます。
ここでは UIWebView を使っていますが、良い子は WKWebView を使ってください。

1. Markdown をレンダリングするための html/js をローカルに用意する

各ライブラリの取得

Markdown をレンダリングする js ライブラリとして marked.js、 css ライブラリとして github-markdown-css を利用します。
せっかくなので emoji も表示したいですね :sushi: 。では emojify の js と css もお借りしましょう。

上記の js / css をダウンロードしフォルダに配置します。
また、それらのライブラリを利用する本体の md.html も作成してしまいましょう。

そうすると、 Xcode にはこのように表示されているはずです。

unspecified.png

md.html でライブラリを読み込む

上記で設置した md.html で 各ライブラリを読み込んでいきます。

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script type="text/javascript" src="./emojify.min.js"></script>
  <link rel="stylesheet" href="./emojify.min.css">
  <script type="text/javascript" src="./marked.js"></script>
  <link rel="stylesheet" href="./github-markdown.css">
  <script>
  function insert(html) {
    marked.setOptions({
      gfm: true,
      tables: true,
      breaks: true
    });
    document.getElementById('content').innerHTML = marked(html);
    emojify.setConfig({img_dir: 'https://github.global.ssl.fastly.net/images/icons/emoji/' });
    emojify.run(document.getElementById('content'));
  }
  </script>
</head>

<body>
  <article class="markdown-body">
    <div id="content" />
  </article>
</body>

</html>

各ライブラリの読み込みと function insert(html) で Markdown を Swift 側から受け取る準備をしています。

ここら辺は marked.js や emojify の使い方になってくるので、詳しくは各ドキュメントを参照ください。

2. WebView がその html を読み込む

ViewController の viewDidLoad などで html を読み込みます。

    override func viewDidLoad() {
        super.viewDidLoad()
        let url = Bundle().url(forResource: "md", withExtension: "html")
        let req = URLRequest(url: url)
        webView.loadRequest(req)
    }

3. html の読み込みが完了したら Markdown を js に渡す

    func webViewDidFinishLoad(_ webView: UIWebView) {
        setMarkdown()
    }

    func setMarkdown() {
        let markdown = "# h1\\n ## h2 \\n * list\\n    * :)"
        let js = "insert('\(markdown)');"
        self.webView.stringByEvaluatingJavaScript(from: js)
    }

webView の stringByEvaluatingJavaScript を使い、先ほど用意した function insert(html) で js を実行しています。

ここで少し注意が必要で、 Swift 側で html の読み込みが完了する前に js を実行してしまうと js の実行が失敗してしまうので、 webViewDidFinishLoad が呼ばれるまで待ちます。

4. js が Markdown を解釈しレンダリングする

無事レンダリングされました :relaxed:

2016-12-10 16.32.46.png

おわり

WebView を使い Markdown をレンダリングする一通りの流れを記載しました。 :blush:

あまり Swift Advent Clendar とは関係ない話になってしまいましたが :bow: 誰かの役に立てればと思います :muscle:

33
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?