Section 10/181 menit

10. Resource Handling Lanjutan

10. Resource Handling Lanjutan

Process vs Copy

swift
// Package.swift — dua cara menangani resources
.target(
    name: "MyApp",
    resources: [
        // process(): SPM akan memproses file sesuai tipenya
        // - .plist → dikompilasi ke binary format
        // - .storyboard, .xib → dikompilasi
        // - .xcassets → dikompilasi ke .car
        // - file lain → di-copy as-is
        .process("Resources/"),
        
        // copy(): selalu di-copy apa adanya, tanpa processing
        // Gunakan untuk file yang butuh path exact atau format tertentu
        .copy("Data/config.json"),
        .copy("Certificates/")
    ]
)

Mengakses Resources dari Kode

swift
// Mengakses resource via Bundle.module (generated oleh SPM)
public struct ResourceLoader {
    
    // Akses file dari bundle
    public static func loadJSON<T: Decodable>(named filename: String, as type: T.Type) throws -> T {
        guard let url = Bundle.module.url(forResource: filename, withExtension: "json") else {
            throw ResourceError.fileNotFound(filename)
        }
        let data = try Data(contentsOf: url)
        return try JSONDecoder().decode(type, from: data)
    }
    
    // Akses image
    public static func image(named name: String) -> UIImage? {
        UIImage(named: name, in: Bundle.module, compatibleWith: nil)
    }
    
    // Akses string dari Localizable.strings
    public static func localizedString(_ key: String) -> String {
        NSLocalizedString(key, bundle: Bundle.module, comment: "")
    }
    
    // Akses asset catalog color
    public static func color(named name: String) -> UIColor? {
        UIColor(named: name, in: Bundle.module, compatibleWith: nil)
    }
    
    enum ResourceError: Error {
        case fileNotFound(String)
    }
}

Localization di SPM Package

swift
Targets/
└── MyFeature/
    ├── Sources/
    │   └── MyFeature.swift
    └── Resources/
        ├── en.lproj/
        │   └── Localizable.strings
        ├── id.lproj/
        │   └── Localizable.strings
        └── ja.lproj/
            └── Localizable.strings
swift
// Package.swift — aktifkan defaultLocalization
let package = Package(
    name: "MyFeature",
    defaultLocalization: "en",  // wajib jika ada .lproj
    targets: [
        .target(
            name: "MyFeature",
            resources: [.process("Resources/")]
        )
    ]
)