How to use Generics in Swift | Advanced Learning #8
Generics
구현 목표
- 제네릭은 구체적 타입을 추상적 타입으로 받도록 할 수 있는 방법
- 제네릭 구현을 통해 함수, 타입의 확장성이 매우 증가(타입마다 구조체를 선언할 필요없이 하나의 보편, 추상화된 구조체 선언 충분)
- 뷰 또한 제네릭 타입을 통해 다른 뷰의 이니셜라이저에 필요한 값으로 넘길 수 있음
구현 태스크
- 제네릭 타입의 구조체 구현
- 제네릭 타입을 통해 특정 뷰를 다른 뷰의 파라미터로 넘기기 ( 서브 뷰 활용)
핵심 코드
struct GenericModel<T> {
let info: T?
func removeInfo() -> GenericModel {
GenericModel(info: nil)
}
}
struct GenericView<T:View>: View {
let content: T
let title: String
var body: some View {
VStack {
Text(title)
content
}
}
}
- 스위프트의 제네릭은
CustomType
등 별도의 용어로 사용해도 상관없지만, <T>
가 일반적으로 사용됨
- 스우프트의 타입 추론을 통해 구조체 이니셜라이저에서 사용되는 데이터 타입을 구조체 선언 시 넘겨줄 수 있다면
GenericModel<String>
이 아니라 GenericModel
을 통해 선언 가능.
View
또한 View
프로토콜을 준수하는 구조체라는 점에서 <T:View>
를 통해 T
가 뷰임을 제네릭으로 전달 가능, 서브 뷰로 활용한 뷰를 파라미터처럼 넘길 수 있음
소스 코드
import SwiftUI
struct StringModel {
let info: String?
func removeInfo() -> StringModel {
StringModel(info: nil)
}
}
struct BoolModel {
let info: Bool?
func removeInfo() -> BoolModel {
BoolModel(info: nil)
}
}
struct GenericModel<T> {
let info: T?
func removeInfo() -> GenericModel {
GenericModel(info: nil)
}
}
class GenericsViewModel: ObservableObject {
@Published var stringModel = StringModel(info: "HELLO WORLD!")
@Published var boolModel = BoolModel(info: true)
@Published var genericStringModel = GenericModel(info: "Hello World!")
@Published var genericBoolModel = GenericModel(info: true)
func removeData() {
stringModel = stringModel.removeInfo()
boolModel = boolModel.removeInfo()
genericStringModel = genericStringModel.removeInfo()
genericBoolModel = genericBoolModel.removeInfo()
}
}
struct GenericView<T:View>: View {
let content: T
let title: String
var body: some View {
VStack {
Text(title)
content
}
}
}
struct GenericsBootCamp: View {
@StateObject private var viewModel = GenericsViewModel()
var body: some View {
VStack {
GenericView(content: MatchedGeometryEffect(), title: "NEW VIEW!")
Text(viewModel.stringModel.info ?? "NO DATA")
.onTapGesture {
viewModel.removeData()
}
Text(viewModel.boolModel.info?.description ?? "NO DATA")
.onTapGesture {
viewModel.removeData()
}
Text(viewModel.genericStringModel.info ?? "NO DATA")
.onTapGesture {
viewModel.removeData()
}
Text(viewModel.genericBoolModel.info?.description ?? "NO DATA")
.onTapGesture {
viewModel.removeData()
}
}
}
}
구현 화면