본문 바로가기
iOS

protocol 이럴때 사용해보세요

by 지금갑시다 2022. 12. 27.

Swift는 프로토콜 지향언어다 라는 이야기가 있듯이 Swift는 프로토콜의 활용이 굉장히 중요하다.

 

그럼 프로토콜은 언제 쓰는데요?!

 

를 위해서 정리해 본다.

 

 

먼저 가벼운 뷰를 만들고 상황을 보자!

struct DefaultColorTheme {
    let primary: Color = .blue
    let secondary: Color = .white
    let tertiary: Color = .gray
}

struct Protocols: View {
    let colorTheme: DefaultColorTheme = DefaultColorTheme()    
    var body: some View {
        
        ZStack {
            colorTheme.tertiary
                .ignoresSafeArea()
            Text("Protocol")
                .font(.headline)
                .foregroundColor(colorTheme.secondary)
                .padding()
                .background(colorTheme.primary)
                .cornerRadius(10)
        }
    }
}

 

DefaultColorTheme의 Preview

위와 같은 뷰를 SwiftUI로 작성한 코드이다.

 

DefaultColorTheme struct 가 primary, secondary, teriary를 가지며, 각각의 Color값으로 뷰가 그려지게 된다.

 

 그렇다면, DefaultColorTheme과 다른 예를 들어 색상 반전과 같은 기능을 추가한다면, 다양한 방법이 있겠지만, 아래의 방법을 보면 AlternativeColorTheme과 같은 프로퍼티들은 동일한 struct를 추가해 주게 되는 방법이 있다.

struct DefaultColorTheme {
    let primary: Color = .blue
    let secondary: Color = .white
    let tertiary: Color = .gray
}

struct AlternativeColorTheme {
    let primary: Color = .red
    let secondary: Color = .white
    let tertiary: Color = .green
}

struct Protocols: View {
    // let colorTheme: DefaultColorTheme = DefaultColorTheme()    
    let colorTheme: AlternativeColorTheme = AlternativeColorTheme()
    var body: some View {
        
        ZStack {
            colorTheme.tertiary
                .ignoresSafeArea()
            Text("Protocol")
                .font(.headline)
                .foregroundColor(colorTheme.secondary)
                .padding()
                .background(colorTheme.primary)
                .cornerRadius(10)
        }
    }
}

AlternativeColorTheme의 Preview

 

 그런데 만약, 지금 상황은 두 가지의 색상 struct만 존재해서 문제가 없지만, 훨씬 더 많은 색상의 구조체가 필요하다면 그때마다 colorTheme의 타입을 바꾸어 주어야 할까??

 이때에 프로토콜을 사용하게 되면 굉장히 유용하게 사용이 가능하다.

 현재는 colorTheme의 타입이 Default가 들어가게 되면 Default로, Alter가 들어가게 되면, Alter로 바꿔주게 되는데, 실은 두 개가 struct의 이름만 다르지, 그 안에 있는 프로퍼티는 primary, secondary, tertiary로 동일하다.

 

 이 점을 이용해서 프로토콜을 만들어 주고 사용하면 된다.

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
}

protocol ColorThemeProtocol {
    var primary: Color { get }
    var secondary: Color { get }
    var tertiary: Color { get }
}

 

ColorThemeProtocol이라는 프로토콜을 만들어 주었고, DefaultColorTheme, AlternativeColorTheme 이 이 프로토콜을 채택해서 따르도록 만들어 주었다.

 

ColorThemeProtocol

즉 프로토콜은

1. 프로퍼티의 변수타입으로 let을 갖지 못하며(var로 작성되어야 함)

2. get, set 등을 명시해 주어야 한다.

    2-1. get은 사용할때, 해당 값을 선택해 사용할 수 있고

    2-2. set이 있다면 그 값을 변경할 수 있음

    2-3. get set이 함께 있을 수 있음

 

위의 프로토콜이 생기면서, View역시 원하는 colorTheme struct를 사용하기 쉽게 바뀌게 된다.

struct Protocols: View {
    // 이렇게 프로토콜 타입으로 주면 두개를 사용 가능해짐
    let colorTheme: ColorThemeProtocol
    
    var body: some View {
        
        ZStack {
            colorTheme.tertiary
                .ignoresSafeArea()
            Text("Protocol")
                .font(.headline)
                .foregroundColor(colorTheme.secondary)
                .padding()
                .background(colorTheme.primary)
                .cornerRadius(10)
        }
    }
}

// 위의 View struct 사용을 위해서는
Protocols(colorTheme: DefaultColorTheme) 혹은 Protocols(colorTheme: AlternativeColorTheme)
로 불러 사용하면 된다.

 

colorTheme을 보게 되면, 기존의 struct가 바뀔 때마다 타입이 바뀌던 프로퍼티에서 ColorThemeProtocol을 타입으로 가져, DefaultColorTheme, AlternativeColorTheme 두 개를 다 쉽게 활용할 수 있다.

 

 

 또한 프로토콜은, struct, class, 다른 protocol 등의 선언부 옆에 써서, '해당 struct, class, protocol들은 이런 역할을 가져야 합니다'와 같이 일종의 설계표 역할을 해주고, 이는 혹시 구현이 되어야 하는 것이 안되어 있다면 오류를 내뿜어 더 안정적인 개발에 도움을 주기도 한다!

 

끗!!

 

 

 

REF: https://www.youtube.com/watch?v=0gM1wmW1Xvc