ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SwiftUI 4.0 - NavigationPath
    SwiftUI 2022. 6. 23. 10:27

    안녕하세요. 그린입니다🟢

    이번 포스팅에서는 SwiftUI 4.0에서 네비게이션 관련해서 새로운 API가 나오면서 딸려온 NavigationPath에 대해 알아보겠습니다🙋🏻

     

    아마.. 짧을거고요(분량이) 아마.. 짧을겁니다(내용이)🕺🏻

     

    저번 포스팅이였던 NavigationStack을 살펴보면서 SwiftUI에서 네비게이션이 많이 편리해졌구나~ 쓸맛 나겠는데?

    라고 학습하면서 느꼈어요!

    혹시 궁금하시거나 안보신 분들은 아래 NavigationStack 포스팅을 선행해주세요🙌

    https://green1229.tistory.com/256

     

    SwiftUI 4.0 - NavigationStack

    안녕하세요. 그린입니다🟢 이번 포스팅에서는 SwiftUI 4.0에서 발표된 NavigationStack에 대해 학습해보겠습니다🙌 들어가기전 주절주절 개인적으로 이번 SwiftUI 4.0 업데이트 사항이 좋은것들이 참 많

    green1229.tistory.com

     

    여기서 각 네비게이션의 스택이 NavigationPath의 인스턴스로 만들어져 관리 될 수 있다는걸 아주 슉~하고 언급한 바가 있습니다.

    그래서 이 NavigationPath이라는 타입이 뭔지 딥하게 알아보려합니다!

     

    NavigationPath?

    WWDC 2022에서 Navigation 부문에서 같이 소개되었으며 iOS 16 부터 사용할 수 있습니다.

    공식문서에서는 NavigationPath을 "네비게이션 스택의 내용을 나타내는 데이터의 타입이 지워진 목록" 이라고 합니다.

    쉽게 생각해보면 그냥 네비게이션 스택에 각 컨텐츠들이 들어갈텐데 이를 가지고 있는 리스트라고 보면 될것 같습니다.

     

    NavigationPath 선언

    struct NavigationPath

    끝....

    심플 단촐 그자체 ✨

     

    NavigationPath Overview

    데이터 컬렉션에 대한 바인딩을 통해 스택을 초기화해 NavigationStack의 상태를 관리합니다.

    스택은 스택의 각 뷰에 대한 컬렉션의 데이터 항목을 저장합니다.

    즉 각 뷰들이 스택의 데이터로 저장되는 것이죠!

    또한 이미 이전 포스팅에서도 겪었다시피 컬렉션을 읽고 쓸 수 있기에 스택의 상태를 확인할 수도 있고 변경할 수도 있습니다.

    스택이 한 종류의 데이터에만 의존하는 뷰를 나타내는 경우 배열과 같은 표준 컬렉션을 사용해 데이터를 가질 수 있습니다.

    반면 단일 스택에 다른 타입의 데이터를 나타내야하는 경우 navigation path를 사용해야합니다.

    path는 타입 이레이저 (타입 지우기?)를 사용하기에 여러 종류의 요소들을 관리할 수 있습니다.

    path는 데이터 요소를 추가 및 계산, 제거 등을 위한 일반적인 컬렉션 제어 기능을 제공합니다.

    즉,  path를 변경해 뷰를 빠져나갈 수도 최상단으로 뷰를 이동시킬수도 있다는 말입니다.

     

    Serialize the path

    네비게이션 스택에 표시되는 값이 Codable 프로토콜과 준수하면 path의 Codable 프로퍼티를 사용해 path의 직렬화 표현을 얻을 수 있습니다.

    이를 통해 스택의 내용을 저장하고 복원할 수 있습니다.

    예를들어 path의 직렬화 및 역직렬화를 처리하는것을 ObservableObject로 정의할 수 있습니다.

    그럼 아래 공식문서의 예시 코드로 보시죠!

    class MyModelObject: ObservableObject {
      @Published var path: NavigationPath
    
      static func readSerializedData() -> Data? {
          // Read data representing the path from app's persistent storage.
      }
    
      static func writeSerializedData(_ data: Data) {
          // Write data representing the path to app's persistent storage.
      }
    
      init() {
          if let data = Self.readSerializedData() {
              do {
                  let representation = try JSONDecoder().decode(
                      NavigationPath.CodableRepresentation.self,
                      from: data)
                  self.path = NavigationPath(representation)
              } catch {
                  self.path = NavigationPath()
              }
          } else {
              self.path = NavigationPath()
          }
      }
    
      func save() {
          guard let representation = path.codable else { return }
          do {
              let encoder = JSONEncoder()
              let data = try encoder.encode(representation)
              Self.writeSerializedData(data)
          } catch {
              // Handle error.
          }
      }
    }

    이렇게 정의된 MyModelObject 객체를 통해 Scene에 들어갈때 네비게이션 path의 상태를 저장할 수 있습니다.

    우선 아래 공식 문서의 코드 예시는 Scene이 백그라운드에 진입할때 path의 상태를 저장하도록 했습니다.

    @StateObject private var pathState = MyModelObject()
    @Environment(\.scenePhase) private var scenePhase
    
    var body: some View {
      NavigationStack(path: $pathState.path) {
          // Add a root view here.
      }
      .onChange(of: scenePhase) { phase in
          if phase == .background {
              pathState.save()
          }
      }
    }

    이렇게 onChange에서 Environment 변수인 scenePhase를 받고 해당 phase가 백그라운드일때 위에서 만들어준 MyModelObject 인스턴스인 pathState를 저장합니다.

    이 기능을 통해 아주 유용하게 경로를 저장하고 불러오고 다재다능 할것 같아요!

     

    마무리

    빨리 SwiftUI 4.0을 도입해보고 싶어요😭

    이렇게 미니멈 타겟 고려하고 고려하다 한 2~3년 뒤에 써볼거 같은 느낌이 강하게 들어서...

    그때되면 감을 잃을것 같은데!ㅋㅋㅋ

    그래도 그때되면 더 SwiftUI가 발전해있겠죠?🙏🏻

     

    [참고자료]

    https://developer.apple.com/documentation/swiftui/navigationpath

     

    Apple Developer Documentation

     

    developer.apple.com

    'SwiftUI' 카테고리의 다른 글

    SwiftUI - isDetailLink (With. NavigationLink)  (2) 2022.08.23
    SwiftUI에서 MVVM 사용을 멈춰야 하는가?  (6) 2022.07.28
    SwiftUI 4.0 - NavigationStack  (0) 2022.06.20
    SwiftUI 4.0 - Charts  (0) 2022.06.10
    SwiftUI - TabView  (0) 2022.04.09
Designed by Tistory.