iOS
ライブラリ
Swift

自作ライブラリでリソースを扱う時に躓いたこと

自分で Cocoa Touch Framework を作った時に、実装面で躓いたことについてメモしておこうと思います。ライブラリでリソースを使うことはそんなにないと思いますが参考までに。

躓き1:画像が取得できない

Assetsに画像ファイルが存在していてかつ画像名も合っているはずなのに、UIImageがnilになってしまうということがありました。

ライブラリ内のswiftファイル
// assetにhogeという名前のimageはあるのにnilになる
let image = UIImage(named: "hoge")

どうしてだろうかと調べているうちにここらへんのstackoverflowに辿り着きました。
https://stackoverflow.com/questions/26782706/cocoa-touch-framework-assets-not-visible-in-app-project
https://stackoverflow.com/questions/25739762/load-image-from-ios-8-framework

先の呼び出し方だと内部的に main bundle を呼び出しており、framework の bundle を呼び出してくれないとのことなので、 bundle を指定する必要があります。ということで雰囲気こんなかんじのクラスを作りました。

final class FrameworkImage {
    static func getImage(name: String) -> UIImage? {
        return UIImage(named: name, in: Bundle(for: self), compatibleWith: nil)
    }
}

なので呼び出し側はこのようになります。

let image = FrameworkImage. getImage(name: "hoge")

躓き2:ローカライズファイルが読み込めない

もう一つの躓きはローカライズファイルです。通常と同じようにLocalizable.stringsを作って呼び出してみるものの、ローカライズされてくれません。

ライブラリ内のswiftファイル
// Localizable.stringsはあるのに翻訳されない
let localizedString = NSLocalizedString("key_string", comment: "")

こちらも同様に bundle が原因でした。

https://stackoverflow.com/questions/2335664/localization-of-strings-in-static-lib

ということで雰囲気こんなかんじのクラスを作りました。

final class LocalizedString {
    static func localizeString(str: String) -> String {
        return NSLocalizedString(str, tableName: nil, bundle: Bundle(for: self), value: str, comment: "")
    }
}

呼び出し側はこのようになります。

let localizedString = LocalizedString.localizeString(str: "key_string")