
⎮ 에러 처리 방법 Lv1 : if문
코드를 작성하다보면, 에러처리를 해야할 때가 있다
개발을 할 때 처음의 error 처리는 조건문과 print문을 사용하여 처리한다.
let password = "123456"
func checkAnswer(_ input: String) {
if input == password {
print("로그인 성공")
} else {
print("로그인 실패")
}
}
checkAnswer("123")
⎮ 에러 처리 방법 Lv2: guard문
이후 guard문을 배우게 되면 guard문을 사용하고 싶어진다.
let password = "123456"
func checkAnswer(_ input: String) {
guard input == password else {
print("로그인 실패")
return
}
print("로그인 성공")
}
checkAnswer("123")
⎮ 에러 처리 방법 Lv3: do, try, catch문
조금 더 심도있게 에러를 처리할 때, 우리는 do, try, catch문을 사용할 수 있다.
1. do, try, catch를 모두 사용하는 방법
// 열거형으로 CustomError 만들기
enum CustomError: Error {
case tooShortInput
case tooLongInput
case wrongInput
}
// 입력의 유효성 검사
func validate(_ input: String) throws -> Bool {
if input.count < 6 {
throw CustomError.tooShortInput
} else if input.count > 8 {
throw CustomError.tooLongInput
} else {
// 유효성 검사가 끝난 값만 정답 확인
return try checkAnswer(input)
}
}
// 유효성 검사가 끝난 값만 정답 확인
func checkAnswer(_ input: String) throws -> Bool {
if input == "123456" {
return true
} else {
throw CustomError.wrongInput
}
}
// do, try, catch 사용
do {
let isCorrect = try validate("123456")
if isCorrect {
print("정답입니다.")
}
} catch {
print(error)
}
try - catch는, 에러를 처리하기 위한 구문으로
throw 구문을 활용하여 말 그대로 에러를 던져준다
// do, try, catch문의 기본 형태
do {
try 오류 발생 가능 코드
} catch 오류 패턴 {
처리 코드
}
do {
let isCorrect = try validate("123466")
if isCorrect {
print("정답입니다.")
}
} catch CustomError.wrongInput {
print("비밀번호가 틀렸습니다.")
}
기본 형태를 따라 위의 코드처럼 작성할 수도 있다.
2. try만 단독으로 사용하는 방법-1(try?)
let isCorrect = try? validate("123456")
if isCorrect == nil {
print("로그인 실패")
} else {
print("로그인 성공")
}
위 코드처럼 try?를 사용하면, Optional 값으로 처리하여 에러가 발생할 때는 값을 nil로 만들 수도 있다.
값이 nil로 반환되기 때문에 do, catch를 할 필요가 없다.
3. try만 단독으로 사용하는 방법-2(try!)
let isCorrect = try! validate("123456")
if isCorrect {
print("로그인 성공")
}
단 위의 경우에는 isCorrect가 nil일 때 크래시가 발생하므로, 값에 오류가 없음을 확신할 때만 사용 그냥, 사용하지 말도록 하자
⎮ 에러 처리 방법 Lv4: Result Type
https://developer.apple.com/documentation/swift/result
Result | Apple Developer Documentation
A value that represents either a success or a failure, including an associated value in each case.
developer.apple.com
Apple Docs에 따르면, Result Type은 다음과 같다
A value that represents either a success or a failure, including an associated value in each case.
성공 또는 실패 케이스를 나타내는 값으로, 각각의 케이스의 연관 값을 포함합니다.
@frozen
enum Result<Success, Failure> where Failure : Error, Success : ~Copyable
// 열거형으로 CustomError 만들기
enum CustomError: Error {
case tooShortInput
case tooLongInput
case wrongInput
}
// 입력의 유효성 검사
func validate(_ input: String) throws -> Bool {
if input.count < 6 {
throw CustomError.tooShortInput
} else if input.count > 8 {
throw CustomError.tooLongInput
} else {
// 유효성 검사가 끝난 값만 정답 확인
return try checkAnswer(input)
}
}
// 유효성 검사가 끝난 값만 정답 확인
func checkAnswer(_ input: String) throws -> Bool {
if input == "123456" {
return true
} else {
throw CustomError.wrongInput
}
}
// do, try, catch 사용
do {
let isCorrect = try validate("123456")
if isCorrect {
print("정답입니다.")
}
} catch {
print(error)
}
위의 코드를 Result Type으로 변경해보면 아래의 코드처럼 변경할 수 있다.
enum CustomError: Error {
case tooShortInput
case tooLongInput
case wrongInput
}
func validate(_ input: String) -> Result<Bool, CustomError> {
if input.count < 6 {
return .failure(.tooShortInput)
} else if input.count > 8 {
return .failure(.tooLongInput)
} else {
return .success(true)
}
}
let checkAnswer = validate("123456")
switch checkAnswer {
case .success(let data):
print(data)
case .failure(let error):
print(error)
}
비교해보자면,
// throws를 사용할 때
func validate(_ input: String) throws -> Bool {
if input.count < 6 {
throw CustomError.tooShortInput
} else if input.count > 8 {
throw CustomError.tooLongInput
} else {
// 유효성 검사가 끝난 값만 정답 확인
return try checkAnswer(input)
}
}
// Result Type을 사용할 때
func validate(_ input: String) -> Result<Bool, CustomError> {
if input.count < 6 {
return .failure(.tooShortInput)
} else if input.count > 8 {
return .failure(.tooLongInput)
} else {
return .success(true)
}
}
throws 함수를 사용할 때 : 에러를 던져주고 유효성 검사가 끝난 값만 checkAnswer를 try (return 되는 값이 Bool)
Result를 사용할 때 : 실패 케이스와 성공 케이스로 return이 가능 (return 되는 값이 성공 또는 실패)
// throws를 사용할 때
func checkAnswer(_ input: String) throws -> Bool {
if input == "123456" {
return true
} else {
throw CustomError.wrongInput
}
}
do {
let isCorrect = try validate("123456")
if isCorrect {
print("정답입니다.")
}
} catch {
print(error)
}
//Result Type을 사용할 때
let checkAnswer = validate("123456")
switch checkAnswer {
case .success(let data):
print(data)
case .failure(let error):
print(error)
}
⎮ Result Type과 do, try, catch의 차이
Result Type과 do - try - catch는 비슷한 매커니즘을 가지고 있는거 같은데,
그럼 어떤 점이 다를까?
| 구 분 | Result Type | do - try - catch |
| 에러 전달 방식 | 값(Value)로 에러를 전달함 | throws 함수 호출 시 에러를 던짐(throw) |
| 처리 방식 | switch문으로 success와 failure를 구분함 | do 블럭 안에서 try하고, catch 블럭에서 에러 처리 |
- Result Type을 사용하는 비동기 작업 예시
func loadData(completion: (Result<Data, Error>) -> Void) {
// 네트워크 처리 후 에러를 다룰 때
completion(.failure(CustomError.tooShortInput))
}
이해할 수 있었던 내용은
1. Result Type은 succes case와 failure case가 명시되어 있어서 가독성이 좋다는 것과
2. Result Type은 비동기 작업을 할 때 사용하고, do - try - catch는 간단한 작업을 할 때 사용한다는 점
정도..?를 이해할 수 있었다.
세부사항은 더 공부가 필요하겠지만...
'스파르타코딩 클럽 > 기초' 카테고리의 다른 글
| Swift | CocoaPods 설치하기 (0) | 2025.04.26 |
|---|---|
| Swift | Swift에서 한글을 정렬하는 방법(+ sort, sorted) (0) | 2025.04.23 |
| Swift | 네트워크 쉽게 이해하기(with URLSession) (0) | 2025.04.17 |
| Swift | 클로저(Closure) 쉽게 이해하기? (2) | 2025.04.05 |
| Swift | MVC 패턴이 뭔데? (0) | 2025.04.02 |