질문
1.
팀원들과 함께 팀프로젝트를 진행하기 전, 알맞게 추상화된 코드로 적재적소에 코드를 재활용하고 싶어서 제너릭과 프로토콜을 연습 중입니다.
2.
특히 코드 추상화는 코드를 구현하는 사람의 생각을 추상화하는 것이라 그런지.. 제 코드를 추상화하는 데도 쉽지 않았습니다.
3.
여러 시행착오를 겪고 있지만, 아래 레포지토리의 리드미에 적힌 내용대로 연습 중에 있습니다.
4.
제너릭과 프로토콜을 활용해서 어떻게 하면 코드를 더 팀원들이 이해하기 쉽고 재활용하기 좋게 추상화할 수 있을지 조언과 요령을 구하고 싶습니다.
a.
또한 제너릭으로 어디까지 될 지, 어디까지가 불가능한지를 사전에 할 수 있을까요..?
b.
SwiftUI 에서는 ForEach가 제너릭 타입이 해셔블하지 않으면 활용할 수가 없어서 구현을 다 해놓고 다시 갈아 엎어야 했던 문제가 있습니다 ㅠㅠ
5.
감사합니다!
화면캡쳐
struct NavigationModifier<NavigationLinkDestinationView: View>: ViewModifier {
let journeyToolbar: JourneyToolbar<NavigationLinkDestinationView>
let isRefreshableView: Bool
var tabSelection: Binding<Int>
func body(content: Content) -> some View {
content
.toolbar {
toolbarBuilder(toolbar: journeyToolbar)
}
}
@ToolbarContentBuilder
private func toolbarBuilder(toolbar: JourneyToolbar<NavigationLinkDestinationView>) -> some ToolbarContent {
switch isRefreshableView {
case false:
ToolbarItem(placement: toolbar.toolbarItemPlacement) {
NavigationLink(destination: {
if let destination = toolbar.destination {
destination
}
}, label: {
if let iconName = toolbar.toolbarIconName {
Image(systemName: iconName)
.foregroundColor(.accentColor)
}
})
}
case true:
ToolbarItem(placement: toolbar.toolbarItemPlacement) {
Button {
tabSelection.wrappedValue = toolbar.selectionTag
} label: {
if let iconName = toolbar.toolbarIconName {
Image(systemName: iconName)
} else {
Text("MyJourney")
.bold()
.foregroundColor(.black)
}
}
}
}
}
}
struct JourneyToolbar<ContentView: View>: Identifiable {
let id: String = UUID().uuidString
let toolbarItemPlacement: ToolbarItemPlacement
let toolbarIconName: String?
let destination: ContentView?
var selectionTag: Int
}
Swift
복사
프로젝트 주소
위 질문에 해당하는 질문의 링크나 스크린샷을 여기에 추가해 멘토분들이 참고할 수 있도록 하세요.
멘토링 진행 (2022-01-15 오후 8시 ~ 9시)
•
제네릭이 일반적으로 타입(어레이, 딕셔너리), 메서드에서 사용되는 경우에 대한 설명
•
스유에서 커스텀 타입을 만들 때, nested 열거형으로 타입을 지정해두고, 이니셜라이저에서 타입을 고르는 방법 설명
•
some View 를 내뱉는 연산 프로퍼티, 메서드라고 @ViewBuilder 가 꼭 필요한 게 아님. 습관적으로 붙이지 말자.
•
우리가 어떤 타입에, 어떤 클로저를 넣어주고 싶을 때 내부에서 @escaping 클로저로 받을 수 있듯이
•
어떤 타입에, 개발자가 커스터마이징 된 View 를 넣고 싶을 때, @ViewBuilder 를 사용할 수 있다.
•
HStack, VStack, Button 같은 애들이 애초에 뷰빌더로 만들어진 것임. 개발자가 자유롭게 디자인을 넣을 수 있다는 점을 리마인드해보면 좋다.
•
협업 하는 다른 동료들을 위해서, 편리한 수정자(modifier)를 만들어주려는 의도는 좋지만
•
튜닝의 끝은 순정이듯이, 편하게 하는 것과 vs 별도의 코드 복잡성이 생기는 것 사이의 trade-off 를 따져봐야 한다.
•
이 개념이 확장되면 → 디자인 시스템이 된다. 현업 가면 웬만하면 다 디자인 시스템이 있을 것.
•
면접 볼 때는, 내가 이렇게 대단한 modifier 를 만들었어요 보다는, 다른 개발자들과 동일한 디자인을 생산해내기 위해, 어떤 고민을 했었고 이런 식으로 디자인시스템을 구현했습니다. 라고 강조하는 방향이 더 어필이 될 듯 하다.
•
디자인시스템의 끝판왕은, 의도적인 컴파일 에러를 유발하는 것이다. 컴파일이 안 되게 디자인한다면, 실수할 확률이 극도로 줄어드니까.