読者です 読者をやめる 読者になる 読者になる

たごもりすメモ

コードとかその他の話とか。

ソースコードビューア GlassDolphin for iPad/iPhone 本当に完成!(しかしreject)

GlassDolphin

前々から作成していたソースコードビューア "GlassDolphin" ですが、先週の土曜(8月21日)に完成の末、AppStoreの審査についに提出いたしました! 以下並べるのがAppStore用のスクリーンショットです!



ですがrejectされました!

もうしばらくお待ちください。 orz

まあそれだけではなんなので、まず簡単に。

rejectの理由になったのは、調査したところSDKに含まれる libarchive.dylib の使用によるもののようです。これはSDKに含まれるがOS APIマニュアルには載っていないもので、まあアウト判定されたら文句の言えない範疇のものではありました。zip/tar.gz/tar.bz2の展開はこのライブラリに頼っていたため、アプリの基本機能の動作に問題が出ました。このままリリースしても、展開できないアーカイブファイルをダウンロードするだけの面白アプリでしかありません。
いっぽう世間にはzipファイルを扱えるアプリというのはかなりの数が出回っており、ものの本によるとzlib(libz.dylib)を使用するのがセオリーのようです。が、このzlibもSDKに含まれるもののOS APIマニュアルには載っていない類のもので、こっちがOKでlibarchiveがダメな理由が自分にはわかりません。まあAppleの言うことですしねえ。

でzipのみ(およびsvn/gitエクスポート)をターゲットにしてアプリをとりあえず出す、という選択肢もありましたが、自分の感覚として「ソースコードビューアが tar.gz/tar.bz2 を展開できないのはありえない」と思われたため、とにかくどうにかしてこの書庫ファイルに対応し、その後にリリースすることにしました。
いくつか実装方法の選択肢はあります(後述)が、どれにしても即日リリースということにはいかなさそうです。お待ちいただいている方がいらっしゃいましたら、もう少々お待ちください。早ければ9月第一週のうちには再度AppStoreへ提出できると思います。

で、細かい経緯。

経緯

先日作成・配布したbeta2は問題なく動作するものでした。AppStoreへの各種手続も順次やって最後までやりました。
バイナリをアップロードしたところ "Invalid Binary Architecture" というrejectメールが約2時間で来ました。これも最初は解決方法がよくわかりませんでしたが、結局ビルドオプションの armv6/armv7 を両方指定するか、もしくは armv7 のみ指定して Info.plist*1 に "UIRequiredDeviceCapabilities" なるキーと値(armv7)を入れればよい、ということはわかりました。*2

で、その後に起きたのが、いったん "Waiting For Review" になって2時間後*3に受け取った以下のメール。

GlassDolphin cannot be posted to the App Store because it is using private or undocumented APIs:

Spi Symbols:


As you know, as outlined in the iPhone Developer Program License Agreement section 3.3.1, the use of non-public APIs is not permitted. 
Before your application can be reviewed by the App Review Team, please resolve this issue and upload a new binary to iTunes Connect.

メールの文面自体は話によく聞くundocumented APIの使用でのrejectを示している。が、分からないのは "Spi Symbols:" という言葉で、意味がまったく思い当たらないし、ぐぐっても出てこない。いや正確には出てくるのだが、そのあたりだと "Spi Symbols" に続けて

Spi Symbols:
__memset_chk
__memmove_chk

These symbols appear in a small number of object files:
 * Grid.o
 * Primitives.o
 * TextureAtlas.o

みたいな説明のあるものばかりだ。しかし自分の受け取ったものには無い。(そして怪しげな空行だけがある。)
わかんねえよコレじゃあ! とキレかかっても不思議ではあるまい。

調査

とりあえず「これじゃあ何がなんだかわからん。教えろ。」とテキトーな英語で返信しておいたが、どうせ彼らは読んじゃいるまい。自分で調査するより仕方がないように思われたので、いくらかやってみた。
まずはとにかくビルドオプションを変えるというもので、デバッグシンボルの出力を極力なくしてみたり、余計なアーキテクチャのバイナリ(armv6のことだ)を外してみたり、あれこれやった。全部ダメだった。

自分で言うのもなんだがUI作成の部分は極力iPhone/iPadの常識に則ったつもりで、un-documentedなAPIを触ったつもりなど微塵もない。
じゃああとはどこが、というと libarchive しか心当たりが残ってない。zlibが通るんだから大丈夫だろ、とか思って使っていたんだが、ダメと言われるとうーんという感じだ。zipを扱えるアプリが世の中にあれだけあるのにtar.gz/tar.bz2を扱うものを一度も見たことがないのはそういうわけだったのだろうかまさか。えええー。
ともあれ実証してみるしかないな、ということで、コードから libarchive を使っている部分*4を丸ごとコメントアウトして、コンパイルに支障のないようダミーのデータを返すコードに差し替えてみる。んで libarchive.dylib をプロジェクトから除外。(zlibは残ったまま。)

