iOS15でSwiftUIのTextのMarkdown syntaxを無効にする

# はじめに
iOS15がリリースされて、SwiftUIにもいろいろな機能が追加されています。
文字列を表示する[Text](https://developer.apple.com/documentation/swiftui/text)にもMarkdown syntaxがサポートされるようになりました。

触ってみて気になったこと、気付いたことを備忘としてまとめておきます。

# iOS15と14までとの違い

```swift:ContentView.swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Hello, **SwiftUI**! [documents here](https://developer.apple.com/documentation/swiftui/)")
        }
    }
}
```

こちらのサンプルコードのビューを表示すると、iOS15未満の場合はプレーンテキストとして描画されますが、iOS15ではMarkdownフォーマットで描画されて、リンクも有効になりました。

|iOS14.4|iOS 15.0|
|:--:|:--:|
|![Simulator Screen Shot - iPhone 12 mini - 2021-10-19 at 16.29.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/c0ef6a91-fc48-841f-6c64-a4049964db7e.png)|![result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/ae71d5aa-aeed-a006-c698-440faf7325c9.gif)|

`Text(<String literal>)`の挙動をOS別にまとめるとこんな感じでした。

|OSバージョン|挙動|
|:--:|:--:|
|iOS15.0未満|プレーンテキストで描画される|
|iOS15.0以上|Markdownフォーマットで描画される|

# iOS15でSwiftUIのTextのMarkdown syntaxを無効にしてみる
こちらが本記事の本題です。
Markdown syntaxがサポートされるようになったのは分かったけど、プレーンテキストとして使いたい場合どうするのか調べてみました。

```swift:ContentView.swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            // Use `init(verbatim:)`
            Text(verbatim: "Hello, **SwiftUI**! [documents here](https://developer.apple.com/documentation/swiftui/)")
        }
    }
}
```

結論、 [init(verbatim:)](https://developer.apple.com/documentation/swiftui/text/init(verbatim:))を使用することで、iOS15でもMarkdown syntaxを無効にしてプレーンテキストとして描画されたのですが、
あらためてドキュメントを見てみると気になることが書いてありました。

```swift:SwiftUI>Text
    /// Creates a text view that displays a string literal without localization.
    ///
    /// Use this initializer to create a text view with a string literal without
    /// performing localization:
    ///
    ///     Text(verbatim: "pencil") // Displays the string "pencil" in any locale.
    ///
    /// If you want to localize a string literal before displaying it, use the
    /// ``Text/init(_:tableName:bundle:comment:)`` initializer instead. If you
    /// want to display a string variable, use the ``Text/init(_:)-9d1g4``
    /// initializer, which also bypasses localization.
    ///
    /// - Parameter content: A string to display without localization.
    @inlinable public init(verbatim content: String)
```

init(verbatim:)はローカライズ無しで、文字列リテラルを表示するよ。
ローカライズする場合は、`init(_:tableName:bundle:comment:)`を使用してね。
といった感じでしょうか。

```swift:SwiftUI>Text
    /// Creates a text view that displays localized content identified by a key.
    ///
    /// ...（略）
    ///
    /// - Parameters:
    ///   - key: The key for a string in the table identified by `tableName`.
    ///   - tableName: The name of the string table to search. If `nil`, use the
    ///     table in the `Localizable.strings` file.
    ///   - bundle: The bundle containing the strings file. If `nil`, use the
    ///     main bundle.
    ///   - comment: Contextual information about this key-value pair.
    public init(_ key: LocalizedStringKey, tableName: String? = nil, bundle: Bundle? = nil, comment: StaticString? = nil)
```

`init(_:tableName:bundle:comment:)`の定義を見てみると、`tableName`, `bundle`, `comment`はデフォルト値が定義されているので、

```Localizable.strings
"Apple" = "りんご";
```
Localizable.stringsの定義が↑このようになっている場合、`Text("Apple")`でローカライズされた「りんご」という文字列が描画されます。

現実的では無いかとは思いますが、、Localizable.stringsにMarkdown syntaxの文字列リテラルがキーとして定義されていたら、どっちが勝つ（優先される）のだろうかと気になりました...( ˘•ω•˘ )

# Localizable.stringsのキーにMarkdown syntaxの文字列リテラルを使用してみる

以下のようなローカライズキーを定義して試してみました。

```Localizable.strings
"Apple" = "りんご";
"**Apple**" = "りんご！";
```

```swift:ContentView.swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Apple")
            Text("**Apple**")
            Text(verbatim: "Apple")
            Text(verbatim: "**Apple**")
        }
    }
}
```

Localizable.stringsに`"Apple"`, `"**Apple**"`が定義されている場合と、定義されていない場合ではそれぞれ以下のような結果になりました。

|Localizable.stringsに`"Apple"`, `"**Apple**"`が<BR>定義されている場合|定義されていない場合|
|:--:|:--:|
|![kye_有り.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/080200d3-3e8a-7177-c5dc-aace8c3a3fb5.png)|![kye_無し.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103695/508be67d-33d8-b7e5-94e0-f38758e60d24.png)|

# まとめ
- Localizable.stringsに`<String literal>`のローカライズキーの定義が有る場合
  - ローカライズされた文字列が表示される
- Localizable.stringsに`<String literal>`のローカライズキーの定義が無い場合 => 
  - Markdownやプレーンテキストとして文字列が表示される
という順番で`Text(<String literal>)`は判定される。

Markdown syntaxを文字列リテラルとして表示したい場合は、`init(verbatim:)`を使用する。