async await

고양이발냄새·2023년 8월 25일
0
struct FunctionTypes {
  var syncNonThrowing: () -> Void
  var syncThrowing: () throws -> Void
  var asyncNonThrowing: () async -> Void
  var asyncThrowing: () async throws -> Void
  
  mutating func demonstrateConversions() {
    // Okay to add 'async' and/or 'throws'    
    asyncNonThrowing = syncNonThrowing
    asyncThrowing = syncThrowing
    syncThrowing = syncNonThrowing
    asyncThrowing = asyncNonThrowing
    
    // Error to remove 'async' or 'throws'
    syncNonThrowing = asyncNonThrowing // error
    syncThrowing = asyncThrowing       // error
    syncNonThrowing = syncThrowing     // error
    asyncNonThrowing = syncThrowing    // error
  }
}
// func redirectURL(for url: URL) async -> URL { ... }
// func dataTask(with: URL) async throws -> (Data, URLResponse) { ... }

let newURL = await server.redirectURL(for: url)
let (data, response) = try await session.dataTask(with: newURL)

https://green1229.tistory.com/340

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // MARK: METHOD 1 - Using Async/Await

    Task {
        if let imageDetail = try? await downloadImageAndMetadata(imageNumber: 1) {
            self.imageView.image = imageDetail.image
            self.metadata.text = "\(imageDetail.metadata.name) (\(imageDetail.metadata.firstAppearance) - \(imageDetail.metadata.year))"
        }
    }

    // MARK: METHOD 2 - Using async properties

//        Task {
//            let character = Character(id: 1)
//            if
//                let metadata = try? await character.metadata,
//                let image = try? await character.image{
//                imageView.image = image
//                self.metadata.text = "\(metadata.name) (\(metadata.firstAppearance) - \(metadata.year))"
//            }
//        }

    // MARK: Method 3 - Using Callbacks

//        downloadImageAndMetadata(imageNumber: 1) { imageDetail, error in
//            DispatchQueue.main.async {
//                if let imageDetail = imageDetail {
//                    self.imageView.image = imageDetail.image
//                    self.metadata.text =  "\(imageDetail.metadata.name) (\(imageDetail.metadata.firstAppearance) - \(imageDetail.metadata.year))"
//                }
//            }
//        } 예제 앱!!!!!!!!!!!!!!!!!
}

task의 용도는 펑션을 만들때 꼭 앞에 async를 붙여주어야한다 하지만 이미 apple에서 만들어져있는 method를 쓸때는 async를 써줄수가 없으므로 그럴경우네느 Task {}안에 넣어서 쓰면 된다 Task안에는 async나 sync 둘다 사용할수 있다

이거 좀 중요함
두개의 async await가 있고 두개가 서로 의존하지 않는다면 두개를 동시에 진행해도 상관이 없다
한개가 끝나고 그다음것을 진행하는것보다 더 효율적인 방법이다 그런데 어떻게 할까?

ㅇㅇ 이렇게 하면됨

func downloadImage(imageNumber: Int) async throws -> UIImage {
    try Task.checkCancellation()
    let imageUrl = URL(string: "https://www.andyibanez.com/fairesepages.github.io/tutorials/async-await/part3/\(imageNumber).png")!
    let imageRequest = URLRequest(url: imageUrl)
    let (data, imageResponse) = try await URLSession.shared.data(for: imageRequest)
    guard let image = UIImage(data: data), (imageResponse as? HTTPURLResponse)?.statusCode == 200 else {
        throw ImageDownloadError.badImage
    }
    return image
}

func downloadMetadata(for id: Int) async throws -> ImageMetadata {
    try Task.checkCancellation()
    let metadataUrl = URL(string: "https://www.andyibanez.com/fairesepages.github.io/tutorials/async-await/part3/\(id).json")!
    let metadataRequest = URLRequest(url: metadataUrl)
    let (data, metadataResponse) = try await URLSession.shared.data(for: metadataRequest)
    guard (metadataResponse as? HTTPURLResponse)?.statusCode == 200 else {
        throw ImageDownloadError.invalidMetadata
    }

    return try JSONDecoder().decode(ImageMetadata.self, from: data)
}

func downloadImageAndMetadata(imageNumber: Int) async throws -> DetailedImage {
    async let image = downloadImage(imageNumber: imageNumber)
    async let metadata = downloadMetadata(for: imageNumber)
    return try DetailedImage(image: await image, metadata: await metadata)
}

// NEW FUNCTION
func downloadMultipleImagesWithMetadata(images: Int...) async throws -> [DetailedImage]{
    var imagesMetadata: [DetailedImage] = []
    for image in images {
        print(image)
        async let image = downloadImageAndMetadata(imageNumber: image)
        imagesMetadata +=  [try await image]
    }
    return imagesMetadata
} Task Tree Sample


of 있는곳에 for loop을 돌려서 나오는 타입을 적어줌
이 경우에는 uiimage
여기서 주의할점은 image가 순서대로 나오지 않으므로 딕셔너리를 이용해서 순서를 쫓아가는등 하는 방법이 있어야함

profile
고양이좋아

0개의 댓글