しおメモ

雑多な技術系ブログです。ニッチな内容が多いです。

Swiftで作成したiOS向けframeworkをローカライズする

普通のアプリの場合は、NSLocalizedStringにキーを渡すだけで大丈夫なのですが、frameworkを公開する場合、デフォルトだとアプリ側のBundleを参照してしまうので、そちらも正しく指定しなくてはいけません。
情報が少なかったので、その方法を記載しておきます。

やること

普通のアプリと同じように、Localizable.stringsを用意します。
Base.lprojを上手く作ってくれない場合があるかもしれませんが、手動で作ればプロジェクトが読み込んでくれます。

f:id:scior:20190202183509p:plain

そのままBundleを指定せずに、NSLocalizedStringを呼んでしまうと、Bundle.mainの方を呼んでしまうので、Bundle Identifierから参照するようにします。

f:id:scior:20190202183820p:plain

上の部分を参照して、

Bundle(identifier: "com.flyingalpaca.Uppsala")

のように取得します。
自分はローカライズの部分までまとめて、extensionにしました。好みでcomputed propertyにしてもいいと思います。

extension String {
    func localized() -> String {
        guard let bundle = Bundle(identifier: "com.flyingalpaca.Uppsala") else { return self }
        return NSLocalizedString(self, tableName: nil, bundle: bundle, comment: self)
    }
}

すると、このような感じで呼べます。

"update_notification_title".localized()

サンプル

実際に使うときは、このようにenumのメソッドでさらにラップして使っています。

public class Dialog {
    /** いろいろ */
    public init() {
        title = LocalizedStringKeys.notificationTitle.localized()
    }
}

fileprivate extension Dialog {
    enum LocalizedStringKeys: String {
        case notificationTitle = "update_notification_title"
        case notificationMessage = "update_notification_message"

        func localized() -> String {
            return self.rawValue.localized()
        }
    }
}

Swift4で範囲の文字列表現をRangeに落とし込む

正確には、RangeExpressionのような、containsで要素を含むかどうかを判定できる適当なクラスに落とし込みます。
今回はRange(0.0...1.0みたいなやつ)だけではなく、RangeExpressionに適合するのすべてのクラスに対応したいと思います。 Swift4.2からRange系が変わっているようなので、それに則ります。

  • やりたいこと
  • RangeExpression
  • GeneralRangeの実装
  • Parserの実装
    • RangeParsableの定義
    • parseの実装
  • Dateで使ってみる
    • RangeParsableの追加
    • 実際にパース
  • 最後に
続きを読む

xargsの-Pオプションでコマンドを並列実行する

シェルだけで簡単にコマンドを並列実行するのに、xargs-Pオプションがあります。
GNU Parallelも便利ですが、そちらはmacユーザーだと別途インストールが必要なので、こちらを紹介します。


使い方

xargs -Pn

-Pで並列実行の最大のプロセス数を指定します。
GNU版の場合、-P0で自動で最大限のプロセスを指定してくれますが、macなどBSD版の場合、n>0の制約がついています。

活用例

例1. 一括画像リサイズ

find . -type f -name "*.jpg" | xargs -I@ -P8 convert -resize 100x100 @ @

Imagemagickと組み合わせて、画像を一括リサイズします。

例2. 連番ダミー画像生成

seq 1 100 | xargs -I@ -P8 convert -size 600x600 -pointsize 150 -gravity Center label:No.@ @.jpg

またImagemagickの例になってしまうのですが、大量に画像を生成する時なども効率的です。

例3. 動画の変換

find . -type f -name "*.MOV" | xargs -I@ -P8 ffmpeg -i @ -vf scale=320:-1 -r 15 @.gif

ffmpegとも相性がいいです。

おわりに

簡単な画像処理などは、Photoshopバッチ処理や、Pythonなどで書くよりも断然楽をできると思います。
その他、wgetcurl等と組み合わせて、画像のクローリングなどにも使用できますが、サーバーに負荷がかかってしまうので、その場合はプロセスを増やしすぎるのはお勧めできません。