jay's devnote
  • README
  • 자료구조 & 알고리즘
    • 자료구조
    • 알고리즘
  • 디자인 패턴
    • 디자인 패턴 원칙, 요약, 분류
    • IS-A 와 HAS-A
    • 전략 패턴
    • 옵저버 패턴
    • 데코레이터 패턴
    • 팩토리 패턴
    • 싱글턴 패턴
    • 커맨드 패턴
    • 어댑터, 퍼사드 패턴
    • 템플릿 메소드 패턴
    • 반복자, 컴포지트 패턴
    • 상태 패턴
    • 프록시 패턴
    • 복합 패턴
  • WWDC
    • 2015, Building Better Apps with Value Types in Swift
    • 2015, Protocol-Oriented Programming in Swift
    • 2016, Understanding Swift Performance
    • 2016, Protocol and Value Oriented Programming in UIKit Apps
    • 2017, Engineering for Testability
    • 2018, High Performance Auto Layout
    • 2018, Testing Tips & Tricks
    • 2020, Advances in UICollectionView
    • 2020, Lists in UICollectionView
  • 패러다임
    • 객체지향 프로그래밍, SOLID 원칙
      • SRP, 단일 책임 원칙
      • OCP, 개방 폐쇄 원칙
      • LSP, 리스코프 치환 원칙
      • ISP, 인터페이스 분리 원칙
      • DIP, 의존성 역전 원칙
    • 만들면서 느껴보는 POP
    • Swift로 함수형 프로그래밍 시작하기
  • 아키텍쳐
    • ReactorKit
      • Pulse(EN)
      • Pulse(KR)
    • Coordinator Pattern
  • iOS
    • Safari로 웹뷰의 세션/쿠키 정보 확인하기
    • App Icon 동적으로 변경하기
    • WKDataDetectorTypes의 데이터 탐지
    • Xcode에서 메모리 누수 확인하기
    • 개발 인증서 관리하기
    • required init?(coder: NSCoder)
    • UIFontMetrics 와 UIFont.preferredFont
    • 제약조건을 줄여주는 UIStackView
    • UICollectionView.CellRegistration<Cell, Item>
  • Swift
    • Swift API Design Guidelines
    • 패턴 매칭
    • allSatisfy()
    • 생성자
    • 프로토콜의 동적 디스패치와 정적 디스패치
    • Swift 문법 정리
  • RxSwift
    • RxSwift 핸드북
    • Just, From, Of
    • withLatestFrom
  • SwiftUI
    • SwiftUI에서의 마크다운 문법
    • @State, @Binding
    • ObservableObject, @ObservedObject, @Published
    • @ObservedObject vs @StateObject
  • Git
    • Git gitignore
    • Github API Rate limit
    • GitKraken(깃크라켄) 활용하기
    • GitKraken으로 Git-flow 활용하기
  • Etc
    • Struct을 [String: Any]로 변환할 때, Encodable의 Extension을 사용 해야 하나요?
    • Podfile, Dependency Rule(SPM)
    • 맥으로 고정 IP 연결하는 방법
    • SwiftPlantUML으로 UML 다이어그램 쉽게 그리기
    • Playground 가 열리지 않는 오류 해결하기
    • CocoaPods 제거하기
  • Python
    • 파이썬과 스위프트 문법 비교
    • 파이썬과 스위프트 문법 요약
  • Firebase
    • Storage를 API처럼 사용해보기
    • RealTime Database를 API처럼 사용해보기
Powered by GitBook
On this page
  1. SwiftUI

SwiftUI에서의 마크다운 문법

PreviousSwiftUINext@State, @Binding

Last updated 2 years ago

음, 그거 아십니까? SwiftUI에서 마크다운 문법을 지원합니다. 전 몰랐어요:) 어쩌다가 우연히 알게 됐는데, 꽤나 신기해서 글로 남겨봅니다.

사용할 수 있는 것은 iOS15부터 인데요. 에 아래와 같이 추가되어 있습니다.

SwiftUI

New Features

LocalizedStringKey can now contain Markdown syntax. The system parses Markdown strings when you create a Text view from a LocalizedStringKey, including Text views created with a string literal. The system styles Text according to Markdown constructs. (74515884)

하나씩 차근차근 설명해볼게요. 일단 해석해보면, LocalizedStringKey가 마크다운 문법을 포함할 수 있다고 되어있죠? 여기서 LocalizedStringKey 부터 알아볼게요.

공식문서는 있습니다. iOS13부터 사용되었고, 얘는 이름도 현지화문자열키이긴 하지만 밑에 오버뷰를 보면 바로 의미를 이해할 수 있어요.

Initializers for several SwiftUI types – such as Text, Toggle, Picker and others – implicitly look up a localized string when you provide a string literal.

즉, 우리가 SwiftUI에서 가장 흔하게 쓰는 타입들 Text, Toggle, Picker들이 암시적으로 현지화된 문자열을 조회한다는 거죠. 이게 무슨 말이냐 ?

