iPhoneのRetina4ディスプレイ判定方法

Retina4か否かを判定する方法をいろいろ調べてみました。
正しいディスプレイのサイズを取得するためには、+[UIScreen mainScreen]メソッドで得られるオブジェクト使うのですが、以下のように3つの値が取得できます。

NSLog(@"mainScreen bounds height %f", [[UIScreen mainScreen] bounds].size.height);
NSLog(@"mainScreen applicationFrame height %f", [[UIScreen mainScreen] applicationFrame].size.height);
NSLog(@"mainScreen currentMode height %f", [[UIScreen mainScreen] currentMode].size.height);

それぞれの結果を見てみると、以下の通りになりました。

  1. mainScreen bounds height 568.000000
    Retina以前のディスプレイと、互換のあるサイズ表記
  2. mainScreen applicationFrame height 528.000000
    1と同様だけど、ステータスバーを含まない高さであり、ステータスバーの状態によって値が変わる。この例は、着信ステータスバーがONになっている状態なので、1より40px少ない値になっている。
  3. mainScreen currentMode height 1136.000000
    物理的なpixel値。解像度の判定まで必要な場合は、この値を使うのが適切かもしれない。

SysStats Monitor/Liteでは、現在2を使っているので、ステータスバーの状態によって取得される値が変わってしまい、着信中やテザリング中にアプリが起動されると、正しく判定できていないことがわかりました。
今回の目的では1と3のどちらでもいいと思いますが、とりあえず1を採用し、以下の形でチェックすることにしました。

#define R4_DISPLAY_HEIGHT 568.0

+ (BOOL)is4InRetinaDisplay {
    
    if ([[UIScreen mainScreen] bounds].size.height == R4_DISPLAY_HEIGHT) {
        return YES;
    } else {
        return NO;
    }

}

SysStats Monitor iOS6/iPhone5 (Retina 4) 対応のまとめ

現在、SysStats MonitorをiOS6/iPhone5 (Retina 4) 対応にするための改修を、コツコツとやっています。iOS6がリリースされてから2ヶ月ほど経つので、あまり新鮮な情報ではないですが、その作業が概ね完了したので、一通りやったことをまとめてみました。

大きく分けると、以下の3項目になります。

iPhone5 (Retina4) への対応

こちらは、見た目の調整であり、以下の2点が大きな目的となります。

  • Retina4ディスプレイのサイズに合わせること
  • 旧機種では、今まで通り表示されること

実際には、単純に画面の縦幅を延ばせばいいというわけではなく、操作に関する問題もいくつか出ました。

画面サイズの変更

640 x 1136 pixelsのLaunch Imageを作成して、プロジェクトに追加することで、画面サイズが変更されます。

Main Interfaceに設定されているNIBの変更

Main Interfaceに設定されているNIBファイル(通常はMainWindow.xib)のWindowオブジェクトの"Full Screen at Launch"プロパティをONにする。
それをやらないと、UITabBarControllerを使っている場合、tab barが反応しなくなってしまうようです。
ios - UITabBarController does not respond on iPhone 5 simulator: 4-inch retina display - Stack Overflow

Autosizing Maskの調整

iPhoneiPadの両方にユニバーサルバイナリ方式で対応しているアプリの場合は、すでに正しく設定されていることと思いますが、SysStats Monitorの場合、UIを共通化していなかったので、iPhone用のUIには、自動的にリサイズされるような設定はしていませんでした。
いくつかの画面で、表示が上の方に偏ったり、重なってしまったりしたものがあったので、正しく表示されるよう調整しました。

UIActionSheetの調整

ここまでの対応をしたところ、画面の見た目上は、正しく表示されるようになりましたが、UIActionSheetについては、2つの問題が発生しました。

  • iPhone5だと、一番下のボタンが反応しない。
  • 旧機種だと、一番下のボタンが表示されない。

UIActionSheetを表示させるメソッドがいくつか提供されており、これまでは、tab barから出したり、現在のviewから出したりで、統一できていませんでした。今回は、すべてを以下のメソッドに置換えることで解消されました。

[actionSheet showInView:self.view.window];

同時に、"Presenting action sheet clipped by its superview"というワーニングも出なくなりました。

