포스트

[UIKit] Bundle을 이용한 이미지 로딩 문제 해결하기

[UIKit] Bundle을 이용한 이미지 로딩 문제 해결하기

Bundle을 이용해 앱 내부 리소스에서 이미지를 로드하는 과정에서 UIImage(data: )를 이용했을 때 이미지가 정상적으로 표시되지 않는 문제가 발생했다.

해당 문제를 해결하기 위한 트러블 슈팅 과정에서 Bundle에 대한 이해가 필요했고, 최종적으로 문제의 원인이 SVG와 PNG의 차이점에서 비롯된 것임을 알 수 있었다.

이 글에서는 문제 해결 과정을 정리하고, 학습했던 관련 개념들을 함께 정리해볼까 한다.

Bundle과 Assets 접근 이해하기

Bundle이란?

Bundle은 앱 실행 코드 및 리소스를 관리하는 객체로, 앱 내의 실행 파일, 스토리보드, 이미지, JSON 파일, 사운드 등 다양한 리소스를 포함한다. 즉, 특정 리소스에 접근하기 위해서 활용되기 적합한 객체라고 볼 수 있다.

Bundle의 기본 개념

  • Bundle.main은 앱의 기본 번들을 나타내며, 실행 파일과 기본 리소스가 포함된 번들을 가리킨다.
  • Bundle.url(forResource: ,withExtension: ) 메서드를 사용하면 번들 내 특정 리소스의 URL을 반환할 수 있다.
    1
    2
    3
    
    if let url = Bundle.main.url(forResource: "testImage", withExtension: "svg") {
      print(url)
    }
    

    위 코드에서 testImage.svg 파일이 번들에 포함되어 있다면 해당 파일의 URL을 얻을 수 있고, 존재하지 않는 경우 nil이 반환된다.

Bundle과 Assets 접근의 제한

처음에는 번들을 활용해 앱의 Assets 폴더 내 이미지를 가져올 수 있을거라 생각했는데, 실제로는 Bundle을 이용해 Assets에 직접 접근할 수 없었다.

이는 Xcode에서 제공하는 Assets Catalog가 내부적으로 최적화된 방식으로 리소스를 저장하기 때문에, 물리적인 경로를 통해 접근할 수 없었기 때문이다. Assets에 저장된 이미지는 UIImage(named: )를 이용해 가져와야 됐다.

문제 상황 및 원인 분석

Assets 접근 문제 해결하기

우선 Assets에 더미 데이터를 넣는 것은 안되기 때문에 1차적으로 해당 리소스를 Assets에 두지 않고, 별도의 파일로 추가하는 방식으로 수정했다.

이미지 데이터 렌더링 문제 발생

다음과 같이 번들을 통해 특정 파일의 URL을 가져온 후, 이를 Data로 변환한 뒤 UIImage를 생성해줬다.

1
2
3
4
5
6
7
8
if let url = Bundle.main.url(forResource: "sampleImage", withExtension: "png") {
    do {
        let imageData = try Data(contentsOf: url)
        let image = UIImage(data: imageData)
    } catch {
        print("Error loading image data: \(error)")
    }
}

하지만 이미지가 정상적으로 뜨지 않는 문제가 발생했다.

UIImage(data: )의 data 지원 포맷 차이이 원인

문제 해결을 위해 디버깅을 진행했고, UIImage(data: )가 지원하는 포맷은 비트맵 이미지 형식이고, SVG와 같은 벡터 이미지 포맷은 지원하지 않는다는 점을 알 수 있었다.

비트맵 이미지(PNG, JPEG, GIF, …)

  • 픽셀 단위로 저장된 정적인 이미지

    벡터 이미지(SVG)

  • 수학적으로 정의된 그래픽으로, 별도의 렌더링 엔진이 필요

즉, 번들에서 가져온 이미지가 SVG 파일일 경우, UIImage(data: )를 이용해 로드할 수 없는 아주 정상적인 동작임을 알 수 있었다.

결과

SVG를 바로 UIImage에 사용할 수 있는 새로운 initializer를 만들어준다면 매우 Best한 행동일 것이다. 하지만 프로젝트 마감기한이 얼마 남지 않았고, 아직 MVP가 다 완성되지 않았었기 때문에 이러한 도전을 해보지 못했다 🥲

우선은 PNG 형식으로 리소스를 교체해주는것을 마무리를 하게 됐지만, 이번 트러블슈팅을 통해 Bundle의 동작 방식과 UIImage의 데이터 처리 방식을 명확하게 이해할 수 있었던것 같다.

🔗 레퍼런스

해당 자료를 찾아보며 도움이 됐던 링크

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.