일단 우리가 Text("Hello")라는 뷰를 SwiftUI에서 만들다고 하면, 그건 실제로는 이 생성자를 사용하고 있는 겁니다.

init(_ key: LocalizedStringKey, 
	   tableName: String? = nil, 
       bundle: Bundle? = nil, 
       comment: StaticString? = nil)

즉, 우리는 그냥 string을 넣는다고 생각하고 있지만 실제로는 아래와 같이 LocalizedStringKey를 생성해서 넣어주고 있는 거에요.

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
@frozen public struct LocalizedStringKey : Equatable, ExpressibleByStringInterpolation {

    /// Creates a localized string key from the given string value.
    ///
    /// - Parameter value: The string to use as a localization key.
    public init(_ value: String)
    ///...
}

그리고 아까 암시적으로 현지화된 문자열을 조회한다고 했죠? 그러면 저 LocalizedStringKey은 Text.init()의 예시대로 저 키값에 맞는 LocalizedStringKey가 있는지 확인을 해보는 겁니다. 그리고 키값이 있다면 현지화해서 뷰를 그려주는 거죠.

더 구체화해서 설명하면, 아래와 같습니다. 😄

  1. 현지화를 위해 Localizable.strings(English) 파일을 만든다.

  2. "안녕" = "Hello"; 를 입력해놓는다.

  3. SwiftUI에서 뷰를 그린다. Text("Hello")

  4. "Hello"는 LocalizedStringKey를 통해 현지화키값을 생성하고, 해당 키값에 맞는 value가 있는지 확인한다.

  5. 있다. Hello -> 안녕

  6. SwiftUI는 안녕이라는 Text 뷰를 그린다.

그래서 그게 어쨌다는..?

아, 약간 좀 돌아왔죠? ^^; LocalizedStringKey를 이해하기 위해서 약간 설명을 좀 하느라 돌아왔네요.

그래서 결론은, 이 _LocalizedStringKey가 실제로 우리가 SwiftUI에서 Text, Toggle, Picker 등을 만들 때 사용된다는 것이고 iOS 15부터는 이 LocalizedStringKey에 마크다운 문법이 적용된다는 것_이죠.

즉, 이게 된다는 겁니다.

import SwiftUI

struct MarkDownSwiftVIew: View {
    
    var body: some View {
        Text("""
             # Hello, world
             **This is bold text**
             *This text is italicized*
             ~~This was mistaken text~~
             **This text is _extremely_ important**
             ***All this text is important***
             [apple.com](https://www.apple.com)
             """
        )
    }
    
}

struct MarkDownSwiftVIew_Previews: PreviewProvider {
    static var previews: some View {
        MarkDownSwiftVIew()
    }
}

신기하죠 ?😀

물론 전부 다 지원되는 것은 아닙니다. 아직 몇 가지 지원되지 않는 것들이 있어보여요.

그래도 취소선, 하이퍼링크 등이 되니까 꽤나 신기한 것 같습니다. 앞으로 더 지원이 많이 되겠죠.

아 그리고, 원한다면 현지화를 포함하지 않고 생성하는 방법도 당연히 가능한데요.

Text(verbatim: "pencil") // Displays the string "pencil" in any locale.

그리고 또 다른 예외로 이런 것도 있는데요. 아래와 같은 코드가 있고, Localizable.strings의 일본어 현지화 파일도 있다고 해볼게요.

"Today" = "今日";
List {
    Section(header: Text("Today")) {
        ForEach(messageStore.today) { message in
            Text(message.title)
        }
    }
}

그럼 뷰는 어떻게 그려질까요 ? 아래와 같이 그려집니다.

Reference

그리고 많은 마크다운의 형제? 중에서도 을 지원하고 있습니다. 이건 오피셜로 애플 개발자 포럼에서 을 주었어요.

아래의 생성자를 사용하면 가능합니다. 공식 문서는 에 있어요.

이유는 위에서 설명한 것과 같아요. Text("Today")는 LocalizedStringKey값을 생성해서 로컬라이징키에 따른 아웃풋이 있는지 암시적으로 조회하지만, ForEach 문을 통해 생성되는 Text(message.title)은 변수 이므로 뷰는 문자열 값을 그대로 사용하기 때문입니다. 이 내용도 에 있는 내용이니 읽어보셔도 좋겠네요.

iOS15 릴리즈 노트
여기
GFM(Github Flavored Markdown)
답변
여기
공식문서
https://developer.apple.com/documentation/swiftui/localizedstringkey/init(_:)
https://developer.apple.com/documentation/SwiftUI/LocalizedStringKey
https://developer.apple.com/documentation/ios-ipados-release-notes/ios-ipados-15-release-notes
https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax
https://developer.apple.com/forums/thread/682711
https://developer.apple.com/documentation/swiftui/text/init(verbatim:)