かみやんの技術者ブログ

主にプログラムの話です

技術者向け iOS5 新機能!

iOS5でましたね〜〜。iPhone4Sは、2011/10/14発売でしたが、私はSoftbankショップで事前予約して10/17に手に入れました〜。いじりながらニヤニヤ。嬉し〜〜。俺が買ったからキミも買え!
iOS5公開ともにこのエントリを書こうと思っていたけどiPhone4Sリリースとともに忙しくて遅れました。今回の目玉はiCloudですね。
では、いつものごとく iOS Dev CenterのiOS5の新機能の適当訳を書きます。

iOSデータストレージガイドライン

iCloudWiFiを使ってiOSバイスを毎日自動的にバックアップする機能があります。アプリのホームディレクトリの中で、アプリ実行ファイル、キャッシュディレクトリ、tempディレクトリ以外のすべてのファイルがバックアップされます。購入した音楽、アプリ、本、カメラロールの写真、デバイスの設定、ホーム画面、アプリの構成、メッセージ、着信音もバックアップされます。ワイヤレスでiCloudにバックアップされるため、アプリでのデータサイズは最小にする必要があります。大きなファイルサイズは、バックアップ時間が伸び、iCloudのストレージも浪費します。
効率的にバックアップするために、次のガイドラインに従ってください。

  1. ユーザが作成したデータやドキュメントは<App_Home>/Documentsに置いてください。
  2. 再びダウンロード可能なデータは、<App_Home>/Library/Cachesディレクトリに置いてください。データベースキャッシュファイルなどのキャッシュや雑誌、新聞、地図などダウンロード可能なコンテンツはここに置いてください。
  3. 一時的に使うデータは、<App_Home>/tmpに置いてください。iCloudにはバックアップされません。ただファイルの削除もしてデバイスのストレージを消費し続けないようにしてください。

iCloud Storage APIs

iCloudストレージAPIはアプリがユーザのドキュメントやデータをサーバに置いたり、それらをユーザの全てのコンピュータやiOSバイスでアクセス機能を提供します。iCloudユビキタスに使ってユーザのドキュメントを作ることは、明示的にファイルをシンクしたり転送したりせずに全てのデバイスで見たり編集できることを意味します。ユーザのiCloudアカウントのドキュメントの保存により、そのユーザのセキュリティ層も提供します。たとえユーザがデバイスを紛失しても、もしiCloudストレージにそのドキュメントがあれば、そのデバイスのドキュメントは消失しなくてすみます。
iCloudストレージのメリットをアプリが得る方法は2つあります。それは利用方法によります。

  • iCloudドキュメントストレージ:ユーザドキュメントやデータを使う機能
  • iCloudキーバリューデータストレージ:アプリのインスタンス間で小さなデータを共有する機能

多くのアプリはドキュメントをユーザのiCloudアカウントで共有するためにiCloudドキュメントストレージを使うでしょう。ユーザは、iCloudストレージを意識しながら使う形です。ユーザは、ドキュメントがデバイス間で共有され、デバイスで管理することを意識します。それに対し、iCloudキーバリューデータストアは、ユーザは意識しません。それは同じアプリの別のデバイスインスタンス(訳注:インスタンスは、インストールされたアプリを指す)と数十kbytes以下ぐらいの小さなデータを共有する方法です。アプリは重要な状態情報を保存するためにこの機能を使うことができます。例えば雑誌アプリは、ユーザが読んだ最後の本の最後のページを保存するでしょう。株価アプリは、ユーザが注目している株の銘柄を保存するでしょう。

iCloudバックアップ

ユーザはアプリとアプリのデータをiCloudアカウントに直接バックアップすることができます。それはアプリを最新の状態にリストアするのを容易にします。iCloudにバックアップされたデータがあるとユーザは新しいデバイスや既存のデバイスに再インストールするときに簡単になります。しかし、iCloudアカウントの容量は限りがあるため、アプリはファイルをどこに保存するかについて選択可能にしなければなりません。
アプリのホームディレクトリにあるファイルはバックアップされ、それ以外の場所はバックアップされません。ユーザのコンピュータにバックアップされるファイルは、iCloudにワイヤレスでもバックアップします。Documentsディレクトリの全てのファイルとLibraryディレクトリの多くのファイルはバックアップ対象です。iCloudアカウントのデータを最小にするためディベロッパーは、簡単に再作成できたり、他の方法で取得できるデータなら Library/Cachesディレクトリに多くのファイルを置く必要があります。
備考:iCloudストレージAPIを使って明示的に保存したアプリのドキュメントはバックアップされません。これらのドキュメントはiCloudアカウントに既に保存されているため、別途バックアップする必要はありません。

