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

iOSアプリのバージョン情報管理について

iOSアプリのバージョン情報

iOSアプリでは、2つのバージョン情報があります。 Xcodeでアプリを新規作成すると、ターゲットのGeneral(一般情報)に、以下のような初期値が設定されているのを、以下の画面で見ることができます。

  • ターゲットの一般情報

f:id:kimada:20170430100710j:plain

  • Info.plist

f:id:kimada:20170430100912j:plain

これらの情報は、開発者がアプリのバージョン情報を管理するのに使えるのはもちろんですが、iTunes Connectを使ったアプリを申請やTestFlightを使ってテストするための、バイナリをアップロード必要な情報となっています。その際に、使用する場面によって名称が異なるので、注意が必要です。

ターゲットの一般情報 Info.plist Info.plist(ソース) iTunes Connect 初期値
Version Bundle versions string, short CFBundleShortVersionString Store バージョン番号 1.0
Build Bundle version CFBundleVersion ビルド 1

開発当初はこれらのバージョン情報をあまり意識する必要はないですが、iTunes Connectにバイナリをアップロードするときには、以下のような制約があるので、適切に管理することが必要になります。

  • Version

AppStoreに表示されるバージョン番号なので、新しいバージョンをリリースするときには、前回より大きな値にしなければならない

  • Build

1つのVersionに対して複数のバイナリをアップロードできるが、同じBuildのものを複数アップロードすることはできない

これらのバージョン情報は、XcodeGUIから手入力で変更できますが、AppleWatchアプリや通知センターウィジェットなど、複数のターゲットが含まれている場合は、結構煩雑になります。agvtoolというコマンドラインツールを使うと、プロジェクト内のすべてのターゲットに一括で設定できるので便利です。

Xcodeでagvtoolを有効化する

まずは、Xcode上でプロジェクトがagvtoolを使えるようにするための設定を行います。 プロジェクトのBuild SettingsVersioningセクションの以下の項目を設定してください。

f:id:kimada:20170430101023j:plain

正しく設定されていれば、以下のコマンドにて、現在設定されてるバージョンが表示されます。

  • Versionの表示
$ xcrun agvtool what-marketing-version
No marketing version number (CFBundleShortVersionString) found for Jambase targets.

Looking for marketing version in native targets...
Looking for marketing version (CFBundleShortVersionString) in native targets...

Found CFBundleShortVersionString of "1.0" in "VersionSettingSample.xcodeproj/../VersionSettingSample/Info.plist" 
Found CFBundleShortVersionString of "1.0" in "VersionSettingSample.xcodeproj/../VersionSettingSampleTests/Info.plist" 
Found CFBundleShortVersionString of "1.0" in "VersionSettingSample.xcodeproj/../VersionSettingSampleUITests/Info.plist"
  • Buildの表示
$ xcrun agvtool what-version
Current version of project VersionSettingSample is: 
    1

agvtoolによるバージョン情報の設定

Versionの設定

Versionは、AppStoreに表示するバージョンの文字列を明示的に設定します。

$ xcrun agvtool new-marketing-version 1.1
Setting CFBundleShortVersionString of project VersionSettingSample to: 
    1.1.

Updating CFBundleShortVersionString in Info.plist(s)...

Updated CFBundleShortVersionString in "VersionSettingSample.xcodeproj/../VersionSettingSample/Info.plist" to 1.1
Updated CFBundleShortVersionString in "VersionSettingSample.xcodeproj/../VersionSettingSampleTests/Info.plist" to 1.1
Updated CFBundleShortVersionString in "VersionSettingSample.xcodeproj/../VersionSettingSampleUITests/Info.plist" to 1.1

Buildの設定

Buildは自分で選んだ値を設定することもできますが、とりあえず単に毎回異なる値が設定されればいいという前提で、ここでは自動でカウントアップする方法を示します。

$ agvtool next-version -all
Setting version of project VersionSettingSample to: 
    2.

Also setting CFBundleVersion key (assuming it exists)

Updating CFBundleVersion in Info.plist(s)...

Updated CFBundleVersion in "VersionSettingSample.xcodeproj/../VersionSettingSample/Info.plist" to 2
Updated CFBundleVersion in "VersionSettingSample.xcodeproj/../VersionSettingSampleTests/Info.plist" to 2
Updated CFBundleVersion in "VersionSettingSample.xcodeproj/../VersionSettingSampleUITests/Info.plist" to 2

