CADisplayLink について
ユースケース
CADisplayLink を実際に使う例と共にどんなクラスなのか簡単に紹介します。
例えば現在時刻を表示する場合。
画面に表示されている日時を定期的に更新する必要があります。
そのような場合に NSTimer で 0.01 秒など適当なインターバルを設定して更新、みたいなこと実装した経験ありませんか?
僕はあります。
それを解決するための表示されているビューを更新するためのイベントを取得するためのクラス、それが CADisplayLink です。
最近 facebook が OSS 化した pop や、長年 iOS の 2D ゲームフレームワークとして親しまれている cocos2d でも、もちろん使われていました。
CADisplayLink の使い方
CADisplayLink を以下の様にしてセットアップすることで、ディスプレイの更新タイミングをトリガーにしたイベント実行が可能になります。
///1 CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(update:)]; ///2 [link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
画面更新には CADisplayLink
前述したバッドケースとして NSTimer で更新、というのがありました。
これの何が悪いかというと、メインスレッドのロックなどが無ければ、画面の更新は大抵の場合 1/60 秒間隔で行われます。
なので、NSTimer でそれより細かい間隔で更新してもディスプレイには反映されません。
また画面の更新間隔はメインスレッドの具合によって変動するので、 CADisplayLink を用いて画面と関連づけて更新した方が良いというわけです。
ちなみに Building Paper を見て初めて知りましたが、大体メインスレッドで5ms以上処理がかかると、ドロップフレームが起こるらしいです。
facebookの”Building Paper”はすべてのiOSエンジニアがみるべき
CADisplayLink の考え方としてはゲーム開発などのフレームワークなどに良くある update 関数と近いというか同じだと思います。
画面上に描画する処理をユーザからの入力や、システム内のループで行っているものを CADisplayLink に置き換える事でアプリケーションをヌルヌル動かす事ができるようになるかもしれません。
アップル Apple Mini DisplayPort-Dual-Link DVIアダプタ MB571Z/A
- 出版社/メーカー: アップル
- 発売日: 2009/01/14
- メディア: Personal Computers
- この商品を含むブログを見る
UIViewTintAdjustmentMode について
tintColor
iOS 4 以前は tintColor プロパティは UIToolBar など、限られたクラスにのみ提供されていました。
UIToolBar - tintColor | iOS Developer Library
iOS 5 になると UIAppearance が提供され、他にもたくさんの UIView のサブクラスが tintColor プロパティを持つようになりました。
iOS 7 では遂に UIView 自身が tintColor プロパティを持つようになり、アプリケーション全体への tintColor の反映が可能なりました。
どういうことかというと、値を明示的に指定しない限り tintColor プロパティは親ビューの値を受け継ぐので、
たとえば keyWindow の tintColor プロパティを設定するだけでアプリ全体に行き渡る、ということです。
UIViewTintAdjustmentMode
iOS 7 からは tintColor 同様、UIView に tintAdjustmentMode というプロパティが追加されました。
このプロパティは上記の tintColor の継承関係をどのように反映させるかを決定するものです。
subviews の中に tintColor プロパティがデフォルトのものしか無ければ値は UIViewTintAdjustmentModeNormal になります。
UIViewTintAdjustmentModeDimmed を明示的に tintAdjustmentMode に設定すると、
その UIView の tintColor からは dimmed 加工が施された UIColor が return されるようになります。
ユースケース
そもそもこのプロパティを見つけるに至ったきっかけになるのですが、
UIAlertView のようなモーダルで覆うカスタムビューを作る場合などに使用します。
以下のコードが非常に勉強になりました。
ちなみに UIAlertView を show したときに後ろ側に回る keyWindow を見るとわかりますが、
UIAlertView はしっかり keyWindow の tintAdjustmentMode を dimmed に設定しています。
なので UIKit の作法に従うためにも、細かいですがしっかりと実装していきたいところですね。
参考
UIView - tintAdjustmentMode | iOS Developer Library
Asset Catalog の AppIcon を使って複数ターゲットで出し分ける
Asset Catalog 以前
Asset Catalog が出るまでは、アプリのアイコンをターゲット毎に出し分ける際は
以前に僕が書いた
と同じ要領で、ビルド後のスクリプトを用いてターゲット毎に用意された画像を適宜配置する必要がありました。
Asset Catalog 以後
Xcode 5 から Asset Catalog という画像管理に便利な機能が追加されました。
Xcode 5 で新しくプロジェクトを作成すると、Images.xcassets というフォルダがデフォルトで作成されます。
内部には AppIcon と LaunchImage という Image Set があり、これらに画像を適用するといった具合です。
画像の slicing を直感的に指定できたり、AppIcon も iOS/iPad 毎、iOS のバージョン毎に指定できたりと便利です。
Asset Catalog を用いたアイコン出し分け
では上記の AppIcon や Launch Image を出し分けるかという肝心な所ですが、
Build Settings を覗くと、 以下の項目がある事に気付くかと思います。
Asset Catalog Compiler - Options
その中に、
Asset Catalog App Icon Set Name Asset Catalog Launch Image Set Name
という設定項目があり、デフォルトでは AppIcon と LaunchImage が設定されています。
これを ReleaseAppIcon などの自身で設定した Image Set 名に設定する事で、
ターゲット毎に Image Set を変更する事が可能になります。
ちなみに xcconfig などで書くのであれば、上記2項目のディレクティブは以下です。
ASSETCATALOG_COMPILER_APPICON_NAME ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME
Asset Catalog のとても残念な所
ここまで Asset Catalog の良い所だけ書いてきましたが、実のところ残念な所も多いです。
たとえば上記で行ったターゲット毎の Image Set の出し分けを、
アプリ内で利用するリソースに対しても行うのは非常に困難で、
結局ビルド後のスクリプトで Images.xcassets 配下の画像リソースを上書きする手間が出てきます。
詳細は下書き程度に書いた僕のブログを読んでください。
iOS 7.1 から iAd 経由でのアプリインストールのコンバージョン計測が可能に
コンバージョン計測
iOS 7.1 から以下の API が iAd.framework に追加されています。
ADClient - (void)determineAppInstallationAttributionWithCompletionHandler:(void (^)(BOOL appInstallationWasAttributedToiAd))completionHandler NS_AVAILABLE_IOS(7_1);
この completionHandler を登録しておくと、 iAd 経由でユーザがアプリをインストールした場合に発火するといった具合です。
また設定において、Limit Ad Tracking を行い、広告トラッキングをオプトアウトしている場合には appInstallationWasAttributedToiAd が NO で発火するようです。
iAd の発展
iOS 6 から advertisingIdentifier が追加され、UDID や MAC Address の取得が禁止になり、 iOS 7 ではiAd の導入が劇的に簡単になりました。
以下のような噂(1年前の記事ですが)も立っているようなので、今後も Apple の広告への取り組みは注目されそうです。
Appleがクッキーを利用しているアプリを拒絶へ: Ad Identifierへの統一がねらい
参考
iAd 実装が iOS7 から恐ろしく簡単になってる件
iAd on iOS 7
iOS 6 までは iAd を表示しようとすると、ADBannerView をインスタンス化して layout してなど色々と面倒でした。
iOS 7 では iAd.framework に以下のカテゴリが追加されています。
UIViewController (iAdAdditions)
これを用いる事で、今までのような煩わしいことをほとんど気にせずに iAd を表示する事が出来る様になります。
ユースケース毎に見ていきましょう。
バナー広告を表示したい
以下のプロパティをセットするだけ。
///(1)フレームワークをimport @import iAd; ///(2)初期化時などに self.canDisplayBannerAds = YES;
これだけでバナーが画面下に表示されます。
Interstitial 広告を表示したい
事前準備として以下を実行すると Interstitial 広告の情報をプリフェッチしておいてくれます。
//起動時などに
[UIViewController prepareInterstitialAds];
自動的に出すだけならカテゴリで追加された UIViewController の以下のセットするだけです。
@import iAd;
self.interstitialPresentationPolicy = ADInterstitialPresentationPolicyAutomatic;
自動だとさすがに煩わしい、意図したタイミングで、という場合は以下の様に
@import iAd; self.interstitialPresentationPolicy = ADInterstitialPresentationPolicyManual; //意図したタイミングで [self requestInterstitialAdPresentation];
iAd という選択肢
「iAd だけじゃやってけない」、「SSP 使って出し分けしたいし」、「広告興味ありません」などの意見には、
上記だけでは充分なメリットはないですが、
「広告導入に手間はかけずに、プロダクトに注力したい」「けど最低限の運営費は欲しい」みたいな開発者には一つの手段には成り得ると思います。
ということで知らない間に驚くほど簡単になってた iAd の紹介でした。
iAd Production Beginner’s Guide
- 作者: Ben Collier
- 出版社/メーカー: Packt Publishing
- 発売日: 2012/02/23
- メディア: Kindle版
- この商品を含むブログを見る