自動リファレンスカウンタ

自動リファレンスカウンタ(ARC)はObjective-Cのオブジェクトのライフタイム管理のプロセスを簡単にするコンパイラレベルの機能です。オブジェクトのretainやreleaseの代わりにARCはオブジェクトのライフタイム要求を評価し、自動的にコンパイル時に妥当なメソッドを挿入します。
この機能をオンにすると、ARCはいくつかの制約を課します。

  • retain, release, autorelease, deallocをコードでコールしてはいけません。さらにretainやreleaseをカスタム実装(訳注:オーバーライド)してはいけません。releaseをコールしてはならないため、deallocもカスタム実装をする必要がなくなる場合がよくあります。コンパイラインスタンス変数の所有関係を解放する必要があるものすべてを管理します。もし他のリソースの管理をしたいときは、deallocをカスタム実装できます。
  • C言語の構造体にオブジェクトのポインタを保持できません。構造体の代わりに他のオブジェクトの中にオブジェクトのポインタを保持します。(訳注:ここでいうオブジェクトは、Objective-Cのオブジェクトと思われる)
  • idからvoid*のキャストなどのようにオブジェクトから非オブジェクトへの直接のキャストはしてはいけません。オブジェクトのライフタイムについて特別な関数やキャストを使ってコンパイラに伝えなければなりません。Objective-CからCore Foundationオブジェクトのキャストでもこれらを使う必要があります。
  • NSAutoreleasePoolは使ってはいけません。その代わりに、autoreleaseブロックの開始位置を示すために@autoreleasepoolキーワードを使う必要があります。下記のサンプルのように、中カッコで囲います。
@autoreleasepool
{
    //Your code here
}

ARCは、プログラマにretainやreleaseを考えさせるよりもオブジェクト間のオブジェクトグラフと関連を意識させます。ARCはゼロウィークリファレンス(ゼロ弱参照)を含むオブジェクトに対するライフタイムの修飾子を新しく追加しました。ゼロウィークリファレンスの値はもしその参照が解放されるとき自動的にnil代入されます。下記のサンプルに示すようにプロパティの宣言時に新しくweakとstrongの変数用の修飾子が追加されました。

// 次の行の宣言は右の宣言と同じ:@property(retain) MyClass *myObject;
@property(strong) MyClass *myObject;

// 下の行の宣言は"@property(assing) MyOtherClass *delegate;"
// の宣言に近いが、違うのはMyOtherClassのインスタンスが解放されるときに
// 不正なポインタが残らないようにnilがこのプロパティに代入されること。
@property(weak) MyOhterClass *delegate;

Xcodeは既存のプロジェクトをARCを使うように変換するのを助けるマイグレーションツールを提供します。このマイグレーションがどう動作するかについてのより詳しい情報は、Xcodeの新機能ユーザガイドを見てください。ARC自身についてより詳しい情報はARCを使ったプログラミングのリリースノートを見てください。

ストーリーボード

ストーリーボードはアプリのユーザインターフェースを定義する新しい方法です。今までは、毎回1つのビューコントローラのユーザインターフェースをnibファイルを使って定義していました。ストーリーボードファイルは独立した複数のビューコントローラと複数のビューコントローラ間のトランジションの両方を1カ所で表現することができます。その結果、ストーリーボードは、あなたが表示したいコンテントに加え、すべてのユーザインターフェースのフローを表現できます。
もしあなたが新しいアプリを作るなら、Xcodeのテンプレートはストーリーボードを使用するために設定されています。既存のアプリの場合のストーリーボードの利用方法は次のようになります。

  1. ストーリーボードを使うためにアプリのinfo.plistを設定します。
    • UIMainStoryboardFileキーとストーリーボードファイル名の値のペアを追加します。
    • 既存のNSMainNibFileキーを削除します(ストーリーボードはメインnibファイルを置き換えます)
  2. 「ストーリーボードファイルの作成」を読んで、Xcodeでストーリーボードファイルを、作成して設定してください。
  3. 「新しいビューコントローラに移行する準備」を読んで、ストーリーボードのトランジションをハンドルするようビューコントローラを更新してください。
  4. もし(たとえば加速度センサ関連のイベントをサポートするために)手動でビューコントローラを表示する必要があるときは、「プログラムによるストーリーボードビューコントローラの表示」を読んで、妥当なビューコントローラを取得し表示するためにストーリーボードクラスを使ってください。

