Swift

available 심층 탐구하기

GREEN.1229 2023. 7. 17. 09:28

안녕하세요. 그린입니다 🍏

이번 포스팅에서는 available에 대해 조금 더 알아보는 학습을 해보려해요 🙌

 

바로 이전에 특정 버전에 대해 분기 처리하는 방법들을 살펴보면서 available을 잠깐 설명하고 간적이 있습니다.

https://green1229.tistory.com/388

 

특정 버전에 대한 분기 처리하기 (systemVersion)

안녕하세요. 그린입니다 🍏 이번 포스팅에서는 특정 버전에 대한 분기처리하는 방법에 대해 알아보겠습니다 🙋🏻 일단 간단한 포스팅이 될 수도 있을것 같네요ㅎㅎ 분기 처리? 개발을 하다보

green1229.tistory.com

 

해당 available을 조금 더 심층 탐구해보는 시간입니다!

available?

특정 플랫폼 또는 OS 버전에서 코드를 실행하도록 해줍니다.

실행하려면 특정 플랫폼이나 최소 OS 버전이 필요한 코드 부분에 조건부 컴파일 마커를 추가합니다.

간단히 컴파일러 제어문으로 조건부 코드를 실행시켜주는 역할입니다.

Swift와 Objective-C에서의 사용이 아래와 같이 다릅니다.

// Swift
if #available(iOS 15, *) {
    // Run code in iOS 15 or later.
} else {
    // Fall back to earlier iOS APIs.
}

// Objective-C
if (@available(iOS 15, *)) {
    // Run code in iOS 15 or later.
} else {
    // Fall back to earlier iOS APIs.
}

Swift는 #available로 Objective-C는 @available로 사용됩니다.

 

또한, 여러 플랫폼에서 코드를 실행하고자 제어한다면 쉼표로 여러 플랫폼 이름을 포함하여 구분할 수 있습니다.

// Swift
if #available(iOS 15, macOS 12, *) {
   // Run code in iOS 15 or later and macOS 12 or later.
} else {
   // Fall back to earlier iOS and macOS APIs.
}

// Objective-C
if (@available(iOS 15, macOS 12, *)) {
    // Run code in iOS 15 or later and macOS 12 or later.
} else {
    // Fall back to earlier iOS and macOS APIs.
}

available의 필요성

앱의 신기능을 개발할 때 최대한 많은 가치를 얻으려 합니다.

새로운 플랫폼이나 OS를 지원하기 위해서 또 다른 새 프로젝트를 만들면 불필요한 작업이 추가될 수 있죠.

그렇기에 최상의 여러 플랫폼 및 OS 버전에서 실행되는 앱의 한 버전을 제공하는것이 목표입니다.

이를 위해 available로 컴파일러 제어문을 추가하여 동작시켜줄 수 있죠!


available의 attribute들

위에서 available에서 지원 가능한 플랫폼 즉, attribute를 각각 나열해줄 수 있었는데요.

그럼 어떤 속성들을 사용할 수 있는지 확인해보죠!

  • iOS
  • iOSApplicationExtension
  • macOS
  • macOSApplicationExtension
  • macCatalyst
  • macCatalystApplicationExtension
  • watchOS
  • watchOSApplicationExtension
  • tvOS
  • tvOSApplicationExtension
  • swift

모든 애플 생태계의 모든 플랫폼을 속성으로 둘 수 있습니다.

속성은 항상 둘 이상의 쉼표로 구분하여 나타내줍니다.

항상 사용되는 *는 나열된 모든 플랫폼에서 선언의 가용성을 나타낼 수 있어요.

다만 Swift 버전 번호를 사용해 가용성을 지정하는 속성에는 *를 사용할 수 없습니다.

 

또 외에도 다양한 지정된 인자들을 받을 수 있는데요.
한번 살펴보시죠!

 

unavailable

지정된 플랫폼에서 사용할 수 없음을 나타냅니다.

Swift 버전 가용성을 지정할때는 사용할 수 없습니다.

@available(*, unavailable)
func green() { }

이렇게 선언하면 애플 모든 플랫폼과 버전에서 해당 green 메서드를 사용할 수 없습니다.

만약 * 대신 특정 플랫폼만 지정하면 해당 플랫폼에서만 사용할 수 없는 메서드가 되는것이죠!

 

introduced

선언이 도입된 지정된 플랫폼 혹은 언어의 첫번째 버전을 나타냅니다.