Xcode上で確認

Xcodeでターゲットの一般情報が設定したバージョンに置き換わっていることが確認できます。 f:id:kimada:20170430101056j:plain

参考

iOSシミュレータ用にビルドされたアプリを、テスト用に配布する方法

Facebook Login Review

自作のiOSアプリから、アプリ側で自動編集した定型的な内容をFacebookに投稿したい場合、publish_actionsというパーミッションが必要です。

アプリがpublish_actionsを使えるようにするためには、FacebookにLogin Reviewを申請して、承認を得なければならなくなりました。
Login Reviewの申請方法については、以下のページに説明されているので、詳細はそちらを参照してください。

developers.facebook.com

Login Reviewの際には、アプリを使ってFacebook認証をする手順をStep by Stepで、動画も添付して説明することが求められますが、それだけではなく実際に動作するアプリのバイナリを提出することも必須となっています。
iOSアプリの場合は、シミュレータで動作する.appをZIPアーカイブしたものを申請フォームからアップロードします。そのための手順が、以下のページで説明されています。

developers.facebook.com

シミュレータ用にビルドする

ZIPアーカイブの作成

上記では、以下のコマンドで、シミュレータ用にビルドされたアプリのバイナリをZIPアーカイブすることができると説明されています。

$ ditto -ck --sequesterRsrc --keepParent \
`ls -1 -d -t ~/Library/Developer/Xcode/DerivedData/*/Build/Products/*-iphonesimulator/*.app | head -n 1` \
path/to/YourApp.zip

ここで注意しないといけないのは、上記では単純に最後に更新された.appを選択するので、必ずしも目的のものがアーカイブされるとは限らないということです。例えば、WatchKit Extentionが含まれたアプリの場合は、そちらが対象となってしまうことがありえます。
確実に目的のアプリのアーカイブを作成するためには、目的の.appの名前でフィルターする必要があります。

以下に、アプリの.appが、MyTestApp.appの場合の例を示します。

$ ditto -ck --sequesterRsrc --keepParent \
`ls -1 -d -t ~/Library/Developer/Xcode/DerivedData/*/Build/Products/*-iphonesimulator/*.app | grep MyTestApp.app | head -n 1` \
/tmp/simbuild/MyTestApp.app.zip

シミュレータにインストールして実行

次に、ここでできたファイルを、実際にシミュレータにインストールして実行する方法が説明されていますが、その場合には、ZIPアーカイブされていない.appが必要です。上記から、"-ck --sequesterRsrc --keepParent"をはずすと、単なるファイルコピーになるので、まずそれを実行して、動作確認してからZIPアーカイブを作成する方が、手順としては素直な気がします。
尚、コマンドラインからシミュレータを操作する場合は、Facebookの手順で説明されている、phonegap/ios-sim · GitHub が便利なので、それをベースに説明してみます。(iso-simは、Homebrewからも、"brew install ios-sim" で、インストール可能です)

github.com

(1) 目的の.appを、作業用ディレクトリにコピーします。
$ ditto `ls -1 -d -t ~/Library/Developer/Xcode/DerivedData/*/Build/Products/*-iphonesimulator/*.app | grep MyTestApp.app | head -n 1` /tmp/simbuild/MyTestApp.app
(2) シミュレータに登録されているデバイスを確認します。
$ ios-sim showdevicetypes
…
com.apple.CoreSimulator.SimDeviceType.iPhone-4s, 9.1
com.apple.CoreSimulator.SimDeviceType.iPhone-5, 9.1
com.apple.CoreSimulator.SimDeviceType.iPhone-5s, 9.1
com.apple.CoreSimulator.SimDeviceType.iPhone-6, 9.1
com.apple.CoreSimulator.SimDeviceType.iPhone-6-Plus, 9.1
com.apple.CoreSimulator.SimDeviceType.iPhone-6s, 9.1
com.apple.CoreSimulator.SimDeviceType.iPhone-6s-Plus, 9.1
com.apple.CoreSimulator.SimDeviceType.iPad-2, 9.1
com.apple.CoreSimulator.SimDeviceType.iPad-Retina, 9.1
com.apple.CoreSimulator.SimDeviceType.iPad-Air, 9.1
com.apple.CoreSimulator.SimDeviceType.iPad-Air-2, 9.1
com.apple.CoreSimulator.SimDeviceType.iPad-Pro, 9.1
…
(3) 上記の中から、テストするデバイスを選んで、アプリをシミュレータにインストールして起動します。

