Skip to content

다른 Package의 Resource 파일 사용하기

sunghun kim edited this page Jan 26, 2023 · 1 revision

🏠 동네한입 팀에서는 FindTownUI, FindTownNetwork, FindTownCore Package를 만들어 사용중입니다. package 세팅과 관련한 이야기는 Package를 이용한 모듈화를 참고해주세요..!
UI와 관련한 Resource 파일들도 모두 FindTownUI에 빼서 사용중입니다.

스크린샷 2023-01-26 오후 5 16 47
스크린샷 2023-01-26 오후 5 17 48

이렇게 말이죠..! 근데 여기서 한가지 문제점이 발생합니다. FindTownCore에서 FindTownUI의 Resource 파일을 사용해야하는 상황이 생겼습니다..


일단 급한대로..

스크린샷 2023-01-26 오후 5 30 11

분명 FindTownCore Package에서 FindTownUI를 target으로 추가를 시켜줬음에도 불구하고

스크린샷 2023-01-26 오후 5 35 39

FindTownUI Resource에 있는 Back Image를 불러올 수 없었습니다..


이리저리 해보다가 도저히 안되겠다 싶어서 우선 급한대로 FindTownCore에도 Resource 파일을 만들어서 세팅을 했습니다.

스크린샷 2023-01-26 오후 5 38 38
스크린샷 2023-01-26 오후 5 38 41
스크린샷 2023-01-26 오후 5 38 49

그리고 울며 겨자먹기로 작업을 하고 PR을 날렸습니다.

스크린샷 2023-01-26 오후 5 42 53

그래서 이거 맞아..?

이 PR 이후에 이슈에 이 친구가 새롭게 등장했습니다.

스크린샷 2023-01-26 오후 5 45 23

Back Image 하나 때문에 FindTownCore에 Resource를 만들어야하는.. 대충 봐도 틀렸다. 라는 생각이 드는 상황입니다..

그래서 '해결하자' 라는 마음을 가지고 다시 살펴봤습니다.

해결방법

우선 FindTownCore와 FindTownUI는 다른 공간(다른 모듈)에 위치하고 있어 따로 Bundle 작업이 필요했습니다.

사실 target만 설정하면 전부 사용할 수 있을 줄 알았는데 Resource는 그게 안되나 봅니다..

제가 찾은 방법은 총 2가지 였습니다.

첫 번째는 FindTownCore에 FindTownUI Bundle을 직접 만드는 방법입니다.

// in FindTownCore

private class BundleFinder {}

extension Foundation.Bundle {
    static var module: Bundle = {
        let bundleName = "FindTownUI_FindTownUI"

        let candidates = [
            Bundle.main.resourceURL,
            Bundle(for: BundleFinder.self).resourceURL,
            Bundle.main.bundleURL,
        ]

        for candidate in candidates {
            let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle")
            if let bundle = bundlePath.flatMap(Bundle.init(url:)) {
                return bundle
            }
        }
        fatalError("unable to find bundle named BioSwift_BioSwift")
    }()
}

// use

let backButtonImage = UIImage(named: "Back", in: .module, compatibleWith: nil)?.withAlignmentRectInsets(UIEdgeInsets(top: 0.0, left: -8.0, bottom: -8.0, right: 0.0))

FindTownUI에서 bundle을 가져오고 module이라는 이름으로 새로운 bundle을 만들어줍니다.

그럼 이제 in: ... 부분에 없었던 .module이 생기고, 이 친구를 넣어주면 정상적으로 Back Image가 출력이 됩니다..!!


두번째 방법은 FindTownUI에서 FindTownCore에서도 사용할 수 있도록 Bundle extension 만드는 방법입니다.

// in FindTownUI

extension Bundle {
    public static var FindTownUI: Bundle = .module
}

// use (FindTownCore)

let backButtonImage = UIImage(named: "Back", in: .FindTownUI, compatibleWith: nil)?.withAlignmentRectInsets(UIEdgeInsets(top: 0.0, left: -8.0, bottom: -8.0, right: 0.0))

FindTownUI에서 bundle extension을 만들어 다른 모듈에서도 접근가능하도록 만드는 겁니다..!!

그럼 첫 번째 방법이랑 똑같이 in: ... 부분에 만들어놓은 이름으로 module이 생기고 정상적으로 Back Image가 출력이 됩니다..!


첫 번째 방법은 FindTownUI Resource를 사용하려는 모듈마다 만들어줘야하는 반면 두 번째 방법은 FindTownUI에서 만들어놓으면 어디서든 접근이 가능하고 코드의 양도 엄청나게 차이가 나기 때문에 두 번째 방법을 채택하여 코드를 수정했습니다..!


[참고]

Bundling resources with a Swift package

How to access the bundle when using Swift Package Manager

Bundling Resources with a Swift Package

Clone this wiki locally