Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use async/await with URLSession #1

Open
Taehyeon-Kim opened this issue May 24, 2022 · 1 comment
Open

Use async/await with URLSession #1

Taehyeon-Kim opened this issue May 24, 2022 · 1 comment
Assignees
Labels
Swift WWDC Topic: swift wwdc21 wwdc2021

Comments

@Taehyeon-Kim
Copy link

Taehyeon-Kim commented May 24, 2022

wwdc21_#1_thumb

Discover how you can adopt Swift concurrency in URL Session using async/await and AsyncSequence, and how you can apply Swift concurrency to improve your networking code.

@Taehyeon-Kim Taehyeon-Kim added wwdc21 wwdc2021 Swift WWDC Topic: swift labels May 24, 2022
@hyun99999 hyun99999 changed the title [WWDC21] Use async/await with URLSession Use async/await with URLSession May 24, 2022
@hyun99999 hyun99999 pinned this issue May 24, 2022
@Taehyeon-Kim
Copy link
Author

Taehyeon-Kim commented May 31, 2022

WWDC21) Use async/await with URLSession

Use async/await with URLSession

*본 글은 WWDC 를 보고, 번역 및 요약 그리고 실행해보는 스터디 프로젝트의 일환입니다.

들어가며

그냥 ThumbnailInternet Technologies Engineer 직책 이름, 모든 것이 멋지다...
역시 나는 Apple을 좋아할 수 밖에 없는걸까?
Guoye Zhang, Engineer는 HTTP Framework 부서에서 일하신다고 한다.

Swift Concurrency(동시성) 장점

  • 선형적(linear)
  • 간결(Concise)
  • 기본 Swift 오류 처리(Native error handling)

네트워킹은 본질적으로 비동기식으로 이루어지고 있습니다. iOS 15, macOS Monterey에서는 Swift 동시성 기능을 활용할 수 있도록 URLSession에 새로운 API 세트를 도입했습니다.

기존 코드(Completion handler를 곁들인)

func fetchPhoto(url: URL, completion: @escaping (UIImage?, Error?) -> Void) {
    let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
        if let error = error {
            completion(nil, error)
        }
        
        if let data = data,
           let httpResponse = response as? HTTPURLResponse,
           httpResponse.statusCode == 200 {
            // main 스레드에서 돌리는 이유?
            DispatchQueue.main.async {
                completion(UIImage(data: data), nil)
            }
        } else {
            completion(nil, DogsError.invaildServerResponse)
        }
    }
    task.resume()
}

제어흐름

앞뒤로 흐름이 왔다갔다 합니다.

  • 데이터 작업(Data Task)을 만듭니다.
  • 작업을 다시 시작(Resume)합니다.
  • 작업이 완료되면 Completion Handler로 이동해서 응답을 확인합니다.
  • 이미지를 생성하고 여기서 제어 흐름이 종료�됩니다.

스레딩

서로 다른 3개의 실행 컨텍스트가 존재합니다.

  • 가장 바깥 레잉어는 호출자(Caller)의 스레드 또는 대기열(Queue)에서 실행
  • URLSessionTask completionHandler는 세션의 대리자 대기열에서 실행
  • 최종 완료 핸들러는 기본 대기열에서 실행

CompletionHandler에 대한 호출은 기본 큐에 일관되게 전달되지 않습니다.

async/await을 이용한 코드

func fetchPhoto(url: URL) async throws -> UIImage {
    
    let (data, response) = try await URLSession.shared.data(from: url)
    
    guard let httpResponse = response as? HTTPURLResponse,
          httpResponse.statusCode == 200 else {
        throw DogsError.invaildServerResponse
    }
    
    guard let image = UIImage(data: data) else {
        throw DogsError.unsupportedImage
    }
    
    return image
}
  • 제어 흐름이 위에서 아래로 선형입니다.
  • 동일한 동시성 컨텍스트에서 실행됩니다.
  • 스레딩 문제에 대해서 걱정할 필요가 없습니다.
  • 현재 실행 컨텍스트를 차단하지 않고, 일시중단하고 성공적으로 완료되면 데이터와 응답을 반환하거나 오류를 throw합니다.
  • Swift의 기본 오류 처리를 사용해서 오류를 Catch하고 처리할 수 있습니다.

Upload

var request = URLRequest(url: url)
request.httpMethod = "POST"

let (data, response) = try await URLSession.shared.upload(for: request, fromFile: fileURL)

guard let httpResponse = response as? HTTPURLResponse,
      httpResponse.statusCode == 200 else {
    throw MyNetworkingError.invaildServerResponse
}

@Taehyeon-Kim Taehyeon-Kim unpinned this issue May 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Swift WWDC Topic: swift wwdc21 wwdc2021
Projects
None yet
Development

No branches or pull requests

1 participant