('com.apple.CoreSimulator.SimDeviceType.iPhone-6s-Plus, 9.1'を選んだ場合の例)

$ ios-sim launch /tmp/simbuild/MyTestApp.app  --devicetypeid 'com.apple.CoreSimulator.SimDeviceType.iPhone-6s-Plus, 9.1' --exit

ここで、正しく実行されることが確認できたら、ZIPアーカイブを作成します。

テスト用に配布する(応用)

あと、これを書きながら気付いたのですが、この方法に従うことで、シミュレータ用に作成されたアプリをテスト用に配布することができますよね。ちょっと動きのイメージを見てもらったりする目的であれば、使えるかもしれませんね。

iOSデバイスのモデル名を取得する

SysStats Monitor / SysStats Lite というアプリでは、実行しているデバイスの名前を取得して表示しています。

f:id:kimada:20141220154635p:plain

実際にシステムから取得できるのは、platform nameと呼ばれる文字列で、上記の例の場合には、"iPad4,4"が該当します。

"iPad mini 2 (Model A1489)"という文字列を得るには、変換テーブルを用意して、読み替えてやる必要があります。

簡単な処理ですが、毎度コピペで作るのは面倒なので、SysStats Monitorで使っていたものを切り出してみました。

自分のアプリで、モデル名を使おうとしている方は、よろしければ、試してみてください。


kimada_p / KIDeviceInfoHelper — Bitbucket

 

READMEにも書いてますが、モデル名は、iOS Dev CenteriOSイメージファイルのダウンロードリンクに表示されている名前をベースにしています。

その命名方式が変わらない限りは、SysStats Monitor / SysStats Liteに表示されるモデル名を見ると、そのデバイスに対応するダウンロードリンクを簡単に見つけることができると思います。

もしも、独自のモデル名を使いたい場合は、中に含まれているモデル名変換テーブルのプロパティリストを編集してください。



VMware Fusion 6.0で、新しいOS X(10.9) VMを作成する方法

VMware Fusionで、OS XVMをかなり簡単に作成できるようになっています。
(注: OS X 10.9 + VMware Fusion 6.0が前提になります)
既存の環境に影響を与えずに、iOS SDK Betaを試してみるなどの場合に便利ですね。

基本的な手順は、以下の通りです。

  1. メニューバーから、[ファイル]>[新規]を選ぶと、仮想マシンを作成ウィザードが開く
  2. 右下の[詳細オプション]を選ぶと、上記の画面に遷移
  3. [リカバリ パーティションから OS X をインストール]を選択し、[続ける]をクリック

詳細は、以下の記事を参照してください。

Creating a new OS X virtual machine from the recovery partition in VMware Fusion 6.0 (2056798) (英語)

ibtoolが突然xibファイルを見つけられなくなったときの対処

ibtoolはNIBファイルをコマンドラインで処理することができる便利なツールです。私は、NIBファイルのローカライズを行うときに、使っていますが、Xcode5.0.1 + Mavericksにしてから、以下のようなエラーで失敗することが、ときどき起きるようになりました。

$ ibtool --strings-file XXXXXXXX.strings --write XXXXXXXX.xib ../English.lproj/XXXXXXXX.xib 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.ibtool.errors</key>
	<array>
		<dict>
			<key>description</key>
			<string>Interface Builder could not open the document "XXXXXXXX.xib" because it does not exist.</string>
		</dict>
	</array>
</dict>
</plist>

もちろん、エラーの原因になっているファイルは存在しています。それにもかかわらず、見つからないと言われている状況です。
残念ながら、原因や再現性はわかっていませんが、とりあえず、エラーを回避する方法を見つけることができたので、書いておきます。

ibtoolを実行すると、バックグラウンドで、ibtooldというプロセスが2つ起動されるようです。これらを強制終了してからもう一度ibtoolを実行すると、正常に処理されました。

