WWDC22(Platforms State of the Union)에서 Swift의 변경점을 정리해봅니다.
개별 세션의 내용을 참조한 내용들도 있으며, 글은 계속 수정될 수 있습니다.
Async Algorithm Package
await 키워드: 두 비동기 시퀸스를 zip으로 묶는 작업이 가능하게 해줍니다.
try-catch: 네트워크 스트리밍되는 비동기 데이터로 인한 네트워크 장애를 처리할 수 있게 해줍니다.
throttle 키워드: 새로 추가된 키워드. 시퀸스로부터의 업데이트를 늦춰주는 시간 기반 알고리즘을 제공.
(기존) actor : 스레드로부터 안전한 동시성 실행 코드를 사용해 데이터를 격리하게 해줍니다. Swift는 의도치않게 병렬 스레드 간에 그런 상태를 공유하는 것을 막아줍니다.
async/await: actor간 통신을 하게 해줍니다.
distributed actor: distributed actor는 복수의 프로세스나 장치에서 통신을 할 수 있게 해줍니다. distrubuted 키워드를 쓰면 원격으로 접근할 수 있는 actor, 메서드가 됨. 맥에서의 분리된 프로세스 사이, 다른 기기와의 P2P접속에서, Swift로 작성된 백앤드서버에서도 접근이 가능하게 합니다.
Swift Regex (정규표현식)
Swift 전용 정규표현식이 나왔습니다.
정규표현식 리터럴: / (정규식 String) /
Playground에서 정규표현식을 사용하면 어느 문자열이 일치하는지 바로 확인이 가능하게 해줍니다.
Regex Builders: 복잡한 정규표현식 패턴을 쉽게 만들수 있는 방법을 제공해줍니다.
기존에 작성된 정규표현식의 리터럴에서 우클릭>Refactor>Convert to Regex Builder 를 통해 쉽게 변환할 수 있는 방법을 제공해줍니다.
any 키워드
any 키워드와 함께 associatedtype을 쓰는 프로토콜을 사용하여 제한된 existential 타입을 사용할 수 있습니다.
struct MusicLibrary {
var playlists: [any Collection<Song>]
}
Generic 개선
아래는 기존의 Generic을 이용한 코드.
// (기존) where절을 통한 타입파라메터(PlayList)의 조건을 제한
func playSongs<PlayList>(in playList: PlayList) where PlayList: Collection, PlayList.Element == Song {
// ...
}
아래는 some 키워드로 개선된 Generic 코드. some 뒤에 매개변수를 설명하면 됩니다. 위 코드와 같은 의미입니다.
// Swift 5.7: 타입 파라메터 자리에 some키워드와 함께 조건이 될 프로토콜과 타입을 작성
func playSongs(in playList: some Collection<Song>) {
// ...
}
위의 any 키워드와 some 키워드로 개선된 Generic 코드와 매끄럽게 이어서 사용할 수 있게 해줍니다.
func playSongs(in playList: some Collection<Song>) {
// ...
}
struct MusicLibrary {
var playlists: [any Collection<Song>]
func playAll() {
for playlist in playlists {
playSongs(in: playlist)
}
}
}
그 외 변경점들
- parameter화된 existential타입과의 동적캐스팅(is, as!, as?)는 캐스트가 유효하더라도 항상 실패하도록 변경되었습니다. 해결하기 위해서는 동적캐스팅을 하기 전에 non-parameter화된 existential타입으로 업캐스팅을 해야합니다.
let source: any Collection<String> = ["Hello", "World")
// Using as? directly fails.
let failure = source as? Array<String>
// As a workaround, upcast to source to a nonparameterized Collection first.
let success = (source as any Collection) as? Array<String>
- 옵셔널을 언래핑해서 쓰기 위한 옵셔널 바인딩 구문이 개선되었습니다!
let foo: String? = "Hello world"
// 기존의 옵셔널 바인딩 구문
if let foo = foo {
print(foo)
}
// Swift 5.7 옵셔널 바인딩 구문
if let foo {
print(foo)
}
- @available(*, noasync) 속성을 사용하여, 비동기 컨텍스트에서 사용할 수 없도록 선언할 수 있습니다.
- Swift 5.7부터 지원하는 Regex의 리터럴 표현에서 Bare Slash구문이 가능하게 되었습니다. 그 영향으로 /를 연산자로 사용하는 기존 코드가 컴파일되지 않을 수도 있습니다.
이 경우 2가지 해결 방법이 있는데
괄호(/)를 추가하여 명시적으로 변경하거나,
프로젝트의 빌드설정에서 'Enable Bare Slash Regex Literals' 항목을 NO로 세팅해서 (SWIFT_ENABLE_BARE_SLASH_REGEX = NO) 해당 리터럴 구문에 대한 지원을 비활성화 시킬 수 있습니다.