SwiftUI

SwiftUI Markdown 사용에 대한 3가지 특이점

Phililip
728x90

안녕하세요.

 

WWDC 2021 발표를 통해, iOS 15 이상 Foundation과 SwiftUI에서 Markdown을 사용할 수 있다는 것 알고 계셨나요??

 

이번 글은 SwiftUI에서 markdown을 사용할 때, 고려해야 할 3가지 특이점에 대해 소개해보려고 합니다.

 

 

 

# 1. GFM 지원

SwiftUI는 Github Flavored Markdown(GFM)을 지원합니다.

 

쉽게 확인할 수 있는 예로, CommonMark에서는 지원하지 않는 취소선(문자열을 ~~로 감싼 것)이 SwiftUI에서는 사용이 가능합니다.

 

Text("Hello ~~world!~~")

 

 

써보니까 GFM도 지원하는 것 같은데?? 라고 추측한 것은 아니고...

 

Apple Developer forum에서 GFM을 지원한다고 공식적으로 답변을 주었습니다. 👍 👍

 

Yes, it is GitHub flavored markdown. AttributedString converts both inline and block styles. SwiftUI renders inline styles (but not images at this time). We use the fantastic cmark-gfm library to parse the markdown string.

 

 

 

 

# 2. String 변수는 markdown 사용 불가능

저희는 위에서 Text 안에 string을 넘겨서 markdown 형식으로 출력되는 것을 확인했습니다.

(정확하게는 string 변수를 넘긴 것이 아니라 string literal을 넘긴 것입니다.)

 

Text("**Hello**, *world!*")

 

 

그런데, string 변수를 사용하면 제대로 동작하지 않습니다.

 

struct ContentView: View {
    let markdown = "**Hello**, *world!*"
    var body: some View {
        Text(markdown)
    }
}

 

 

이렇게 호출해봐도 결과는 똑같아요ㅠㅠ

 

struct ContentView: View {
    let markdown = "**Hello**, *world!*"
    var body: some View {
        Text("\(markdown)")
    }
}

 

 

 

대신에, LocalizedStringKeyinit(_:)을 사용하면 정상 동작하는 것을 볼 수 있어요.

 

struct ContentView: View {
    let markdown = "**Hello**, *world!*"
    var body: some View {
        Text(.init(markdown))	✅
    }
}

 

 

왜 그럴까요???

 

Text 뷰string 변수를 넘기면, localization 없이 string 변수에 있는 text를 화면에 출력합니다.

 

 

 

또한, Text 뷰에 string literal을 넘기면, LocalizedStringKey 생성자를 호출해서 localizedstring을 화면에 출력합니다.

 

 

 

(LocalizedStringKey가 ExpressibleByStringLiteral 프로토콜을 준수하니 가능한 일이겠죠??ㅎㅎ)

 

@frozen public struct LocalizedStringKey : Equatable, ExpressibleByStringInterpolation {
	// ...
}

public protocol ExpressibleByStringInterpolation : ExpressibleByStringLiteral {
	// ...
}

 

 

Text 뷰에서 마크다운 형식으로 출력하려면, LocalizedStringKey 생성자를 사용해야 하니,

 

string 변수를 사용하는 대신 LocalizedStringKey의 init(_:) method를 사용하는 것이죠!!! ㅎㅎㅎ

 

 

 

 

# 3. AttributedString에서 개행이 필요한 경우 MarkdownParsingOptions를 사용

AttributedString을 사용하면 markdown이 지원됩니다.

 

struct ContentView: View {
    let attributedString = try! AttributedString(markdown: "**Hello** ~~world!~~")
    var body: some View {
        Text(attributedString)
    }
}

 

 

하지만 개행을 넣으면, 줄 바꿈이 화면에 적용되지 않습니다.

 

struct ContentView: View {
    let attributedString = try! AttributedString(markdown: "**Hello** ~~world!~~\nNewLine")
    var body: some View {
        Text(attributedString)
    }
}

 

 

 

개행이 필요한 경우, AttributedString 초기화할 때 option으로 .inlineOnlyPreservingWhitespace를 넣어주세요.

 

struct ContentView: View {
    let attributedString = try! AttributedString(markdown: "**Hello** ~~world!~~\nNewLine", options: .init(interpretedSyntax: .inlineOnlyPreservingWhitespace))	✅
    var body: some View {
        Text(attributedString)
    }
}

 

 

 

 

## 참고

- https://blog.eidinger.info/3-surprises-when-using-markdown-in-swiftui

 

 


 

 

이번 글은 여기서 마무리.

 

 

 

 

반응형

'SwiftUI' 카테고리의 다른 글

renderingMode(_:)  (0) 2022.03.01
AlignmentGuide  (0) 2022.02.27
스크린샷 주의 팝업, 화면 녹화 방지  (3) 2022.02.25
addArc(tangent1End:tangent2End:radius:)  (0) 2022.02.22
iOS 15에 추가된 background 관련 신규 method  (0) 2022.02.21