Skill Sets/Swift

[Swift]] Swift 5.6 release Unavailable Condition

코코자장자장 2022. 3. 30. 14:24

안녕하세요! Swift 5.6이 새로 release되어 관련된 내용을 포스팅 해볼까 합니다!

 

 

아래의 깃허브를 참고하여 만들었습니다.

 

GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Lang

This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhance...

github.com

 

Swift5.6 이전에는 버전의 사용가능 여부를 확인하기 위해 #available 조건을 지원했지만 반대의 경우는 지원하지 않았습니다.
Swift5.6 이후 무언가의 비가용성에 대한 확인이 필요한 경우, 새로운 #unavailable 조건이 사용가능합니다.

 

 

예시 상항을 하나 만들어 보겠습니다.

 

iOS 13에서 UIWindow가 SceneDelegate의 도입으로 App Delegate에서 SceneDelegate로 생성 위치가 바뀌었습니다.(이유는 multi window 지원때문이라고합니다.)

 

iOS 12를 포함한 이전의 AppDelegate 앱은 앱 실행이 완료될 때 Window를 설정하지만 SceneDelegate를 지원하는 앱은 대신 Life Cycle의 후반부, 특히 AppDelegate가 앱의 기본 UIScene에 연결할 때 설정해야 합니다.

 

이것은 일반적인 didFinishLaunching 흐름 외부에서 발생하기 때문에 이러한 극단적인 동작 차이는 간단한 if-else 가용성 확인으로 전달할 수 없습니다.

 

따라서, AppDelegate는 사용자가 iOS 13을 실행하지 않는 경우에만 창을 설정하도록 하는 negative한 플랫폼 검사가 필요합니다.


Swift 5.6 이전 버전에서는  아래와 같은 코드로 프로그래밍을 했습니다.

// if NOT in iOS 13, load the window.
// Post iOS 13 the window is loaded later in the lifecycle, in the SceneDelegate.
if #available(iOS 13, *) {

} else {
  loadMainWindow()
}


가독성을 위해 아래와 같이 구성할 수도 있었습니다.

// if NOT in iOS 13, load the window.
// Post iOS 13 the window is loaded later in the lifecycle, in the SceneDelegate.
if #available(iOS 13, *) {} else {
  loadMainWindow()
}


하지만 이 코드는 실수를 유발할 가능성이 높아서 추천되지 않습니다.
그래서 gaurd로 코드를 구성하면,

guard #available(iOS 13, *) else {
  loadMainWindow()
  return
}
// no-op


이렇게 가능하지만, guard 사용과 관련된 코딩 스타일 권장사항에 위배된다고 합니다.
guard에서는 비가용성을 검사하는것이 아닌 happy path???를 통해 구문으로 들어가야하는 것이 추천된다고 합니다.

그래서 만들어진 것이 #unavailable입니다.

이제 Swift5.6 이 후에는 

if #unavailable(iOS 13, *) {
  loadMainWindow()
}
if #unavailable(iOS 13, *) {
  // Symbol Availability: Default (deployment target)
} else {
  // Symbol Availability: iOS 13
}



이렇게 사용하실 수 있습니다.


또한 iOS 버전의 사에에서 동작 가능하도록

if #available(iOS 9.0, *), #unavailable(iOS 13.0, *) {
  // Symbol Availability: iOS 9.0
} else {
  // Symbol Availability: ???
}


이런 방법으로 사용도 가능합니다.

 

​​

오늘은 여기까지입니다.

즐거운 하루 되세요!