Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

J

[Swift & SwiftUI] 버전 대응 Wrapper 본문

Swift & SwiftUI

[Swift & SwiftUI] 버전 대응 Wrapper

yujaehui 2024. 5. 19. 19:34

버전 대응 Wrapper

Swift 애플리케이션에서 iOS, macOS 등 특정 플랫폼 버전에 따라 코드를 실행하거나 기능을 활성화해야 하는 경우가 종종 존재.

이러한 요구를 처리하기 위해 버전 대응 Wrapper를 활용하여 코드의 가독성과 재사용성을 높일 수 있음.


1. 기본 버전 조건 처리

Swift는 @available 및 #available 키워드를 사용하여 플랫폼 및 버전 조건을 확인.

if #available(iOS 16, macOS 13, *) {
    print("iOS 16 이상에서 동작")
} else {
    print("이전 버전에서 동작")
}
  • #available: 실행 시점에서 조건 확인.
  • @available: 컴파일 시점에서 사용 가능성을 표시.

예제: 뷰에 버전 따라 다른 스타일 적용

struct ContentView: View {
    var body: some View {
        if #available(iOS 16, *) {
            Text("iOS 16 이상 스타일")
                .font(.largeTitle)
        } else {
            Text("이전 버전 스타일")
                .font(.title)
        }
    }
}

2. 버전 대응 Wrapper 구현

반복적으로 #available을 사용하는 대신, 재사용 가능한 버전 대응 Wrapper를 정의하여 코드 중복을 줄일 수 있음.

struct VersionCompatibility {
    static func ifAvailable<T>(
        execute: () -> T,
        fallback: () -> T
    ) -> T {
        if #available(iOS 16, *) {
            return execute()
        } else {
            return fallback()
        }
    }
}
let label = VersionCompatibility.ifAvailable {
    "iOS 16 기능 사용"
} fallback: {
    "이전 버전 대체 기능"
}

3. View 버전 대응 Wrapper

버전별로 다른 뷰를 반환할 수 있는 Wrapper를 정의.

struct VersionedView<Content: View, Fallback: View>: View {
    @ViewBuilder let content: Content
    @ViewBuilder let fallback: Fallback

    var body: some View {
        if #available(iOS 16, *) {
            content
        } else {
            fallback
        }
    }
}
struct ContentView: View {
    var body: some View {
        VersionedView(
            content: {
                Text("iOS 16 이상에서 보이는 뷰")
                    .font(.largeTitle)
            },
            fallback: {
                Text("이전 버전에서 보이는 뷰")
                    .font(.title)
            }
        )
    }
}

4. 고급 Wrapper: Modifier 기반 처리

UI의 특정 구성 요소에 조건부로 Modifier를 적용할 수도 있음.

struct ForgroundWrapper: ViewModifier {  
    let color: Color
    
    func body(content: Content) -> some View {
        if #available(iOS 15.0, *) {
            content
                .foregroundStyle(color)
        } else {
            content
                .foregroundColor(color)
        }
    }
}

extension View {
    func forground(_ color: Color) -> some View {
        modifier(ForgroundWrapper(color: color))
    }
}
struct ContentView: View {
    var body: some View {
        Text("버전별 Modifier 적용")
            .forground(.white)
    }
}

5. API Wrapper

네트워크 호출이나 기능 구현에서도 플랫폼별 API를 Wrapper로 처리할 수 있음.

struct APIManager {
    static func fetchData() {
        if #available(iOS 16, *) {
            print("iOS 16 API 사용")
            // Use modern API
        } else {
            print("이전 버전 API 사용")
            // Use legacy API
        }
    }
}

6. 버전 대응 Swift Package

Swift Package Manager(SPM)를 사용하여 특정 플랫폼 버전 이상에서만 라이브러리를 활성화할 수도 있음.

let package = Package(
    name: "VersionedLibrary",
    platforms: [
        .iOS("15.0"),
        .macOS("12.0")
    ],
    products: [
        .library(name: "VersionedLibrary", targets: ["VersionedLibrary"])
    ],
    dependencies: [],
    targets: [
        .target(name: "VersionedLibrary", dependencies: [])
    ]
)

7. 선택 가이드

사용 사례 적합한 처리 방법
UI 요소를 버전별로 다르게 표시해야 함 View Wrapper, Modifier Wrapper
API 호출 로직이 버전에 따라 다름 함수 기반 Wrapper 처리
프로젝트 전체에서 일관된 조건을 사용 Static Wrapper 함수
Swift Package에서 버전 조건 설정 Package.swift의 platforms

'Swift & SwiftUI' 카테고리의 다른 글

[Swift & SwiftUI] PropertyWrapper  (0) 2024.04.29
[Swift & SwiftUI] OpaqueType  (0) 2024.04.19