参考: Objective-Cと戦うブログ: UIActionSheetで「Presenting action sheet clipped by its superview.」というエラーについて

iOS6への対応

SDKの対応アーキテクチャの変更

最新のXcodeでは、armv6(iPhone 3G)と、iOS 4.3よりも前のOS向けのバイナリの生成が出来なくなっています。
Xcode Release Notes
これにより、私の所有している環境では、iOS5.1以降のみ実機テストが可能な状態になってしまいました。
そのため、以下の対応を行いました。

  • Architectures: armv7, armv7sに変更し、armv6を削除
  • iOS Deployment Target: iOS5.1
デバイスの回転への対応

iOS6から、デバイスが回転したときのイベントのハンドリング方法が変わりました。
UIViewControllerのデフォルトの実装では、全方向の回転を受付けるのがデフォルトになっているようです。
SysStats Monitorの場合、iPad版はそれで問題ないのですが、iPhone版はデバイスの回転をサポートしていません。
それを抑止するため、iPhone版のApplicationDelegateクラスに、以下のメソッドを追加しました。

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    return UIInterfaceOrientationPortrait | UIInterfaceOrientationPortraitUpsideDown;
}

尚、起動時のRootViewControllerの登録を、古い方法で記述していると、iOS6では回転したときのイベントが発生しなくなってしまうようです。
iphone - iOS 6 shouldAutorotate: is NOT being called - Stack Overflow

iOS5でやり残していたものへの対応

UDIDを取得するメソッドがdeprecatedになった

iOS5で、すでにUIDevice.uniqueIdentifierプロパティは、deprecatedになっていましたが、対応が漏れていました。
将来的に削除されたときに備えて、以下のようにプロパティの存在チェックをしてから呼び出すように変更しました。

    // prepared for that uniqueIdentifier is deprecated.
    uniqueIdentifierLabel.text = [currentDevice respondsToSelector:@selector(uniqueIdentifier)] ? currentDevice.uniqueIdentifier : @"N/A";

とりあえず、アプリの画面サイズを、Retina4 (640 x 1136 pixels) に対応させる方法

まず、結論から言ってしまうと、640 x 1136 pixels の Launch Image が設定されていれば、Retina4 デバイスでアプリが実行されたときに、画面サイズが640 x 1136pixelsになるようです。

具体的な設定方法は、 iOS App Programming Guide を参照していただくとして、最も簡単な方法は以下の通りです。

1) Xcodeで、Retina4 用の Launch Image が設定されていないプロジェクトを開き、左ペインをIssue Navigatorに切替えると、以下のようなWarningが表示されます。

2) この Warning メッセージをクリックすると、以下の Alert パネルが表示されます。

3) Add をクリックすると、とりあえず、真っ黒な Default-568h@2x.png ファイルがプロジェクト内に作成され、Launch Image として認識されます。

この状態で、とりあえずRetina4デバイスの実機かSimulatorでアプリを実行すると、それまで上下にあった隙間が埋められ、画面サイズが640 x 1136 pixelsで実行されるようになります。

autoresizing 機能により、ほとんどの画面は、最適化されて表示してくれるはずですが、絶対座標が指定されていたり、autoresizing の設定が適切でないコンポーネントは、思った通りにならない場合もあるので、一通りの動作確認をして、想定通りに機能するよう、調整する必要があります。

実際に、私の場合は、TabBarをタップしても反応しないという問題や、表示がズレる問題が発生しました。
いくつかハマりどころがありそうです。

それらについては、また後日書いてみたいと思います。

補足

iOS Human Interface Guidelines の Launch Image の説明によると、

For apps that run on iPhone 5 and iPod touch (5th generation), create a launch image that measures 640 x 1136 pixels.

と書かれていますので、Appleのマニュアルの中では、これが、画面サイズを640 x 1136pixelsにするための条件を、暗黙的に示しているのかもしれません。

MacPortsのupgradeでハマったこと

久しぶりに、MacPortsのupgradeを実行して、ハマったところがあったので、メモを兼ねて書いておきます。

makeがない??

まず最初は、初歩的な問題でした。

$ sudo port upgrade outdated
....
Error: Unable to open port: can't read "build.cmd": Failed to locate 'make' in path: '/opt/local/bin:/opt/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin' or at its MacPorts configuration time location, did you move it?
....

