Swift5 달라진 특징

08 May 2019 — Written by Paul Han
#swift#swift5#chahnge language version#officially

What's new in Swift 5.0

Overview

  • Swift 5 런타임이 최신 Apple에서 제공하는 OS에 포함 되었습니다
  • Swift 5 런타임이 간소화된 App Store는 최신 OS를 실행하는 기기에서 빠른 다운로드를 제공합니다.
  • SIMD(Single Instruction Mutiple Data) 벡터 타입들은 표준라이브러리에 내장 되었습니다
  • 문자열 리터럴은 문법을 개선하여 읽고 쓰기가 더 쉬워졌습니다
  • 새로운 열거형 타입 을 사용하면 비동기 작업에서 오류를 보다 쉽게 처리 할수 있습니다.

아래에서는 하나씩 좀더 상세하게 정리해볼게요~

Stable ABI(Application Binary Interface) and Binary Compatibility

스위프트 라이브러리는 이제 최신 모든 Apple 플랫폼 OS 배포에 통합되기 때문에 앱을 보다 쉽게 빌드하고 작게 만들수 있습니다.

자세한 내용은 아래 블로그 게시물을 참고하세요

Standard Library Updates

Swift 5의 표준 라이브러리에는 다음과 같은 새로운 기능이 포함되어 있습니다.

  • 문자열이 UTF-8 인코딩으로 다시 구현되어 종종 더 빠른 코드가 될 수 있습니다
  • 문자열 리터럴의 원시 텍스트에 대한 향상된 지원
  • Result 및 SIMD vector 타입이 표준라이브러리에 추가되었습니다
  • 문자열 보간 강화, 데이터에서 텍스트를 구성하는 유연성이 향상되 었습니다
  • Dictonary, Set의 성능이 향상되었습니다.

아래에서는 Swift Evolution process에 대해 살펴 보겠습니다.

  • SE-0200 Raw strings
  • SE-0235 A standard Result type
  • SE-0228 Customizing string interpolation
  • SE-0216 Dynamically callable types
  • SE-0192 Handling future enum cases
  • SE-0230 Flattening nested optionals resulting from try?
  • SE-0225 Checking for integer multiples
  • SE-0218 Transforming and unwrapping dictionary values with compactMapValues()

Hacking Swift 5.0

원시 문자열

원시 문자열은 #기호를 문자열의 시작과 끝부붙에 사용하여 표현 할수 있습니다.

let rain = #"The "rain" in "Spain" falls mainly on the Spaniards."#
let keypaths = #"Swift keypaths such as \Person.name hold uninvoked references to properties."#

이제 따옴표, 역슬래시를 문자열 그대로라고 이해하게 할 수 있습니다. 이는 기존 문자열 보간법을 다르게 이해한다는 것입니다. 아래에서 #기호를 사용하여 원시 문자열을 나타날때 상수 answer를 어떻게 문자열내에 포함하는지 살펴볼 수 있습니다.

let answer = 42
let dontpanic = #"The answer to life, the universe, and everything is \#(answer)."#

원시 문자열 안에서 answer를 사용할때 원래의 문자열 보간법을 사용하기위해 #을 사용한것을 볼수 있습니다.

드문 경우지만 원시 문자열 안에서 #을 사용하기 위해서는 쌍따옴표 앞뒤로 #을 두번 감싸 사용해야 합니다.

let str = ##"My dog said "woof"#gooddog"##

또한 원시 문자열은 Swift의 다중 행 문자열 시스템과 완벽하게 호환 됩니다.

let multiline = #"""
The answer to life,
the universe,
and everything is \#(answer).
"""#

원시 문자열은 정규표현식에서 특히 유용한데요 백슬래시를 많이 사용하지 않고 작성 할수 있기 때문입니다.

let regex1 = "\\\\[A-Z]+[A-Za-z]+\\.[a-z]+"
let regex2 = #"\\[A-Z]+[A-Za-z]+\.[a-z]+"#

A standard Result type

Result 타입을 표준 라이브러리에 도입하여 비동기 API와 같은 복잡한 코드의 오류를 보다 간단하고 명확하게 처리 할 수 있게 되었습니다.

Swift의 Result 타입은 success, failure두가지 경우가 있는 enum 형식으로 구현됩니다. success, failure 둘다 Generic을 사용하여 구현되므로 사용자가 선택한 관련 값을 가질수 있지만 failure는 Swift의 Error 타입과 일치해야 합니다.

Result사용 예시를 보여주기 위해 서버에 연결하는 함수를 작성하여 사용자에게 읽지 않은 메시지의 수를 확인할 수 있습니다.

아래 예제 코드는 하나의 에러만 가지고 있는데 요청된 URL 문자열이 유효한 URL이 아니라는것 입니다.

enum NetworkError: Error {
    case badURL
}

fetching 함수는 URL 문자열을 첫 번째 매개 변수로 사용하고 completion 핸들러를 두 번째 매개변수로 사용 합니다. completion 핸들러는 Result를 받아드리고 여기서 성공 사례는 정수를 저장할 것이고 실패 사례는 일종의 NetworkError가 될 것 입니다. 여기에 실제로 서버에 연결하지 않지만 완성 처리기를 사용하면 적어도 비동기 코드를 시뮬레이션 할 수 있습니다.

import Foundation

func fetchUnreadCount1(from urlString: String, completionHandler: @escaping (Result<Int, NetworkError>) -> Void)  {
    guard let url = URL(string: urlString) else {
        completionHandler(.failure(.badURL))
        return
    }

    // complicated networking code here
    print("Fetching \(url.absoluteString)...")
    completionHandler(.success(5))
}

이 코드를 사용하려면 호출이 성공했는지 실패했는지 Result를 확인해야 합니다.

fetchUnreadCount1(from: "https://www.hackingwithswift.com") { result in
    switch result {
    case .success(let count):
        print("\(count) unread messages.")
    case .failure(let error):
        print(error.localizedDescription)
    }
}

Result를 자신의 코드에서 사용하기전에 알아야 할 세 가지가 더 있습니다.

먼저 Result에는 get() 메서드가 있습니다 이 메서드는 성공한 값이 있으면 반호나하거나 그러지 않으면 오류를 던집니다. 이렇게 하면 Result를 다음과 같이 일반 던지기 호출로 변환할 수 있습니다.

fetchUnreadCount1(from: "https://www.hackingwithswift.com") { result in
    if let count = try? result.get() {
        print("\(count) unread messages.")
    }
}

두번째 Result에는 throwing closure를 받아들이는 initializer가 있습니다. 클로저가 성공 사례에 사용 된 값을 성공적으로 반환하면 그렇지 않습니다. 그렇지 않으면 throw된 failure 케이스가 배치 됩니다.

let result = Result { try String(contentsOfFile: someFile) }

세번째 생성 한 특정 Error 열거형을 사용하는 대신 일반 Swift.Error를 사용할 수도 있습니다. 따라서 Result<Int, NetworkError> 대신 Result<Int, Error>를 사용할 수 있습니다. 이것은 타입이 지정된 throw의 안정성을 잃는다는 것을 의미하지만 다양한 오류 열거형을 던질 수 있습니다.

Transforming Result

Result에는 map(), flatMap(), mapError()flatMapError()의 네 가지 유용한 메소드가 있습니다. 이들 각각은 success 또는 error를 어떻게 든 변환 할 수있는 능력을 제공하며 처음 두 개는 선택 사항에서 같은 이름의 메소드와 유사하게 작동합니다.

... 작성중 ...

Reference