[Swift] 스위프트 에러 핸들링 방법 (defer 구문 사용은?)
앱을 통제할 수 없는 상황은 언제든지 발생할 것이다.
예를 들어, 활성화된 인터넷 연결을 기반으로 동작하는 앱은 아이폰 디바이스가 네트워크 신호를 잃는 것을 제어할 수 없으며,
사용자가 비행기 모드(airplane mode)를 활성화하는 것도 막을 수 없다.
앱이 해낼 수 있는 것은 그러한 에러를 확실하게 처리하도록 구현하는 것이다. 예를 들어, 앱을 계속 사용하려면 활성화된 인터넷 연결이 필요하다는 것을 사용자가 알 수 있도록 메시지를 표시하는 것이다.
에러 던지기
메서드나 함수가 에러를 던질 수 있다는 것을 선언할 때는 다음의 예제와 같이 throws 키워드를 이용한다.
func transferFile() throws {
}
결과를 반환하는 메서드나 함수의 경우, throws 키워드는 다음과 같이 반환 타입 앞에 위치하게 된다.
func transferFile() throws -> Bool {
}
오류가 발생할 때 에러를 던지는 코드를 추가할 수 있다. 이것은 throw 구문과 guard 구문을 결합하여 사용하게 된다.
let connectionOK = true
let connectionSpeed = 30.00
let fileFound = false
enum FileTransferError: Error {
case noConnection
case lowBandwidth
case fileNotFound
}
func fileTransfer() throws {
guard connectionOK else {
throw FileTransferError.noConnection
}
guard connectionSpeed > 30 else {
throw FileTransferError.lowBandwidth
}
guard fileFound else {
throw FileTransferError.fileNotFound
}
}
메서드 내에 있는 각각의 guard 구문은 각 조건이 참인지 거짓인지를 검사한다.
에러를 던지는 메서드와 함수 호출하기
메서드 또는 함수가 에러를 던지도록 선언했다면 일반적인 방법으로는 호출할 수 없다. 이러한 메서드를 호출할 때는 다음과 같이 앞에 try 구문을 붙여야 한다.
try fileTransfer()
try 구문을 이용하는 방법 외에도 던져진 모든 에러를 잡아서 처리하는 do-catch 구문 내에서 호출하는 방법도 있다. 예를 들어, fileTransfer 메서드를 sendFile이라는 이름의 메서드 내에서 호출해야 한다고 가정해보자. 이 경우에는 다음과 같이 구현할 수 있다.
func sendFile() -> String {
do {
try fileTransfer()
} catch FileTransferError.noConnection {
return "No Network Connection"
} catch FileTransferError.lowBandwidth {
return "File Transfer Speed too Low"
} catch FileTransferError.fileNotFound {
return "File not Found"
} catch {
return "Unknown error"
}
return "Successful transfer"
}
에러 객체에 접근하기
do {
try filemgr.createDirectory(atPath: newDir,
withIntermediateDirectories: true,
attributes: nil)
} catch let error {
print("Error: (error.localizedDescription)")
}
defer 구문 사용하기
defer 구문은 메서드가 결과를 반환하기 직전에 실행되어야 하는 일련의 코드를 지정할 수 있게 해준다. 다음의 코드는 defer 구문이 포함되도록 sendFile 메서드를 수정한 것이다.
func sendFile() -> String {
defer {
removeTmpFiles()
closeConnection()
}
do {
try fileTransfer()
} catch FileTransferError.noConnection {
return "No Network Connection"
} catch FileTransferError.lowBandwidth {
return "File Transfer Speed too Low"
} catch FileTransferError.fileNotFound {
return "File not Found"
} catch {
return "Unknown error"
}
return "Successful transfer"
}
-알라딘 eBook <핵심만 골라 배우는 SwiftUI 기반의 iOS 프로그래밍> (닐 스미스 지음, 황반석 옮김) 중에서