アプリは、そのビューコントローラとビューのすべてを格納するために、1つのストーリーボードのファイルを使用することができます。ビルド時に、Interface Builderは、ストーリーボードのファイルの内容を取得し、パフォーマンスを向上させるために、個別に読み込むことができる個別の部品に分割します。 アプリはこれらの部品を直接操作する必要はありません。あなたがやらなければならないことは、アプリのinfo.plistにメインストーリーボードを宣言することだけです。あとは、UIKitが残りをすべて処理します。

ストーリーボードファイルの作成

アプリのストーリーボードファイルを作成するためにInterface Builderを使用します。ほとんどのアプリは1つだけストーリーボードのファイルを必要としますが、必要に応じて複数のストーリーボードのファイルを作成することができます。すべてのストーリーボードファイルは、初期ビューコントローラを持っています。このビューコントローラは、ストーリーボードへのエントリポイントを表します。たとえば、メインストーリーボードファイルで、初期ビューコントローラは、アプリで最初に表示されるビューコントローラになります。
ストーリーボードファイル内の各ビューコントローラは、単一のシーンを管理します。 iPhoneのアプリでは、シーンにはコンテンツの一画面分を管理しますが、iPadのアプリでは複数のシーンを同時に画面上に配置することができます。ストーリーボードファイルに新しいシーンを追加するには、ライブラリからストーリーボードのキャンバスにビューコントローラをドラッグします。その後は、nibファイルの場合と同様に、ビューコントローラのビューにコントロールやビューを追加することができます。そして以前と同様に、あなたのビューコントローラとそのビューの間のアウトレットとアクションを設定することができます。
1つのビューコントローラから別のビューコントローラに遷移したい場合は、1つのビューコントローラのボタンやテーブルセルや他のトリガーオブジェクトをControlキー+クリックして、別のシーンのビューコントローラにドラッグします。ビューコントローラ間でドラッグすると、設定可能なオブジェクトとして、Interface Builderで表示されるセグウェイ(訳注:滑らかな遷移の意味。新しい専門用語)が、作成されます。 セグウェイは、モーダルトランジションやナビゲーショントランジションのようにUIKitで利用可能な同じタイプのトランジションのすべてをサポートしています。また、1つのビューコントローラと別のビューコントローラを置き換えるカスタムトランジションを定義することができます。
Interface Builderを使ったストーリーボードファイルの設定についてのより詳細な情報は、「Xcodeの新機能ユーザーガイド」を読んでください。

新しいビューコントローラに移行する準備

現在のシーンでユーザがセグウェイをトリガーする度に、ストーリーボードランタイムは、prepareForSegue:senderを呼び出します。このメソッドは、現在のビューコントローラの表示についての必要なすべてのデータを渡すために機会を与えてくれます。あなたのビューコントローラクラスを実装するときは、これらの遷移を処理するため、このメソッドをオーバーライドする必要があります。
UIViewControllerクラスのメソッドの実装についてより詳細な情報は、「UIViewController Class Reference」を読んでください。

プログラムでストーリーボードビューコントローラの表示

ストーリーボードランタイムは、通常、ビューコントローラ間の遷移を処理しますが、プログラムコードからセグウェイをトリガすることができます。 セグウェイを設定するときに加速度センサのイベントを使用する場合のようにInterface Builderでは設定できない場合があります。新しいビューコントローラに遷移するためのいくつかの選択肢があります:

  • もしストーリーボードファイルが現在のビューコントローラから(恐らくビューコントローラの他のコントロールによってトリガーされる)遷移先のビューコントローラのセグウェイを含むとき、UIViewControllerのperformSegureWithIndentifier:senderメソッドを使ってセグェイをトリガーできます。
  • もしストーリーボードファイルに遷移先ビューコントローラが定義されているがセグウェイがないとき、UIStoryboardクラスのinstantiateViewControllerWithIdentifierメソッドを使って最初のビューコントローラをプログラムでロードできます。その後、ナビゲーションスタックにプッシュするなどのように今までの方法でビューコントローラを表示してください。
  • もし遷移先ビューコントローラがストーリーボードファイルにないときは、今までの方法でプログラムで生成と表示をしてください。それらの方法については、「ビューコントローラプログラミングガイド for iOS」に説明があります。

