Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 카카오뱅크 ios
- Tuist
- GCD
- Combine
- ios swiftdata
- 네트워크 통신
- observable
- swiftdata
- swift 5.9
- Firebase
- swift db
- xcode
- JSON
- KeyPath
- Subject
- ribs
- Tuist Swift
- Swift Tuist
- Firebase Analytics
- swift
- swift 6
- ios
- SeSAC
- arc
- SwiftUI
- realm
- swift database
- RxSwift
- ios database
- Subscribe
Archives
- Today
- Total
천원의 개발
iOS Result 타입을 활용한 에러처리 본문
Result ?
Swift 5.0 부터 지원하는 에러를 처리하는 방법입니다.
Result 타입 정의
enum Result<Success, Failure: Error> {
case success(Success)
case failure(Failure)
}
enum을 활용하여 success와 failure의 case로 구분 지어주고 제네릭을 타입을 연관값에 넣어주어 사용합니다.
어떻게 사용할지 감이 안 잡히시죠 한번 같이 사용해 봅시다.
Error프로토콜을 채택한 APIError
enum APIError: String, Error {
case invalidRessponse = "응답이 없습니다."
case noData = "데이터가 없습니다."
case failedRequest = "요청에 실패 하였습니다."
case invalidData = "검색어와 일치하는 레시피가 없습니다."
case failedResponse = "응답을 받을 수 없습니다."
}
아래는 간단한 API 통신을 처리하는 코드 입니다. 여기서 보면 completion이라는 클로저를 활용하여 error가 있을때는 CookRecipe는 nil값을 전달하고 APIError는 .failedRequest를 전달하는 모습을 확인 할 수있습니다. 이렇게 코드를 구성하게 되면 우리가 원하는
(CookRecipe, APIError)
nil, true
true, nil
두개의 상황만 처리 해주면 되지만
nil, nil
true, true
상황 까지 처리 하는 코드가 되어 버리는 것이죠
func requsetAPI(text: String, completion: @escaping (CookRecipe?, APIError?) -> Void {
URLSession.shared.dataTask(with: url) { data, response, error in
DispatchQueue.main.async {
guard error == nil else {
completion(nil, .failedRequest)
return
}
guard let data = data else {
completion(nil, .noData)
return
}
guard response.statusCode == 200 else {
completion(nil, .failedResponse)
return
}
do {
let result = try JSONDecoder().decode(CookRecipe.self, from: data)
completion(result, nil)
} catch {
completion(nil, .invalidData)
}
}
}.resume()
}
이번에는 Result타입을 활용한 코드를 확인 해보겠습니다.
클로저의 매개변수 타입을 Result<CookRecipe, APIError>로 변경 해줍니다.
func requsetAPI(completion: @escaping (Result<CookRecipe, APIError>) -> Void) {
URLSession.shared.dataTask(with: url) { data, response, error in
DispatchQueue.main.async {
guard error == nil else {
completion(.failure(.failedRequest))
return
}
guard let data = data else {
completion(.failure(.noData))
return
}
guard response.statusCode == 200 else {
completion(.failure(.failedResponse))
return
}
do {
let result = try JSONDecoder().decode(CookRecipe.self, from: data)
completion(.success(result))
} catch {
completion(.failure(.invalidData))
}
}
}.resume()
}
실패시에는 case .failure와 연관 값으로 APIError의 case를 넣어주고 성공시에는 case .success와 CookRecipe 데이터를 넣어주는 방식으로 동작합니다.
확실히 받아올 때 옵셔널 처리를 안해줘두 되고 enum을 통한 failure와 success가 명시적으로 보이니 명확히 구분 할 수 있는것 같습니다.
함수 호출하는 코드
requsetAPI { result in
switch result {
case let .success(data):
print(data)
case let .failure(error):
switch error {
case .invalidData, .failedResponse, .invalidRessponse, .noData, .failedRequest:
print(error.rawValue)
}
}
}
'iOS&Swift🍎 > iOS' 카테고리의 다른 글
iOS Preview 보면서 codebase로 작업하기 (0) | 2023.07.12 |
---|---|
iOS Realm 데이터베이스를 활용하여 위젯 만들기(Realm 파일 공유) (0) | 2023.01.02 |
iOS URLSession 정리 (0) | 2022.10.17 |
iOS Realm Migration(마이그레이션) 하는 법 (0) | 2022.10.13 |
iOS Codable 사용법 (0) | 2022.10.13 |