これは、Xcode 4.3.xをインストールした後に、Command Line Toolのインストール*1をし忘れてたことによります。すぐに気付いて、インストールしてクリアしました。

ncursesがactivateできない??

次は、以下の問題が起きました。

$ sudo port upgrade outdated
....
--->  Activating ncurses @5.9_1 
Error: org.macports.activate for port nurses returned: Image error: /opt/local/bin/captoinfo is being used by the active ncursesw port.  Please deactivate this port first, or use 'port -f activate nurses' to force the activation.
Please see the log file for port nurses for details:
....

何か不整合が起きているために、エラーになったようです。
以下のレポートを参考に、強制的にuninstallしてから、やり直したら、とりあえず、先に進んでくれたようです。

#34872 (Failed to install ncurses) – MacPorts

$ sudo port -f uninstall ncursesw
....
Warning: Deactivate forced.  Proceeding despite dependencies.
--->  Uninstalling ncursesw @5.7_0+darwin_10 

perl5も失敗??

とりあえず、先に進んだのですが、今度はperl5のactivateでもエラーになりました。

$ sudo port upgrade outdated
....
--->  Activating perl5 @5.12.4_0+perl5_12 
Error: org.macports.activate for port perl5 returned: Image error: /opt/local/bin/a2p is being used by the active perl5.8 port.  Please deactivate this port first, or use 'port -f activate perl5' to force the activation.
Error: Failed to install perl5
Please see the log file for port perl5 for details:
....

こちらも、以下のレポートを参考にいくつかのバージョンをuninstallしました。
#28831 (port upgrad outdated fails with error: /opt/local/bin/a2p is being used by the active perl5.8 port.) – MacPorts

$ sudo port installed | grep perl
  p5-libwww-perl @5.834_0 (active)
  perl5 @5.8.9_0
  perl5 @5.12.4_0+perl5_12 
  perl5.8 @5.8.9_3 (active)
  perl5.12 @5.12.4_1 (active)
  subversion-perlbindings @1.6.9_0 (active)

$ sudo port uninstall perl5 @5.8.9_0
--->  Uninstalling perl5 @5.8.9_0 

$ sudo port upgrade perl5.8
....

$ sudo port installed | grep perl
  p5-libwww-perl @5.834_0 (active)
  perl5 @5.12.4_0+perl5_12 
  perl5.8 @5.8.9_3
  perl5.8 @5.8.9_8 (active)
  perl5.12 @5.12.4_1 (active)
  subversion-perlbindings @1.6.9_0 (active)
$ sudo port uninstall perl5.8 @5.8.9_3 
--->  Uninstalling perl5.8 @5.8.9_3 

この後、再実行したら、エラーがなく無事終了しました。

$ sudo port upgrade outdated
....
--->  Updating database of binaries: 100.0%
--->  Scanning binaries for linking errors: 100.0%
--->  No broken files found.


環境によって、ここで説明した方法が当てはまらないこともあるかもしれませんが、もしも、同じような状況になったときに、参考になればと思います。

*1:Command Line Toolのインストールは、PreferenceのツールバーからDownloadボタンをクリックして表示された一覧から、Command Line Toolsの行にあるinstallボタンをクリックします

Retinaディスプレイで画像リソースをキレイに表示するには?

iPadRetinaディスプレイになったことで、また1つ、解像度の異なるiOSデバイスが増えました。

どれだけの種類があるかというのは、List of iOS devices - Wikipedia, the free encyclopedia
にまとめられています。

ここから、ディスプレイの解像度に関する情報だけ抜き出してみると、以下の4パターンになります。

アプリのユーザインタフェースでは、さまざまな箇所で画像リソースを使用していますが、各デバイスの解像度に適合したサイズのものを用意しないと、それらがキレイに表示されなくなってしまいます。
実際にどのような考慮が必要なのか、例を挙げてまとめてみました。

Application icon

各解像度に対して、以下の4種類のサイズが必要になります。

解像度 デバイス イコン画像サイズ
480 × 320 px iPhone 3GS, 〜iPod touch 3G 57 x 57
960 × 640 px(Retina) iPhone 4/4S, iPod touch 4G 114 x 114
1024×768 px iPad, iPad2 72 x 72
2048×1536 px(Retina) new iPad 144 x 144