ニューススタンド対応

(興味がないので省略)。ニューススタンドアプリだと本のダウンロードをバックグラウンドで行うことができて便利です。その処理はOSが行いダウンロードが終わったらアプリに通知されます。アイコンは最新号の表紙に自動的にになるので便利です。info.plistにUINewsstandAppキーを追加する必要がああります。ニューススタンドアプリは最新号が出たことをプッシュ通知し、コンテンツをダウンロードする必要があるため、アプリとは別にサーバが必須となります。(訳注:最新号が勝手にダウンロードされるのかな?)

AirPlayの改善

AirPlayは、テレビやオーディオシステムなどのAirPlayの対応デバイスiOSベースのデバイスから、ユーザーのストリームオーディオやストリームビデオを表示することができます。 iOS5では、開発者は近くのApple TV 2でアプリのコンテンツを表示することができます。ユーザーは任意のアプリケーションのAirPlayを使ってApple TVにiPad2の内容をミラーリングすることができます。そして、ミラーリングの代わりに別のコンテンツを表示したい開発者は、AirPlayの経由でiPad2につながったUIScreenオブジェクトを新しいウィンドウに割り当てることができます。(訳注:iPad2とかいてあるが、iPhone4Sも含むのではないかと思われる)
さらに、下記の方法でAirPlayのメリットを得ることができます。

  • AVFoundationを使うアプリは、AVPlayerクラスを使うことでAirPlay経由でストリーミングオーディオやストリーミングビデオを表示することができます。詳細は「AV Foundation Frameworkリファレンス」を参照してください。
  • Media Player frameworkは、いくつかの場所で「Now Playing」情報を対応しました。コンテンツの一部をAirPlayで表示させることもできます。詳しくは、「MPNowPlayingInfoCenterクラスリファレンス」を参照してください。
  • UIWebViewクラスは、AirPlay経由でマルチメディアコンテンツの表示に対応しました。これはデフォルトでONであり、あなたはONにする必要がありません。

備考:iOS5では、AirPlayはサポートされているすべてのオブジェクトはデフォルトでONです。アプリで表示したくない場合は、明示的にOFFにする必要があります。
より詳細な情報は、「AirPlay概要」を参照ください。

GLKit Framework

(興味がないので省略)。GLKitはOpenGL ES2.0の簡単に扱うクラスを提供します。GLKViewとGKLViewControllerは初期化とレンダリングループをサポートして、アプリは描画するだけで済みます。GLKTextureLoaderは、画像のデコードも含めて行います。同期ロードと非同期ロードがあり、非同期ロードでは完了ハンドラブロックをアプリが用意する必要があります。GLKitは、ベクトル、行列、クォータニオンを用意します。GL ES 1.1の行列スタックと同様の機能を提供します。GLKBaserEffect, GLKSkyboxEffect, GLKReflectionMapEffectクラスは、よく使うフラグメントシェーダーを提供します。GLBaseEffectはライトやマテリアル等のGL ES 1.1同等のシェーダーです。

Core Image Framework

Core Image framework(CoreImage.framework)は、ビデオや静止画を操作する強力なビルトインフィルタを提供します。タッチアップ(訳注:タッチアップって何?)やフォトの修正などの簡単なオペレーションから顔認識やフィーチャー認識(訳注:フィーチャー認識って何?)のようにもっと高度なオペレーションまでのビルドインフィルターを利用できます。オリジナルの画像を直接変更することなくフィルターをかけれます。Core ImageはCPUとGPUのパワーを利用して高速に効果的にオペレーションをします(訳注:恐らくCPUのneon機能やGPUのフラグメントシェーダ機能を使うため自分でコードを書くより高速)。
CIImageクラスは、写真の品質を上げるために利用できるフィルターセットにアクセスできます。自分でフィルタを作る場合は、CIFilterオブジェクトを生成してカスタマイズすることができます。
より詳細な情報は、「Core Image Reference Collection」を参照ください。

Twitter Framework

