본 포스팅은 '스위프트 프로그래밍 (3판)' 도서와 앨런 Swift 문법 마스터스쿨 강의를 참고하여
Swift 프로그래밍에 대해 정리하는 글입니다.
혹시 틀린 부분이 있거나 질문이 있으시다면 언제든지 댓글 달아주시면 정말 감사하겠습니다 :)
에러 처리
에러 처리는 왜 필요할까?
=> 프로그램은 완벽하게 돌아갈 수 없다. 만약에 에러에 대한 적절한 처리를 하지 않았을 경우 앱이 꺼지게 되고, 앱이 반복적으로 꺼지게 되면 사용자 경험에 상당히 악영향을 끼침
=> 따라서, 미리 발생할 수 있는 에러 케이스를 사전에 정의하여 적절한 처리를 해준다면, 최소한 앱이 꺼지는걸 방지할 수 있다.
Error 프로토콜
enum NetworkError: Error {
case networkingError // 네트워크 에러
case dataError // 데이터 에러
case parseError // json parse 에러
}
- 보통 Error 프로토콜을 준수하는 enum 형식으로 에러를 표현한다.
do-catch
do {
try network()
// 정상적인 경우 코드를 하단에 작성
} catch {
//에러일 때 실행할 코드
}
- 여기서 network() 라는, try 가 앞에 붙는 메서드는 반드시 에러를 던진다는 키워드인 throws 가 붙은 메서드여야 한다.
func network(_ search: String) throws -> Bool {
1) 에러 처리방법 1 : try
-> catch 문을 통해 에러별 디테일한 처리가 필요할 때
enum HeightError: Error { //1) 에러 프로토콜 채택
case maxHeight
case minHeight
}
// 2) 에러가 발생할 수 있는 함수에 대한 정의 -> throws 키워드를 반드시 붙여야함
func checkingHeight(height: Int) throws -> Bool {
if height > 190 {
throw HeightError.maxHeight
} else if height < 130 {
throw HeightError.minHeight
} else {
if height >= 160 {
return true
} else {
return false
}
}
}
do {
let isChecked = try checkingHeight(height: 200) // 에러를 던질 있는 함수 실행
print("놀이기구 타는 것 가능: \(isChecked)") // 위에서 정상적으로 넘어왔을 떄의 동작
} catch {
print("놀이기구 타는 것 불가능") // 실패했을 때의 동작
}
에러 별 세부 분기처리를 하고 싶을 때
catch HeightError.maxHeight {
} catch HeightError.minHeight {
} catch { // 그 외의 에러 처리
}
catch {
if let error = error as? HeightError { // 실제 우리가 정의한 구체적인 에러 타입이 아니고, 에러 타입(프로토콜)이 넘어올 뿐
switch error {
case .maxHeight:
case .minHeight:
}
}
}
2) try? (Optional try)
-> 에러가 발생하는 경우 nil을 리턴하는 방식으로 에러처리 (do catch 문을 사용하지 않고 에러 처리 가능)
let isChecked = try? checkingHeight(height: 150) // Bool?
if let result = isChecked { // 벗겨질 경우 -> 즉 에러가 아닐 경우
print(result)
}
func fetchData() -> Data? {
if let data = try? fetchDataFromDisk() {
return data
}
if let data = try? fetchDataFromSerer() {
return data
}
return nil
}
3) try! (Forced try)
-> 에러가 발생하지 않음을 확신하는 경우(에러가 발생하면, 런타임 에러가 발생하므로 사용 지양)
Result
에러를 던지는 것이 아닌, 성공/실패를 담아 반환할 수 있는 타입
https://developer.apple.com/documentation/swift/result
- Result<Success, Failure> 에서 success, failure는 각각 열거형 타입이다.
func resultTypeCheckingHeight(height: Int) -> Result<Bool, HeightError> {
if height > 190 {
return Result.failure(HeightError.maxHeight)
} else if height < 130 {
return Result.failure(HeightError.minHeight)
} else {
if height >= 160 {
return Result.success(true)
} else {
return Result.success(false)
}
}
}
let result = resultTypeCheckingHeight(height: 200)
switch result {
case .success(let data):
print("결과값은 \(data)입니다.")
case .failure(let error):
print(error)
}
기존 do-catch 문과 다른 점은,
1) 에러를 던질 수 있는 함수가 필요 없음 (throws 키워드 필요 X)
2) 에러 발생 시 throw를 통해 에러를 던지거나, try문이 필요 없음
do-catch문에 비해 가지는 이점?
1) 에러를 던지는 함수에서 에러 형식을 특정하기 어려움 (어떤 에러인지 알려면 추가적으로 시간이 소요됨)
2) 에러가 발생할 때 throw를 할 필요가 없어짐
3) catch문에서 switch 문으로 에러를 처리할 때, 에러 타입캐스팅 불필요
'🐦 Swift' 카테고리의 다른 글
[Swift] ARC(Automatic Reference Counting) (0) | 2023.06.29 |
---|---|
[Swift] 프로토콜 (protocol) (0) | 2023.06.20 |
[Swift] 확장 (익스텐션, Extension) (0) | 2023.06.11 |
[Swift] 클래스의 상속, 생성자, 타입캐스팅 (0) | 2023.06.11 |
[Swift] 속성(property)와 메소드(method) (0) | 2023.06.08 |