티스토리 뷰
728x90
반응형
Swift5의 Result Type을 사용하면 비동기 API쪽 코드(데이터 받아와서 디코딩해주는..)를 간단하고 명확하게 만들 수 있다
[ 1 ] 그전에는..
1) 옵셔널로 구분
func fetchModel<T: Decodable>(completion: @escaping (T?) -> Void) {
let url = URL(string: "...")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else {
return completion(nil)
}
guard let model = try? JSONDecoder().decode(T.self, from: data) else {
return completion(nil)
}
completion(model)
}.resume()
}
nil인지 아닌지 여부로 데이터가 잘 받아지고 디코딩도 잘 되었는지 확인했다
fetchModel { (model: SomeModel?) in
if let model = model {
print(model)
}
}
2) 더 나아가 에러까지 구체적으로 명시해서 구분
enum APIError: Error {
case data
case decodingJSON
}
func fetchModel<T: Decodable>(completion: @escaping (T?, APIError?) -> Void) {
let url = URL(string: "...")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else {
return completion(nil, .data)
}
guard let model = try? JSONDecoder().decode(T.self, from: data) else {
return completion(nil, .decodingJSON)
}
completion(model, nil)
}.resume()
}
fetchModel { (model: SomeModel?, error) in
if let error = error {
print(error)
}
if let model = model {
print(model)
}
}
3) 더더 나아가 APIResult 라는 Enum을 정의해서 처리
enum APIResult<T> {
case success(T)
case failure(APIError)
enum APIError: Error {
case data
case decodingJSON
}
}
func fetchModel<T: Decodable>(completion: @escaping (APIResult<T>) -> Void) {
let url = URL(string: "...")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else {
return completion(.failure(.data))
}
guard let model = try? JSONDecoder().decode(T.self, from: data) else {
return completion(.failure(.decodingJSON))
}
completion(.success(model))
}.resume()
}
fetchModel { (result: APIResult<WeatherResult>) in
switch result {
case .success(let model):
print(model)
case .failure(let error):
print(error)
}
}
[ 2 ] Result Type
Swift5는 standard library(표준 라이브러리)에 Result Type이 추가되었다
이제 위의 APIResult같은 enum을 따로 만들어주지 않아도 된다 : )
(https://github.com/apple/swift-evolution/blob/master/proposals/0235-add-result.md)
public enum Result<Success, Failure> where Failure : Error {
/// A success, storing a `Success` value.
case success(Success)
/// A failure, storing a `Failure` value.
case failure(Failure)
}
enum APIError: Error {
case data
case decodingJSON
}
func fetchModel<T: Decodable>(completion: @escaping (Result<T,APIError>) -> Void) {
let url = URL(string: "...")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else {
return completion(.failure(.data))
}
guard let model = try? JSONDecoder().decode(T.self, from: data) else {
return completion(.failure(.decodingJSON))
}
completion(.success(model))
}.resume()
}
guard let 대신 do catch를 쓸 수도 있다
func fetchModel<T: Decodable>(completion: @escaping (Result<T,APIError>) -> Void) {
let url = URL(string: "...")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else {
return completion(.failure(.data))
}
do {
let model = try JSONDecoder().decode(T.self, from: data)
completion(.success(model))
} catch {
completion(.failure(.decodingJSON))
}
}.resume()
}
fetchModel { (result: Result<WeatherResult,APIError>) in
switch result {
case .success(let model):
print(model)
case .failure(let error):
print(error)
}
}
+ Swift5 에 관해 더 읽어보기
https://swift.org/blog/swift-5-released/
이 영상도 좋다...!! >___<
반응형
'🍏 > Swift' 카테고리의 다른 글
[Date] Swift에서 Date를 이용하는 여러 케이스들 모음 (0) | 2020.02.01 |
---|---|
[Enum] Enum에서 불가능한 상황들(?) (0) | 2019.06.06 |
[Swift] ~= 연산자 (0) | 2019.04.29 |
[Swift] Swift로 Binary Search( 이진 탐색 알고리즘 )를 구현해보자 (0) | 2019.03.30 |
[Swift] Binary Search Tree ( 이진 탐색 트리 ) 를 Swift로 구현해보자 + search / insert / delete (0) | 2018.10.15 |
댓글
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- ribs
- METAL
- 장고 Custom Management Command
- Django FCM
- 플러터 싱글톤
- Watch App for iOS App vs Watch App
- flutter 앱 출시
- Flutter getter setter
- github actions
- drf custom error
- 장고 URL querystring
- PencilKit
- Flutter 로딩
- Flutter Clipboard
- Django Heroku Scheduler
- Sketch 누끼
- Python Type Hint
- flutter build mode
- flutter deep link
- ipad multitasking
- 플러터 얼럿
- Dart Factory
- cocoapod
- flutter dynamic link
- DRF APIException
- 구글 Geocoding API
- Flutter Spacer
- Flutter Text Gradient
- SerializerMethodField
- Django Firebase Cloud Messaging
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
29 | 30 | 31 |
글 보관함