프로토콜은 개발을 하면서 매우 중요한 개념입니다
프로토콜이란
프로토콜이란 프로그래밍에서 인터페이스 역할을 하는 중요한 요소입니다. 프로토콜은 특정 작업 또는 기능을 정의하는데 사용됩니다. 그리고 이미 SwiftUI에서는 View 프로토콜 같은 여러 프로토콜이 제공되고 있으며 View는 사용자 인터페이스의 모습과 동작을 정의하는 특징을 갖고 있고 다른 프로토콜들도 여러 기능을 수행할 수 있도록 미리 정의되어 있는 기능입니다.
프로토콜의 필요성
코드를 만들다보면 아래처럼 3개의 상수 모두 Color 타입인 구조체로 교차해서 사용할 수 있을 것 같은데 색상(내용)이 서로 같이 않기 때문에 당연히 사용하지 못하는 경우가 발생할 수 있습니다.
struct DefaultColorTheme {
let primary: Color = .blue
let secondary: Color = .white
let teriary: Color = .gray
}
struct AlternativeColorTheme {
let primary: Color = .red
let secondary: Color = .white
let teriary: Color = .green
}
위에 상황과 같은 문제들을 해결할 수 있는 프로토콜을 만들면서 프로토콜이 어떤 것인지 어떻게 사용하는 것인지 알아보겠습니다.
프로토콜 정의하기
프로토콜은 name과 requirements가 필수로 정의되어야 합니다. requirements는 View 프로토콜같은 경우는 body를 반드시 구현해야되듯이 프로토콜을 사용하기 위해서 반드시 요구되는 요구사항들을 미리 정의하도록 만들 수 있습니다.
requeirements의 또 다른 특징이 있다면 변수는 반드시 var로 선언되야하고 get 또는 get set 을 설정해야 합니다. get은 프로토콜로부터 데이터를 가져올 수 있다는 것만 의미하고 get set은 값을 수정 및 가져올 수 있다는 것을 의미합니다.
protocol ColorThemeProtocol {
var primary: Color { get }
var secondary: Color { get }
var tertiary: Color { get }
}
이렇게 구현하게 되면 아래 코드처럼 두개의 서로 다른 struct이라도 같은 프로토콜을 준수하기 때문에 ColorThemeProtocol를 준수한다고 정하면 다음과 같이 사용할 수 있게 됩니다.
// let colorTheme: DefaultColorTheme = DefaultColorTheme()
// let colorTheme: AlternativeColorTheme = AlternativeColorTheme()
let colorTheme: ColorThemeProtocol = DefaultColorTheme()
let colorTheme: ColorThemeProtocol = AlternativeColorTheme()
부가적으로 이렇게 되면 Preview에서도 두개의 ColorTheme 구조체를 간편하게 바꾸며 확인할 수 있게 됩니다.
ContentView(colorTheme: DefaultColorTheme())
ContentView(colorTheme: AlternativeColorTheme())
프로토콜은 서로 상속 가능
프로토콜은 서로 상속되기 때문에 프로토콜을 하나로 합친 프로토콜을 만들어 사용할 수도 있습니다.
protocol ColorThemeProtocol {
var primary: Color { get }
var secondary: Color { get }
var tertiary: Color { get }
}
protocol ColorThemeProtocol2 {
var primary: Color { get }
var secondary: Color { get }
var tertiary: Color { get }
}
protocol ManyColorThemeProtocol: ColorThemeProtocol, ColorThemeProtocol2 {
}
전체 코드
import SwiftUI
struct DefaultColorTheme: ColorThemeProtocol {
let primary: Color = .blue
let secondary: Color = .white
let tertiary: Color = .gray
}
struct AlternativeColorTheme: ColorThemeProtocol {
let primary: Color = .red
let secondary: Color = .white
let tertiary: Color = .green
}
struct AnotherColorTheme: ColorThemeProtocol {
var primary: Color = .blue
var secondary: Color = .red
var tertiary: Color = .purple
}
protocol ManyColorThemeProtocol: ColorThemeProtocol, ColorThemeProtocol2 {
}
protocol ColorThemeProtocol {
var primary: Color { get }
var secondary: Color { get }
var tertiary: Color { get }
}
protocol ColorThemeProtocol2 {
var primary: Color { get }
var secondary: Color { get }
var tertiary: Color { get }
}
protocol ButtonTextProtocol {
var buttonText: String { get }
}
protocol ButtonPressedProtocol {
func buttonPressed()
}
protocol ButtonDataSourceProtocol: ButtonPressedProtocol, ButtonTextProtocol {
}
class DefaultDataSource: ButtonDataSourceProtocol {
var buttonText: String = "Protocols"
func buttonPressed() {
print("버튼 눌렸다")
}
}
class AlternativeDataSource: ButtonTextProtocol {
var buttonText: String = "대체 데이터 소스"
}
struct ContentView: View {
let colorTheme: ColorThemeProtocol = DefaultColorTheme()
let dataSource: ButtonDataSourceProtocol = DefaultDataSource()
var body: some View {
ZStack {
colorTheme.tertiary
.ignoresSafeArea()
Text("Protocol Example")
.font(.headline)
.foregroundStyle(colorTheme.secondary)
.padding()
.background(colorTheme.primary)
.onTapGesture {
dataSource.buttonPressed()
}
}
}
}
'SwiftUI' 카테고리의 다른 글
Cocoapods (0) | 2024.05.01 |
---|---|
KaKao Map 카카오맵 (0) | 2024.04.30 |
UIViewControllerRepresentable (0) | 2024.04.27 |
PreferenceKey (0) | 2024.04.25 |
UIViewRepresentable SwiftUI에서 UIKit 사용하기 (0) | 2024.04.24 |