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

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を作成する方法

MacOSX 技術情報

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ファイルを見つけられなくなったときの対処

iPhone技術情報

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

iOS7 SysStats Lite SysStats Monitor

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

アプリを終了させるときに、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で、予想を上回る快適な環境に

Mac

昨年、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番のプラスドライバーが必要になります。一般的なドライバーセットに入っていると思いますが、もしも持っていない場合は、それも準備する必要があります。

PhoneGapを使ってみた

iPhone技術情報 ハイブリッド

最近は、HTML5で作られたモバイル向けWebアプリケーションをベースに、ネイティブアプリケーションを開発する、ハイブリッド型のアーキテクチャを採用するケースも増えてきているようです。
今さらですが、とりあえず、その代表的なプラットフォームであるPhoneGapを使ってみようと思いたち、最近のバージョンをベースに簡単に日本語で説明されている記事を探してみましたが、見つからなかったので、PhoneGapのサイトにある「Getting Started with iOS」を参考に、少し触ってみました。

Getting Started with iOS

インストールから、HelloWorldアプリケーションを動かすところまでの手順が説明されています。
ここでは、簡単に、そこで説明されている手順をたどってみます。

Requirements

実機を使用しないのであれば、事前に準備しておく必要があるのはは、Xcodeのみですが、ここで説明されている通り、Xcode Command Line Toolsをインストールしておく必要があります。

Install Cordova

以下のページから最新版をダウンロードして、任意の場所に展開します。
http://phonegap.com/download/

注: この記事を書いた時点の最新版は2.8.0ですが、私が試したところでは、Camera APIの一部の機能が正しく動作しなかったので、2.7.0を使っています。

Project Creation
  • Determine Project Location

このチュートリアルで作成するHelloWorldプロジェクトを配置するディレクトリを準備します。

$ mkdir ~/Documents/Cordova27
  • Open Terminal

説明の対象になっているバージョンが2.3.0となっていますが、現在はディレクトリ構成が変わっており、phonegap-2.7.0/lib/ios/bin になっているようです。
ターミナルを開いて、そのディレクトリに移動しておきます。

  • Create New Project

HelloWorldプロジェクトを作成します。

$ ./create ~/Documents/Cordova27/HelloWorld org.apache.cordova.HelloWorld HelloWorld

プロジェクトをXcodeで開くことで、実行することができます。


オプション: Camera APIのサンプルを実行してみる

HelloWorldだけでは面白くないので、もう少しPhoneGapの機能がわかるサンプルを実行してみましょう。
PhoneGapのアプリケーションは、UIWebViewにHTMLをロードすることで実行されます。デフォルトでは、作成されたプロジェクトのwww/index.htmlがアプリケーション起動時に実行されるスタートページとして設定されています。その指定は、config.xmlというファイルで行われています。

    <content src="index.html" />

通常、独自のアプリケーションを作成するときには、このindex.htmlを置換えることになります。とりあえず、PhoneGapのドキュメントに記載されている、Camera APIのサンプルを実行してみましょう。

以下の場所にある、「Full Example」の内容をコピーし、index.htmlにペーストして置換えてください。
http://docs.phonegap.com/en/2.7.0/cordova_camera_camera.md.html#camera.getPicture_full_example

Xcodeから実行すると、以下の画面に置き換わっているはずです。

デバイス固有の機能は、deviceReadyイベント後でないと使用できないので、最初は各ボタンを無効にしておいて、deviceReadyが来たら有効にするといった処理を付け加えてもいいかもしれません。

        <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>

            // Cordova is ready to be used!
            //
            function onDeviceReady() {
                pictureSource=navigator.camera.PictureSourceType;
                destinationType=navigator.camera.DestinationType;
                $(".camerabutton").removeAttr("disabled");
            }

    <body>
        <button class="camerabutton" disabled onclick="capturePhoto();">Capture Photo</button> <br>
        <button class="camerabutton" disabled onclick="capturePhotoEdit();">Capture Editable Photo</button> <br>
        <button class="camerabutton" disabled onclick="getPhoto(pictureSource.PHOTOLIBRARY);">From Photo Library</button><br>
        <button class="camerabutton" disabled onclick="getPhoto(pictureSource.SAVEDPHOTOALBUM);">From Photo Album</button><br>
        <img style="display:none;width:60px;height:60px;" id="smallImage" src="" />
        <img style="display:none;" id="largeImage" src="" />
    </body>

注:
iOS Simulatorで実行する場合には、カメラの撮影機能を動作させることはできませんのでご了承ください。
フォトアルバムに写真が入っていない場合は、事前に登録しておく必要があります。登録方法は、以下の記事が参考になるかと思います。
iPhoneシュミレータに画像を登録する方法 - satoko's blog - s21g




JavaScriptから簡単にネイティブの機能が使えるので、たしかにObjective-Cは知らなくても、iOSアプリケーションが作れてしまいますね。
尚、今回は、とりあえず使ってみることが目的だったので、UIについては二の次になっています。実際のアプリケーションでは、jQuery MobileSencha Touchといった、モバイルWebアプリケーションフレームワークと組合せることで、もっと洗練されたUIを実現することになります。そのあたりも面白そうなので、また時間があるときに調べてみたいと思います。