簡単に言ってしまうと、

  • iPhone/iPod touchiPadは、画面の大きさが違うので、表示するアイコンのサイズが違う。
  • Retinaは2倍の解像度なので、サイズも2倍にしないと、粗い画像になってしまう。

ということですね。

SysStats Monitorというアプリの場合は、480 × 320 pxのデバイスしか存在しないころにリリースしたものなので、新しい解像度のデバイスが出るたびに、アイコンを追加しています。

上記のアイコンは「Small App Icon」と呼ばれるもので、アプリの中にバンドルするものです。
それに加えて、もう一つApp Storeで表示するときのアートワーク画像用として、512 x 512の「Large App Icon」も用意する必要があります*1。こちらは、iTunes Connectでアプリの申請をするときのメタデータとして登録します。
私の場合、それを縮小して各アイコンを作っているので、これに関してはあまり手間をかけずにできています。

裏を返せば、まず最初に「Large App Icon」を作成しておく方が、よいということですね。
これから、iPhoneアプリ開発を始める方は、ご注意ください。

Tab bar icon

それ以外にも、アプリの中のTab barのボタンに使う画像も、解像度を考慮する必要があります。
こちらは、iPhoneiPadの違いはないので、Retinaか、そうでないかの2種類になります。

私の場合、当初、30 x 30で作成してしまったので、もう一度60 x 60を作り直す必要があり、やや手間がかかってしまいました。
なので、こちらも、最初から大きめのサイズで作っておくのが無難ですね。

その他の画像

これ以外にも、Launch image(起動時のスプラッシュ画像)や、Spotlightの検索結果や設定画面で表示されるアイコンなど、いくつか画像リソースの種類があります。
以下のドキュメントには、全般的な説明が書かれています。

iOS Human Interface Guidelines - Custom Icon and Image Creation Guidelines

その他の画像については、こちらを参照してください。

*1:必須ではありませんが、Retina用に1024 x 1024のものも作成することが推奨されています。

アプリのメタデータのデフォルト言語を変更する方法

iTunes Connectで、メタデータ(AppStoreに表示される紹介文など)のデフォルト言語をアプリごとに指定できるようになりました。
これまでは、最初のアプリ登録時に選択したデフォルト言語が、その後追加されるすべてのアプリに適用されてしまい、かつ、変更もできなくて、苦労していました。

以下に、変更の手順を、簡単に説明します。

各アプリの情報設定を行う画面左上にあるApp Informationというタイトルの横、[Edit]というボタンをクリックします。

すると、以下のような設定パネルが表示されるので、そこで、そのアプリのデフォルト言語を選択することができます。

Localizeしたリソースを登録していない地域のAppStoreでは、アプリの紹介文やスクリーンショットが、このデフォルト言語で表示されます。そのため、デフォルトを[Japanese]にしていると、そこで日本語の紹介文やスクリーショットが表示されてしまいます。
なので、デフォルト言語は[English]にしておき、Localizationで[Japanese]を追加するのが無難だと思います。

私も、早速、そのように変更して、正しく適用されていることを確認しました。
同じような状況の方は、ぜひ、試してみてください。

SysStats Monitor / SysStats Lite 3.2 アップデートのお知らせ

先程、SysStats Monitor/SysStats Lite 3.2が、AppStoreにリリースされました。
主な変更点は、以下の通りです。

  • iOS5への対応
    • CPU使用率のUserとSystemの値が合算されるようになったことへの対応
    • デフォルトのプロセスブックマークに追加された標準アプリを反映
  • 強制的に英語モードで実行する機能を追加
    設定は、標準の設定アプリから行ってください。
  • その他
    いくつかのマイナーバグの修正と改善を行いました。

有料版のSysStats Monitorは、Facebook Feed Dialogの仕様変更があったようです - The iPhone Development Playgroundでお知らせしたFacebookの問題も解決しました。

これから使ってみようと思われる方は、以下のAppStoreをクリックして、AppStoreからダウンロードしてみてください。

SysStats Monitor (有料版) SysStats Monitor

SysStats Lite (無料版) SysStats Lite

どうぞ、よろしくお願い致します。