스위프트에서 빈 옵셔널 String 다루기
2017.09.09
by Nathan Chan, translated by pilgwon
스위프트의 String 옵셔널은 약간 이상합니다. String?
타입은 “불가능”한 값이 두 가지 있습니다: nil
과 ""
. 이것은 버그와 예상치 못 한 동작을 처리하고 익히기가 번거롭게 만들 수 있습니다.
예를 들어 UITextField
의 text
속성이 String?
입니다. 우리는 텍스트 필드가 비었있을 때 적절하게 유저에게 알림을 줄 수 있고, 나중에 사용할 수 있도록 텍스트 String의 래핑을 해제하는 동안 다음 코드를 작성할 수 있습니다:
if let title = textField.text else {
if title.isEmpty {
// 알림: 텍스트필드가 비어있습니다!
}
// 타이틀 String이 지금 래핑이 풀려있고, 비어있지도 않고, 사용할 준비가 되었습니다
}
textField.text?.isEmpty ?? true
와 같이 guard let
이나 옵셔널 체이닝의 조합을 사용하는 것도 좋습니다. 어느 쪽이든, 구현 방법은 정신 사납고, 당신은 여러가지 그리고/또는 네스티드 조건문들을 다뤄야 할 것입니다.
스위프트 익스텐션이 구해줄 것입니다!
익스텐션은 이미 존재하는 클래스, 스트럭쳐, 열거형 또는 프로토콜 타입에 새로운 함수를 추가할 수 있게 해줍니다. where
과 함께라면, 당신은 익스텐션을 특정 타입 또는 적합한 타입으로 제한 할 수 있습니다.
그렇다면 이것을 어떻게 String?
에 대한 빈 String 값을 처리하는 데에 적용할 수 있을까요? 이제 익스텐션 안에서 nilIfEmpty
속성을 정의해서 옵셔널 String을 제한해 봅시다. 이것은 빈 String을 nil
으로 바꾸거나 String?
의 원래 값을 반환합니다.
extension Optional where Wrapped == String {
var nilIfEmpty: String? {
guard let strongSelf = self else {
return nil
}
return strongSelf.isEmpty ? nil : strongSelf
}
}
이제는 위의 코드를 정리하여 텍스트 필드가 비어있는 경우를 감지하여 사용자에게 경고하고 텍스트 String의 래핑을 해제 할 수 있습니다:
guard let title = textField.text.nilIfEmpty else {
// 알림: 텍스트필드가 비어있습니다!
return
}
// 타이틀 String이 지금 래핑이 풀려있고, 비어있지도 않고, 사용할 준비가 되었습니다
이쁘지 않나요?
이 익스텐션은 유저가 map
이나 flatMap
과 같은 고차원의 함수를 쓸 때 간단하게 쓸 수 있습니다:
let stuff = ["nate", "", nil, "loves", nil, "swift", ""]
let a = stuff.map { $0.nilIfEmpty }
print(a) // [Optional("nate"), nil, nil, Optional("loves"), nil, Optional("swift"), nil]
let b = stuff.flatMap { $0.nilIfEmpty }
print(b) // ["nate", "loves", "swift"]
끝나기 전에…
혹시 빈 옵셔널 String을 다루기 위한 다른 접근 방법을 아시나요? 저는 매우 듣고 싶습니다. 댓글을 달아주시거나 저를 트위터 @nathanwchan에서 찾아주세요.