Sparkleでバイナリ差分更新が失敗する時の対処方法

Macアプリのバージョンアップを管理・実行してくれるフレームワークのSparkleを使ってみました。ドキュメントを読みながら、試行錯誤しつつ組み込んでいきましたが、バイナリの差分更新(Sparkle用語ではBinary Delta Updates)が失敗し四苦八苦しました。その原因がわかったので、まとめておきます。また、配布に  DMGファイルを使っていると、generate_appcastツールがappcastファイルの作成に失敗する原因もわかったので合わせて書いておきます。

バイナリ差分更新の失敗の原因と対処

原因

アプリの名前(CFBundleName /CFBundleDisplayName)をローカライズしていて日本語名にしていたことが原因でした。この日本語名が濁点を含んでいて、ファイルシステムが保持する時に文字コードが変換されるらしく、CFBundleNameを定義する時にことえりで入力した文字コードと異なっていたため、Sparkle内で不整合が起こって実際のバイナリ差分更新には成功するものの、その後の確認(verification)処理で失敗して、バイナリ差分更新処理が失敗となってしまっていました。

CFBundleName: エンジン
Hex:

0xE30x820xA80xE30x830xB30xE30x820xB80xE30x830xB3

ファイルシステム: エンジン
Hex:

0xE30x820xA80xE30x830xB30xE30x820xB70xE30x820x990xE30x830xB3

対処

3通りのやり方があります。

  • CFBundleName /CFBundleDisplayNameをローカライズしない
  • ファイルシステムが保持してる名前を使用する
    [[NSFileManager defaultManager] stringWithFileSystemRepresentation:]

    上記のコードで実際の文字(コード)を取得してCFBundleName /CFBundleDisplayNameのローカライズにコピペして使う。

  • Sparkleのバージョンアップを待つ
    issueとして報告したところ、バージョン1.7で修正されるそうです。

appcast.xmlの作成に失敗する原因と対処

原因

DMGファイルに/Applicationsのエイリアスを入れていたのが原因でした。

generate_appcastのバグで、配布用のアーカイブファイルには、.appしか入っていないという前提で処理がされていました。

ドキュメントに、「DMGファイルには/Applicationsのシボリックリンクを入れること」と書かれているので、Sparkleを使うためには必須なのかと思っていたのですが、どうやらTips的に書いてあるだけのようです。generate_appcastツールの本来の処理としては、/Applicationsのエイリアスがあろうがなかろうが全く関係ないです。

対処

こちらもissueとして報告したら、すぐに(バージョン1.6.xで)反映されるとのことでした。

あとがき

バイナリ差分更新の失敗の方は、Xcodeのdebugログや、この記事で表示されてる文字は、見た目は同じに見えます。しかし、いつもメモ帳代わりに使っているSublime text 3にdebugログを貼り付けて眺めていたら、ファイルシステムの方は、「エンシ ゛ン」のように濁点が1文字として表示されてびっくりしました。テキストエディットや私が持っている他のテキストエディタでは全く同じに見えます。文字コードの処理についてはよくわかりませんが、とりあえず、Sublime text 3使っててよかった!優秀!

フリーウェアを使っておきながら、それを使ったアプリをこれから有料販売するのに少し後ろめたい気がするのですが、不具合報告で貢献活動をしたと自分自身の気持ちに整理をつけ、関係者やこれからアプリを購入される方にご容赦願いたい次第です。