私の場合は、とりあえずこの方法で回避できました。
同じような状況でお困りの方は、お試しください。

iOS7で、マルチタスク表示からアプリを終了するときのTips

ホームボタンをダブルクリックして、バックグラウンドで動作しているアプリを終了するときの操作が、大きく変わりました。
基本的な操作については、以下の記事が参考になると思います。

アプリを終了させるときに、SysStats Monitor / Liteと連動させると、少しおもしろい使い方ができるので、紹介したいと思います。

注: ここで紹介している方法は、この記事を書いた時点の、iOS7.0にて有効なものであり、iOS6.1以前のバージョンには適合しませんのでご了承ください。
尚、今後のiOSのバージョンアップによって、ユーザインタフェースが変わった場合にも、適合しなくなる可能性があります。

操作方法

(1) まず、SysStats Monitor または、SysStats Liteを起動します。

注: SysStats Monitor / Liteは、メモリ使用量のグラフをタップすると、グラフの表示形式が変わります。この表示例では、棒グラフ表示になっています。

(2) そのまま、ホームボタンをダブルクリックして、マルチタスク表示にします。


(3) 画面を少し右にスクロールして、SysStats Monitor / Liteが中心になるように、調整します。


(4) すぐ右隣にあるアプリを上にスワイプして、終了させます。

この例では、Safariを終了させています。

(5) SysStats Monitor / Liteの表示がリアルタイムに更新されます。

アプリを終了したことによってメモリ使用量の変化があったかどうかを、確認することができます。
大きな変化が見られる場合は、そのアプリが使用しているメモリーの使用量が多かったことになります。
変化が見られない場合は、そのアプリがすでに終了していたか、メモリー使用量が少なかったかのいずれかです。

(6) SysStats Monitor / Liteをタップして、再表示させます。

アプリを終了したことによって、増加した空きメモリのサイズが表示されます。
(この例では、Safariを終了させたことで、52MBの空きメモリが増えたことを示しています)
注: 空きメモリーの増加量が少ない場合は、表示されません。

(参考情報)アプリケーションプロセスの確認

そのまま、SysStats Monitor / Liteを終了せずに、TabBarの左から2番目の「プロセス」をタップして、プロセス画面を表示させます。

「終了を検知したもの」のリストの中に、終了したアプリのプロセス(この例ではSafari)が表示されます。
ここで、実際のプロセス名を確認することができます。


少しマニアックな操作かもしれませんが、やってみると意外に楽しめるので、ぜひ試してみてください。

Mac Book ProにSSDで、予想を上回る快適な環境に

昨年、MacBook Pro (13-inch, Mid 2012)のHDDモデルを購入しましたが、操作中に頻繁にフリーズにすることに、とうとう我慢できなりました。そこで、SSDに交換してみましたところ、予想を上回る、快適さを手にしました。
最も大きな点は、やはり、パワーオンしてからログインパネルが出るまでの時間が、飛躍的に短縮されたことでしょうか。
あと、目立つところとしては、VMware Fusionのパフォーマンスの向上もありがたいですね。
操作中のフリーズもほとんど起きなくなりました。
至るところで、ハードディスクのIOボトルネックが解消し、CPUの性能がフルに生かされている感じがします。

実際に購入したもの

今回の作業のために実際に購入したものは、以下の通りです。

Samsung SSD840 ベーシックキット500GB MZ-7TD500B

SSDの本体のみです。元のHDDは750GBでしたが、余分なものを削除すれば移行できるので、500MBを選択しました。
SSD840 EVOという新しいものも出たようですが、こちらの方が値段も1万円くらい安いし、そこまでの性能は必要ないと判断しました。

玄人志向 2.5インチ USB3.0接続 ハードディスクケース GW2.5TL-U3/BK

元のHDDを取り外した後に、ここからシステム起動したり、データを移行するときに必要です。移行完了後は、そのまま外付けHDDとして使えます。

アネックス(ANEX) ヘクスローブドライバーT型 T6×50 No.6300

ディスク装置を本体に取り付けるための、支えになるネジを扱うときに、必要になります。
あと、本体のフタを開けるときは、00番のプラスドライバーが必要になります。一般的なドライバーセットに入っていると思いますが、もしも持っていない場合は、それも準備する必要があります。