で、アップロードしてみた。問題の2時間が経過した。rejectされない…… orz

20時間ばかり放置してみたが "Waiting For Review" のまま。多分機械的にチェックしているのは通って、人間のチェック待ち状態になったんだろう。どうせほとんど動かないアプリなので、開発者としてアプリの取り下げを行った。

改善案

明日明後日で突然 libarchive の使用をApple様がお認めになる可能性などゼロに等しいし待っててもしょうがないので、どうにか方法を考えないといかん。方法は主に以下のみっつ。

  1. 扱えるアーカイブ形式を zip ファイルのみに限定
    • 世の中のアプリの状況を見てると zlib の使用は通ると思われる。この改修方法であれば審査を通過する可能性は高い。ただし、蹴られても文句を言えない、という可能性も残っている。これで蹴られたら最悪な感じ
  2. tar.gz/tar.bz2も扱うが、変換サーバを通してzipに直してからダウンロードさせる
    • 現状の svn/git ダウンロードと同じで、変換サーバ側でいちどダウンロードし、zipファイルで固め直した上で端末にダウンロードさせる。改修コスト自体はおそらくほとんどない(svn/gitと同等、2日程度で終わる)ものと思われる。どっちにしろ書庫ファイルの展開は zlib に頼ることになり、上の選択肢と同じリスクは抱えることになる。まあ通れば上の案よりはユーザにとってかなりマシ。
  3. libarchiveに頼らずtar.gz/tar.bz2を展開するライブラリを自作する
    • 自作、といってもlibarchiveの移植になるだろうけど。しかも読み込みに特化させて。読み込みに特化、アーキテクチャの汎用化も考えない、となれば移植自体は不可能ではないだろうけど、時間と手間はかかるし、安定性や速度で libarchive を簡単に上回れるとはとても思えない。日数はかかるが、ただ使い勝手としてはいちばんいいものになると思う。

ぶっちゃけ、zipに限定してしまうのが一番ラクで、多分けっこうすぐにできると思う。それでもrejectされる可能性はあると書いたが、世の中でこんだけ出回ってるんだから多分大丈夫なんだろ。Twitterで聞いてみたところ、zipだけでもあれば、という意見はけっこう来た。
たださー、zipだけでもって意見はだいたい条件付なんだよね。Windowsであれば、Javaであれば、ひとまずなら、……。自分の経験則として、使い勝手が最初にあまり良くなくても我慢してもらえるけど、機能として必須だと使う側が思ってるのにそれが満たされてないって、最悪なんだよな。一撃で使うのをやめるレベル。そして多分二度と戻ってこない。
自分でもじっくり考えてみた。で、思った。ソースコードビューアが tar.gz/tar.bz2 を扱えない、ってのはありえない。それは無しだ。そして、自分で無しだと思うような状態のアプリをAppStoreに出すなんてありえない。

そんなわけで tar.gz/tar.bz2 の展開ができるまではリリースしないと決めたが、方法として2番目(変換サーバ)と3番目(独自実装)のどちらを取るかはまだ決めてない。手早く出すことを重視するなら2番目、手堅く行くなら3番目かな。ただし3番目だと、正直リリースできるのがいつになるのかまったくわからなくなる。
だから多分、当面は2番目の方法になると思う。これだと svn/git と同じく THE INTERNET 上のものしかダウンロードできなくなるが、ローカルネットワーク上のものなら、多分利用者自身で zip で再アーカイブするのは難しくないでしょう。

そんな感じで。今週末は自転車のレースがあるので作業は無理。来週の平日に改修をやって、早ければ9月1週目のうちに再度提出できると思う。

あーもー。あれだ。
Appleのばかやろーっ。

*1:これってiOS SDKの開発でみんな気軽に言うけど、Xcode上では #ProjectName#-info.plist というファイルで、ビルド後に Info.plist になるんだよね。どこにも書いてなくて戸惑ってたけど、ビルドしたら初めてわかった。iOS SDKの開発本なんかはこの類の不親切がすごく多い。

*2:armv6をオプションに入れた状態でビルドすると、不要なアーキテクチャは外せ、て警告が出るんだよね。だから外してたら「外すなら UIRequiredDeviceCapabilities を指定しろ、と言われてreject。まったくもう。

*3:何度も繰り返したが、毎回きっかり2時間後にメールが来る

*4:改めて見直してみると、すごいイイ感じに局所化してあった。俺えらい!