Twitter Framework(Twitter.framework)は、ツイートを送る機能を提供します。フレームワークは、ユーザ認証もハンドルし、HTTPリクエストのテンプレートも提供します。ツイート発言の編集は、TWTweetComposeViewControllerを使います。このクラスは送信する前にツイートを編集する機会をユーザに与えます。
ユーザは設定アプリを使ってあるアプリがTwitterと通信してよいか制御します。Twitterフレームワークはユーザのアカウントにアクセス可能かAccounts framework(Accounts.framework)と組み合わせて動作します。
より詳細な情報は、「Twitter Framework Reference」を参照してください。

Accounts Framework

Accounts framework(Accounts.framework)は、ユーザアカウントのシングルサインオンを提供します。シングルサインオンは、アプリでログイン画面を別途表示する必要がないためユーザエクスペリエンスが向上します。これはアプリでアカウントの認証を管理する必要がないため開発も簡単になります。iOS5では、アプリはTwitterアカウントにアクセスするためにTwitter frameworkと組み合わせてAccountsフレームワークを使います。
より詳細な情報は、「Accounts Framework Reference」を参照してください。

Generic Security Service Framework

Generic Security Service framework(GSS.framework)は、アプリに標準的なセキュリティ関連のサービスを提供します。このフレームワークの基本インターフェースは、RFC2743とRFC4401です。標準インターフェースを提供することに加えて、iOSは、標準では定義されていないけれどもアプリで必要とされる資格情報を管理する機能が追加されています。
GSSフレームワークについては、ヘッダファイルを参照してください。

Core Bluetooth

Core Bluetooth framework(CoreBluetooth.framework)は、Bluetooth LE(省電力)アクセサリとやりとりすることができます。このフレームワークObjective-Cインターフェースは、LEアクセサリをスキャン(訳注:探す)・接続・切断・リード・ライト・登録・属性変更通知などさまざまなことができます。
詳細な情報は、ヘッダファイルを参照してください。

アプリの設計レベルの改善

(疲れてきたので省略)。
UIDocumentクラスの追加:バックグラウンドで非同期に読み込み、書き込みが可能です。iCloudストレージの協調読み込み・書き込みが可能です。テンポラリファイルに書いてから交換するので安全です。異なるバージョンでのコンフリクトの解決をサポート(訳注:iCloudでのコンフリクト対応か)。自動保存があります。フラットファイルとパッケージファイルをサポートします。Core Dataを使うアプリ用に、UIManagedDocumentサブクラスがあります。iCloudストレージ対応アプリを書くならすごく便利なクラスです。

Data Protectionの改善:iOS4ではファイルシステム全体を暗号化できましたが、ユーザがアンロック(訳注:待ち受け画面からホームに移る動作)するまでアプリはファイルにアクセスできませんでしたが、ごにょごにょするとファイルにアクセスできるようになります(訳注:適当)。

UIKitのコントロールの見た目をカスタマイズ:ツールバー、ナビゲーションバー、サーチバー、ボタン、スライダー、その他のコントロールで、ティントカラーと背景画像、タイトル位置が変えることができるようになりました。アピアランスプロクシ(表現プロクシ)を使って直接いろんな属性が変更できます。UIAppearanceプロトコルができました。(訳注:こりゃいいね!)

Container View Controller追加:いままでUINavigationController、TITabBarController、UISplitViewControllerというコンテナビューコントローラがありましたが、これからはカスタムコンテナビューコントローラが作れます。これを使うとメッセージを転送したり、回転したりの対応ができます。

設定アプリ:設定アプリ内でアプリの設定画面を作れますが、そこにラジオグループが追加されました。これで画面遷移なしにリストからの選択のようなことができます。

Xcodeツール

(疲れてきたので省略)。
Xcodeの改善:LLVMコンパイラはARC(自動リファレンスカウンタ)に対応しました。ARC対応への変換コマンドもメニューに追加されました。Interface Builderはストーリーボード作成に対応しました。iOSシミュレータはCore Location framework(訳注:GPS)のために別の場所をシミュレーションすることができるようになりました。デバイスのアプリのデータをダウンロードできるようになりました(訳注:恐らくデバイスからMacへデータが転送できるようになったということ)。シミュレータやデバイスでのデバッグやテストのときに自動的にリストア(訳注:データをシミュレータやデバイスへ転送)できます。

