SwiftUI

[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 프로그래밍> (닐 스미스 지음, 황반석 옮김) 중에서

Leave a Reply

error: Content is protected !!