Swift

프로젝트 리소스(Image, ColorSet 등) 관리하기

papayetoo 2022. 1. 25. 21:46
import UIKit
// 리소스에 접근하기 위해서 R import
import R

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 이미지 접근하기
        self.imageView.image = R.Image.karina
    }


}

프로젝트를 하다 보니 프로젝트 내에 있는 Image 나 ColorSet을 효율적으로 관리하고 싶다는 생각이 들었는데...

 

찾다보니 SwiftGen이라는 리소스 관리 라이브러리? 라는 게 있습니다. 

 

SwiftGen을 사용하면 assets에 있는 Image나 ColorSet을 enum 형태로 만들어서 Image나 ColorSet을 사용하는 데서 발생하는 오류를 줄일 수 있습니다.

 

SwiftGen의 사용법은 추후에 다루겠습니다.

 

SwiftGen을 사용했을 때는 같은 프로젝트 폴더 내에 .swift 파일이 사용되고, 해당 enum을 가져다가 쓰면 ColorSet이나 Image를 쉽게 사용할 수 있습니다.

 

하지만 SwiftGen 말고 brew나 carthage 설치 없이 리소스 파일들을 관리하고 싶은 고민에 부딪혔습니다. 

 

그래서 자주 방문하는 민소네님의 블로그에서 http://minsone.github.io/ios/mac/ios-managing-color-image-storyboard-xib-from-resources-framework 을 보고 이런식으로 하면 좀 더 리소스 관리를 잘할 수 있겠다 싶어 따라하게 되었습니다.

 

1. 샘플로 Bundler라는 프로젝트를 생성하고 그 안에 있는 Assets를 삭제했습니다.

2. 그리고 프로젝트 설정에서 R(안드로이드에서 리소스 관리할 때 쓰는 것과 동일, 다른 이름을 써도 무방)이라는 프레임워크를 추가합니다.

3. R 안에 assets를 추가하고 이름을 Images라고 했습니다.

4. 프로젝트에서 쓰여질 Image를 R의 Images.assets에 추가합니다.

5. 마지막으로 R 이라는 이름의 클래스를 선언합니다. extension에서 static 변수로 해당 이미지에 접근할 수 있습니다.

// 이 코드는 민소네님 블로그에서 본 코드와 동일합니다.
import Foundation
import UIKit

public class R {
    static let bundle = Bundle(for: R.self)
}

public extension R {
    enum Image{}
}

public extension R.Image {
    static var karina: UIImage { .load(name: "Karina")}
}


extension UIImage {
    static func load(name: String) -> UIImage {
        guard let image = UIImage(named: name, in: R.bundle, compatibleWith: nil) else {
            assert(false, "\(name) 이미지 로드 실패")
            return UIImage()
        }
        return image
    }
}

6. 그러면 이미지 리소스에 접근하기 위한 코드는 간단한 형태로 바꿀 수 있습니다.

import UIKit
// 리소스에 접근하기 위한 R 임포트
import R

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 이미지에 접근하기
        self.imageView.image = R.Image.karina
    }


}