버전 번호는 마침표로 구분된 1~3개의 양의 정수로 구성되요.

introduced: <#version number#>
@available(*, introduced: 17.0)
func green() { }

이렇게 선언해준다면 green 메서드는 17 버전에서 도입되었으니 17 이상 버전에서만 사용할 수 있고 미만 버전에서 사용 시 컴파일 에러가 나오게 됩니다.

 

deprecated

선언이 사용되지 않는 지정된 플랫폼 혹은 언어의 첫번째 버전을 나타냅니다.

introduced와 마찬가지로 마침표로 구분된 1~3개의 양의 정수로 구성되요.

버전 번호를 생략하면 선언이 현재 사용 중단되었음을 나타내며 언제 사용 중단이 발생했는지에 대해서는 정보를 제공하지 않습니다.

만약 버전 번호를 생략해야한다면 콜론도 생략해야 합니다.

deprecated: <#version number#>
@available(*, deprecated: 17.0)
func green() { }

해당 선언을 이용해 17 버전에서 deprecated 되었다는 경고 메시지를 노출 시켜주도록 할 수 있습니다.

 

obsoleted

선언이 폐기된 지정된 플랫폼 혹은 언어의 첫번째 버전을 나타냅니다.

선언이 폐기되면 지정된 플랫폼이나 언어에서 제거되기에 더 이상 사용할 수 없습니다.

버전 번호는 마침표로 구분된 1~3개의 양의 정수로 사용되요.

obsoleted: <#version number#>
@available(swift, obsoleted: 5.9)
func green() { }

deprecated는 경고로 끝나지만 obsoleted는 컴파일 에러를 나타냅니다.

즉, swift 5.9 버전 이하면 오류를 내뿜죠!

여기서 미만이 아니라 이하기에 5.9도 에러가 납니다~

 

message

더 이상 사용되지 않거나 폐기된 선언을 사용 시 경고 혹은 오류를 내보낼 때 컴파일러가 표시하는 텍스트 메시지를 제공해줍니다.

메시지는 문자열로 구성되요.

message: <#message#>
@available(*, unavailable, message: "nope")
func green() { }

이렇게 메시지를 unavailable과 같이 선언해주면 green 메서드를 사용하려고 할때 컴파일 오류 메시지로 nope이 나오게 됩니다.

 

renamed

이름이 변경된 선언의 새 이름을 나타내는 텍스트 메시지를 제공합니다.

컴파일러는 이름이 바뀐 선언을 사용 시 오류를 내보낼 때 새 이름을 표시하여 보내줍니다.

문자열로 구성되죠.

renamed: <#new name#>
// First release
protocol MyProtocol {
    // protocol definition
}

// Subsequent release renames MyProtocol
protocol MyRenamedProtocol {
    // protocol definition
}

@available(*, unavailable, renamed: "MyRenamedProtocol")
typealias MyProtocol = MyRenamedProtocol

이렇게 선언이 이뤄져있으며 사용할 수 있습니다.


그럼 이어서 이전 포스팅에서 잠깐 설명했던적이 있는 available에서 두가지 쓰임 방식에 대해 짚고 넘어갈께요!

#available과 @available 리마인드

#available은 조건문과 같이 사용할 때 사용됩니다.

if #available(iOS 17, *) {
  // 17 이상 버전 코드
}
else {
  // 17 미만 버전 코드
}

즉, Bool 타입을 반환시켜주니 꼭 조건문과 같이 사용됩니다.

 

@available은 조건문과 같이 분기 처리를 할 수 없고, 배포 타겟 버전을 체크합니다.

즉 아래와 같이 보통 클래스, 프로토콜, 메서드 같은 곳에 붙여 사용합니다.

@available(iOS 17, *)
func example() { }

만약 배포 타겟이 17 미만이라면 컴파일 시 에러가 나게 되죠!


마무리

이렇게 어떤 속성들을 사용할 수 있는지 위주로 available을 학습해봤어요!

간단한 쓰임에도 많은 케이스가 들어가 있어서 꽤 유용할 수 있을것 같아요 🙌


참고 자료

https://developer.apple.com/documentation/xcode/running-code-on-a-specific-version

 

Running code on a specific platform or OS version | Apple Developer Documentation

Add conditional compilation markers around code that requires a particular family of devices or minimum operating system version to run.

developer.apple.com

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/attributes/#Declaration-Attributes

 

Documentation

 

docs.swift.org