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 |
29 | 30 | 31 |
Tags
- SWIFT
- ios
- map
- Clean Code
- uitableview
- Protocol
- tableView
- 리펙터링
- combine
- 리팩토링
- RxCocoa
- 클린 코드
- UITextView
- Observable
- 애니메이션
- MVVM
- collectionview
- HIG
- swift documentation
- UICollectionView
- Xcode
- Human interface guide
- clean architecture
- uiscrollview
- 리펙토링
- rxswift
- 스위프트
- swiftUI
- Refactoring
- ribs
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - Swift] 2. Swift Concurrency 개념 - async, await를 이용하여 api 호출해보기 본문
iOS 응용 (swift)
[iOS - Swift] 2. Swift Concurrency 개념 - async, await를 이용하여 api 호출해보기
jake-kim 2022. 12. 3. 22:211. Swift Concurrency 개념 - async, await, Task, async let, Actor
2. Swift Concurrency 개념 - async, await를 이용하여 api 호출해보기
Async, Await 없는 API 호출
- 모델 준비
struct AlbumResult: Codable {
let results: [Album]
}
struct Album: Codable, Hashable {
let collectionId: Int
let collectionName: String
let collectionPrice: Double
}
- 구현
enum APIError: Error {
case invalidURL
case noData
}
enum API {
static func fetchAlbums(completion: @escaping (Result<AlbumResult, Error>) -> Void) {
guard let url = URL(string: "https://itunes.apple.com/search?term=taylor+swift&entity=album") else {
completion(.failure(APIError.invalidURL))
return
}
URLSession.shared.dataTask(with: url) { data, _, error in
if let error = error {
completion(.failure(error))
return
}
guard let data = data else {
completion(.failure(APIError.noData))
return
}
do {
let result = try JSONDecoder().decode(AlbumResult.self, from: data)
completion(.success(result))
} catch {
completion(.failure(error))
}
}
.resume()
}
}
- 사용하는쪽
API.fetchAlbums { result in
switch result {
case let .success(response):
print(response)
case let .failure(error):
print(error)
}
}
Async, Await를 사용한 경우
- URLSession앞에 await 키워드를 붙여서 편리하게 사용이 가능
- 스위프트에서 URLSession 확장으로 구현되어 있는걸 활용
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
extension URLSession {
public func data(for request: URLRequest, delegate: URLSessionTaskDelegate? = nil) async throws -> (Data, URLResponse)
public func data(from url: URL, delegate: URLSessionTaskDelegate? = nil) async throws -> (Data, URLResponse)
public func upload(for request: URLRequest, fromFile fileURL: URL, delegate: URLSessionTaskDelegate? = nil) async throws -> (Data, URLResponse)
public func upload(for request: URLRequest, from bodyData: Data, delegate: URLSessionTaskDelegate? = nil) async throws -> (Data, URLResponse)
public func download(for request: URLRequest, delegate: URLSessionTaskDelegate? = nil) async throws -> (URL, URLResponse)
public func download(from url: URL, delegate: URLSessionTaskDelegate? = nil) async throws -> (URL, URLResponse)
public func download(resumeFrom resumeData: Data, delegate: URLSessionTaskDelegate? = nil) async throws -> (URL, URLResponse)
}
- API 정의
- completion handler가 없기 때문에 더욱 깔끔한 코드
- URLSession.shaed.data(from:) 앞에 await 키워드를 붙여서 사용
// MARK: Async & Await
static func fetchAlbums() async throws -> AlbumResult {
guard let url = URL(string: "https://itunes.apple.com/search?term=taylor+swift&entity=album") else {
throw APIError.invalidURL
}
let (data, _) = try await URLSession.shared.data(from: url)
let result = try JSONDecoder().decode(AlbumResult.self, from: data)
return result
}
- 사용하는 쪽
// async await
Task {
do {
let result = try await API.fetchAlbums()
print(result)
} catch {
print(error)
}
}
비교 not async await vs async await
- API 정의 부분
- 사용하는쪽
* 전체 코드: https://github.com/JK0369/ExAsyncAwaitAPI
* 참고
https://betterprogramming.pub/making-network-requests-with-async-await-in-swift-6b5880c9df6a
'iOS 응용 (swift)' 카테고리의 다른 글
Comments