반응형

Swift에서 API의 지원 버전을 명시하거나 런타임에 확인할 때 사용하는 두 가지 문법, @available  #available 의 차이를 명확하게 정리했습니다.

 

 

1. 핵심 비교

구분 @available #available
역할 선언(Declaration) 수준에서 “언제부터 지원되는지” 표시 런타임(Runtime) 시점에서 “현재 OS가 지원하는지” 검사
적용 위치 클래스, 함수, 프로퍼티, struct, enum, extension 등 if / guard 문 등 제어문 내부
평가 시점 컴파일 시 런타임 시
문법 형태 Attribute (속성) Condition (조건문)
주 목적 API의 최소 지원 버전 명시 버전에 따라 코드 분기 실행
예시 키워드 @available(iOS 15, *) if #available(iOS 15, *) { ... }
빌드 시 동작 선언된 버전 미만에서는 컴파일 에러 항상 컴파일되지만 실행 시 분기

 

2. @available — 선언 레벨에서 사용

특정 API, 타입, 메서드 등이 언제부터 사용 가능한지를 명시합니다.

@available(iOS 15.0, *)
func useModernAPI() {
    // iOS 15 이상에서만 호출 가능
}

예시: 여러 플랫폼 지정

@available(iOS 14.0, macOS 11.0, *)
struct MyFeature { }

예시: Deprecated 표시

@available(iOS, deprecated: 16.0, message: "Use newAPI() instead.")
func oldAPI() { }

예시: Unavailable 표시

@available(iOS, unavailable)
func removedFeature() { }  // iOS에서는 호출 불가

 

3. #available — 런타임 분기 처리

실행 중인 디바이스의 OS 버전을 확인해 조건문으로 분기합니다.

if #available(iOS 15.0, *) {
    // iOS 15 이상일 때 실행
} else {
    // 하위 버전 대체 코드
}
  • #available은 런타임 검사용
  • if 문 내부에서는 해당 버전 이상의 API를 안전하게 사용할 수 있습니다.

 

4. 함께 사용하는 예시

@available(iOS 15.0, *)
struct ModernFeatureView: View {
    var body: some View {
        Text("iOS 15 전용 기능")
    }
}

struct ContentView: View {
    var body: some View {
        if #available(iOS 15.0, *) {
            ModernFeatureView()
        } else {
            Text("iOS 15 이상에서만 지원됩니다.")
        }
    }
}

설명:
- @available : ModernFeatureView가 iOS 15 이상에서만 유효함을 명시
- #available : 런타임에 실제 OS 버전을 확인 후 분기 실행


 

5. @available 옵션 요약

옵션설명예시

iOS, macOS, watchOS, tvOS 플랫폼 지정 @available(iOS 14, macOS 11, *)
introduced: 추가된 버전 @available(iOS, introduced: 14)
deprecated: 더 이상 권장되지 않음 @available(iOS, deprecated: 16, message: "Use newAPI()")
obsoleted: 완전히 제거됨 @available(iOS, obsoleted: 17)
message: 경고 메시지 표시 @available(iOS, deprecated: 15, message: "Use newAPI()")
unavailable 특정 플랫폼에서 사용 불가 @available(iOS, unavailable)
* 기타 플랫폼 전체 @available(iOS 15, *)

 

6. #available 문법 요약

if #available(iOS 15, macOS 12, *) {
    // 최신 API
} else {
    // 대체 코드
}
  • 쉼표로 여러 플랫폼 지정 가능
  • *는 “기타 플랫폼은 무시” 의미
  • 반드시 괄호로 감싸고 else 블록으로 이전 버전 대응

 

7. 내부 동작 차이

구분 @available #available
체크 시점 컴파일러가 선언 시점에서 확인 런타임에 ProcessInfo 기반 체크
컴파일러 동작 “이 함수는 iOS 15 이상에서만 호출 가능”으로 제한 실제 실행 시 버전 비교 코드 삽입

 

8. 빌드 예시

코드 iOS 14 빌드 iOS 15 빌드
@available(iOS 15, *) func a() {} 컴파일 에러 정상 빌드
if #available(iOS 15, *) { a() } 정상 (런타임 조건) 정상

 

9. 요약

구분 설명
@available “이 코드는 iOS XX 이상에서만 존재한다.”
#available “현재 실행 중인 OS가 iOS XX이상일 때만 실행한다.”

 함께 사용하면 컴파일 타임과 런타임 모두 안전하게 버전별 API를 다룰 수 있습니다.


 

10. 결론

  • @available : 선언 시점의 제약 (컴파일러 검사)
  • #available : 실행 시점의 분기 (런타임 검사)
  • 실무에서는 항상 둘을 조합하여 “안전한 버전 호환 코드”를 작성하는 것이 권장됩니다.

 

반응형
Posted by 까칠코더
,