UI Automationの改善:(訳注:Automationはテストツール)。UIATargetオブジェクト、UIAHostオブジェクト、UIAElementオブジェクトとか。UIAKeyboardオブジェクトとか。

Instruments:System Traceが追加され、システムコール、スレッドスケジューリング、VMオペレーションなどが取れるようになりました。Network Connectionが追加され、アプリがTCP/IPUDP/IPをどう使っているか。それぞれのアプリでどれぐらいのデータが流れているか。ラウンドトリップタイムや再転送要求情報などがみられるようになりました。

iOS5で問題が発生したところ

アイビスでは、ibisMail(アイビスメール)とibisPaint(アイビスペイント)をリリースしていますが、iOS5で実行した場合にいくつか問題が起きました。

ソフトウェアキーボードサイズ変更問題

ibisMailではソフトウェアキーボードの変換候補がiOS4ではキャレット(カーソル)のすぐ下に出ていたのが、iOS5ではソフトウェアキーボードのすぐ上に表示されることになったために、メッセージ作成画面などのTextViewを使った画面でキャレットが見えなくなる。という問題が起きました。今までキーボードの出現と非表示のイベントをnotification centerにハンドラを登録してTextViewの大きさを変更していましたが、このイベントにソフトウェアキーボードのサイズ変更イベントが追加されたようで、これに対応することで解決しました。

Unicode6対応問題

iOS4では絵文字が、ソフトバンクの絵文字のマッピングだったのですが、iOS5ではUnicode6に絵文字が採用されたことを反映して絵文字のマッピングが変更されました。これによりメールの送受信でキャリア(ソフトバンクau、ドコモ)のメールサーバの絵文字変換システムが対応していない文字として「?」に変換するようでibisMailでは致命的な問題となっています(現在、調査中)。今までも3キャリアの絵文字の送受信対応は、バイナリを解析したりとかなりハックしながら対応してきたのに、また絵文字で問題が起きて残念です。メールアプリに限らずあるアプリ同士で絵文字が相互に使えていたのが、iOS4の人同士は化けない、iOS5同士の人は化けない、iOS4iOS5の間で情報を交換しようとすると化けるということは起こりえると思います。しかし長期的に見れば多くのOSで世界中で絵文字が交換できるようになる可能性ができたので前進したとも言えます。

カスタマイズしたAlertView

ibisPaintではTwitterYouTubeのUserIDやパスワードを入力する欄として、AlertViewをカスタマイズしてTextFieldを挿入したりしていたのですが、AlertView内のビューを列挙してクラス名で比較して、TextFieldを挿入、などのコードがあったようで、iOS5ではレイアウトが崩れました(内部クラス名で比較したのが悪いのですが)。iOS5では、TextField付きのAlertViewはカスタマイズせずともオプションで簡単に表示できるようになった影響かと思います。

iOS5のせいじゃないけど au

iOS5に対応できているかは、β版等で試験できるのですが、au版のiPhoneでの試験はiPhone4Sが販売されるまで試験が出来ず、結果的にibisMailでは、@ezweb.ne.jpのメールサーバの自動認識に失敗し、手動でimapサーバのポートや認証方式を指定しなければ使えず、レビューにもたくさんezweb対応してないじゃん。と書かれてしまって評価が下がってしまいました。早急にアプリダウンロードのアプリ説明文や製品ページ、FAQにも手動設定の方法を書いたのですが、たくさんのお問い合わせが来てしまってサポートが大変です。事前に試験が全く出来ないのはなかなか辛いところです。

さいごに

auiPhoneが出たせいか、なんか盛り上がっている感じ。iPhoneユーザが増えて嬉しい限りです。docomoからもで出るとよいな。iPhoneアプリ開発は楽し!
次回は、iCloudについての訳を公開できたらよいな。
おまけ。下記、ibisPaint(アイビスペイント)でユーザさんが書いてくれだ絵。スティーブ・ジョブズ、ありがとう

ーー
この記事が参考になったという方は、ibisMail Free(無料)でよいのでダウンロードをよろしくお願いします。
URL:ibisMail Freeのダウンロード、レビューはこちら
URL:ibisMail for iPhoneのダウンロード、レビューはこちら
URL:ibisMail for iPadのダウンロード、レビューはこちら
URL:ibisPaintのダウンロード、レビューはこちら サイトは、ibispaint.com
ご意見ご要望はTwitterから: @kamiyan