Search
Duplicate

[Swift] Control Flow - Checking API Availability

The Swift Programming Language Documents를 참고해서 정리했습니다. 여러 가지 생각들이 버무려져 있습니다.
contents
*이전 포스팅은 [Swift] Control Flow - Control Transfer Statement 에서 보실 수 있습니다.

Control Flow

Swift는 다양한 Control Flow를 제공합니다.
for-in, while과 같은 반복문, 특정 조건에 따른 분기문, guard, switch, 그리고 실행 흐름 중간에 다른 지점으로 보내주는 break, continue 등을 제공해줍니다.
제공해주는 Control Flow를 사용해서 코드의 흐름을 원하는대로 제어할 수 있습니다.

API Availability

Swift에는 API Availability를 확인할 수 있는 기능이 내장되어 있습니다.
해당 기능은 특정 배포 타겟에서 사용할 수 없는 API를 실수로 사용하지 않도록 보장해주는 역할을 합니다.
만약, 해당 타겟에서 사용할 수 없는 API라면 컴파일 에러를 발생시켜 사용할 수 없는 API라는 것을 알려줍니다.
그럼, 어떻게 해당 기능을 사용할 수 있을까요?
방법은 간단합니다. #available 키워드를 사용해서 원하는 타겟에서 API를 사용할 수 있도록 할 수 있습니다.
if #available(iOS 10, macOS 10.12, *) { // iOS 10 API, macOS 10.12 API 사용 가능 } else { // 해당 타겟에 맞지 않는 API 사용 가능 }
Swift
복사
#available 키워드는 if문뿐만 아니라 guard문에서도 이용할 수 있습니다.
guard문은 guard 뒤에 나오는 부분이 참이라면 조건에 따라서 코드 블록을 실행하게 됩니다. 따라서, #available에 작성된 타겟에 부합한다면 다음 코드를 이어서 실행하고 아니라면 else문으로 들어가게 됩니다.
guard문 예시를 들기 위해서 Preference라는 구조체를 하나 만들었습니다.
@available(iOS 13.0, *) struct Preference { var backgroundColor = UIColor.systemBackground }
Swift
복사
해당 구조체는 iOS 13.0부터 사용할 수 있습니다. 만약, 그보다 낮은 버전이라면 Preference를 사용할 수 없습니다.
그러면, 해당 구조체 타입을 사용하는 chooseBackgroundColor 메소드를 만들어볼게요.
func chooseBackgroundColor() -> UIColor { guard #available(iOS 13.0, *) else { return UIColor.black } let preference = Preference() return preference.backgroundColor }
Swift
복사
메소드 첫 부분에 guard문을 사용해서 iOS 13.0에 부합하는지 확인합니다.
만약, 그보다 낮은 버전이라면 else문을 통해서 UIColor.black을 반환받습니다. 아니라면 그 다음 코드를 실행시킬 수 있어요.
Preference 구조체는 iOS 13.0부터 사용이 가능하기 때문에 if문을 통해서 한 번 더 감싸줘야하지만 guard문으로 이미 iOS 13.0 이후 버전인지 확인하기 때문에 따로 if문을 써줄 필요가 없게 됩니다.
만약, 위의 메서드가 이렇게 짜여져 있었다고 생각해보겠습니다.
func chooseBackgroundColor() -> UIColor? { guard #available(iOS 13.0, *) else { return UIColor.black } return nil }
Swift
복사
즉, else문이 필요해서 짜여진 코드라고 생각해볼게요. 이런 경우에는 #available을 쓰는 것이 맞지 않아보입니다.
좀 더 읽기 좋게 만드는 법은 없을까요?
Swift에서는 #available말고도 #unavailable이라는 키워드를 제공해줍니다.
해당 키워드를 사용하면 else문에 들어가야 하는 내용만 적을 수 있게 됩니다. 가독성이 이전보다 좋아지는거죠.
func chooseBackgroundColor() -> UIColor? { if #unavailable(iOS 13.0) { return UIColor.black } return nil }
Swift
복사
근데, 마지막 부분에 들어가는 *은 무슨 의미인가요?
#available 끝에 매번 들어가는 *은 필수로 들어가야 하는 부분입니다.
*의 의미는 앞에 지정한 플랫폼 외의 다른 플랫폼에서 실행하게 되었을 때, 프로젝트에서 지정한 최소 배포 타겟에서 해당 플랫폼 API를 실행할 수 있다는 걸 의미합니다.

️ 참고 자료