UIKit

Image 비동기 로딩 API (UIKit)

Phililip
728x90

안녕하세요.

 

이번에는 UIKit에서 이미지를 비동기로 로딩할 수 있는 API들에 대해 소개해보려고 합니다.

 

 


 

보통 UICollectionView, UITableView에서 스크롤을 하면, 이미지 로딩 때문에 조금씩 끊기는 현상을 볼 수 있어요.

 

그 원인은

 

첫째, 이미지 로딩할 때 디코딩이 필요한데 디코딩 작업이 메모리를 많이 사용하기 때문이에요.

둘째, 이미지 디코딩은 main thread에서 작업을 해야 하고 화면에 출력될 때 디코딩하는 lazy 한 방식을 사용하기 때문이에요.

 

 

물론, background에서 로딩, 디코딩할 수 있는 API가 있지만 워낙 low-level의 API이고 메모리 관리를 직접 해줘야 하는 불편함이 있어서 쉬운 작업은 아니에요...ㅠㅠㅠ

 

그런데!! iOS 15부터 훨씬 쉽게 background에서 작업할 수 있는 API가 추가되었습니다.

 

한번 알아볼게요ㅎㅎ

 

 

## 1. UIKit

### 1.1 preparingForDisplay()

디코딩된 이미지를 반환하는 동기 API입니다.

 

그리고 background에서 동작이 가능합니다.

 

애플은 serial queue와 함께 사용하는 것을 권장하고 있어요.

 

// Create your serial queue for lining up the decoding tasks.
let serialQueue = ...

// In the view configuration method:

// Access the corresponding `UICollectionViewCell` / `UITableViewCell`.
let itemCell = ...

let image: UIImage = getImageForItem(item)

serialQueue.async {
   // Call `preparingForDisplay`, which runs synchronously.
   let decodedImage = image.preparingForDisplay()!

   DispatchQueue.main.async {
      // Fetch the relevant cell here instead of capturing it to ensure that the fetched cell belongs to the correct index path.
      let itemCell = ...

      // Set the decoded image as the image for the image view of the cell now that you have the decoded image.
      itemCell.imageView.image = decodedImage
   }
}

 

 

 

### 1.2 prepareForDisplay(completionHandler:)

디코딩된 이미지를 반환하는 비동기 API입니다.

 

// In the view configuration method:

// Access the corresponding `UICollectionViewCell` / `UITableViewCell`.
let itemCell = ...

let image: UIImage = getImageForItem(item)

image.prepareForDisplay { decodedImage in
      // Fetch the relevant cell here instead of capturing it to ensure that the fetched cell belongs to the correct index path.
      let itemCell = ...

      // Set the decoded image as the image for the image view of the cell now that you have the decoded image.
      itemCell?.imageView.image = decodedImage
}

 

 

 

### 1.3 byPreparingForDisplay()

async/await 패턴에서 사용할 수 있는 비동기 API입니다.

 

// In the view configuration method:

// Access the corresponding `UICollectionViewCell` / `UITableViewCell`.
let itemCell = ...

let image: UIImage = getImageForItem(item)

async {
   // Start preparing the image the asynchronously.
   let decodedImage  = await image.byPreparingForDisplay()

   // Set the decoded image to the cell.
   itemCell.imageView.image = decodedImage
}

 

 

 

SwiftUI에서 비동기로 이미지를 로딩하고 싶을 땐 AsyncImage를 사용하면 됩니다!!ㅎㅎ

 

 

 

## 참고

- https://pspdfkit.com/blog/2021/ios-15-image-api/

 

Loading Images on iOS 15 | PSPDFKit

We discuss the new iOS 15 APIs provided by UIKit for loading and displaying images and the SwiftUI APIs for loading an image from a remote URL.

pspdfkit.com

 

 


 

이번 글은 여기서 마무리.

 

 

 

반응형

'UIKit' 카테고리의 다른 글

viewDidLayoutSubviews  (0) 2022.07.24
UIKeyboardLayoutGuide  (0) 2022.03.29
DiffableDataSource를 사용해서 TableView 드래그&드롭 기능 넣기  (0) 2022.02.19
DiffableDataSource  (0) 2022.02.19
UICollectionView (2)  (0) 2022.02.17