[TIL/Swift] enum으로 navigation 관리하기

pendant.kpendant.k
2 min read

Enum을 통해 네비게이션할 수 있는 Route를 정리하고, 각 Route로 이동할 수 있는 함수 작성

시나리오 : 마이페이지 내 List Cell들이 있고, 이를 클릭하면 해당 ListCell이 나타내는 페이지로 Navigation 실행해야함

  1. ForEach를 통해 enum.allCases를 돌려서 반복되는 View 코드를 줄이고 싶었음
List {
      Section {
          // 반복되는코드는개발자를불안하게해요반복되는코드는개발자를불안하게해요
          MyPageListCell(...)
          MyPageListCell(...)
          MyPageListCell(...)
      }
}
List {
      Section {
          ForEach(MyPageRouteSection1Config.allCases, id: \.rawValue){
              config in 
              MyPageListCell(...)
          }
      }
}

코드 정리를 위해서 MyPageRouteSection1Config 등의 enum 구현

Section으로 나누어진 List에 아이템을 촤라락(allCases쓴다는 뜻) 뿌리고 싶어서 다음과 같이 3가지의 enum을 별도로 구현함

만들고나니 각 Subview에 넘겨줄 함수를 만드는 과정에서 여러 개의 enum을 파라미터로 넘겨줘야했음. 이를 해결하기 위해 Protocol을 추가적으로 구현함

// 변수 이름 구린 거 같긴함 좀 더 직관적인 게 없을까.
// GPT탓임
protocol MyPageNavigatable {
    var routeName: String { get }
}

해당 프로토콜을 enum 프로토콜로 지정하여 사용함

다음과 같이 최종적으로 코드를 구현하였음

enum MyPageRouteSection1Config: String, CaseIterable, MyPageNavigatable {
    case spouse = "배우자"
    case myMedicine = "나의 약, 주사 정보"

    var routeName: String {
        return self.rawValue
    }

    func toRoute() -> Route {
        switch self {
        case .spouse:
            return Route.spouse
        case .myMedicine:
            return Route.myMedicine
        }
    }
}

해당 프로토콜과 enum들을 활용한 navigate() 함수는 다음과 같음

private func navigate(to myPageRoute: MyPageNavigatable) {
    self.appState.routes.append(myPageRoute.toRoute())
}

결론

  • 기존에 반복되던 코드를 줄일 수 있었음

  • 작업이 더 늘어난 것 같은데, 이건 기분탓이겠지

  • 하지만 확장성 + 오류 발생 가능성을 고려하면 이게 더 맞는 방법이라고 생각함 (휴먼 에러가 발생할 확률은 줄어들잖아. 한잔해)

반복되던 View 코드는 다음과 같이 정리되었읍니다

 // **MARK: Section 1**

Section {
    ForEach(MyPageRouteSection1Config.allCases, id: \.rawValue) { config in
        MyPageListCell(title: config.rawValue, action: {
            self.navigate(to: config)
        })
    }
} header: {
    Spacer(minLength: 0)
}
.listRowSeparator(.hidden, edges: .bottom)
.listRowSpacing(.zero)

+) nested enum을 활용하는 게 더 났지않을까 하는 전문가 친구의 의견을 받았다.(개천재?)

enum NestedExample {
    enum Section1 {
        case spouse
        case myMedicine
    }

    enum Section2 {
        case notice
        case faq
    }
}

조금이나마 뿌듯했던 마음이 싹 사라지게 됐읍니다.

Swift의 enum(이놈아님)은 활용도가 무궁무진하니 생각의 폭을 늘려보자.

0
Subscribe to my newsletter

Read articles from pendant.k directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

pendant.k
pendant.k

iOS / Flutter Developer