Apple TVアプリでボタンやフォーカスの動きを調べる

フォーカス移動の検知

override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
    context.nextFocusedView?.backgroundColor = UIColor.grayColor() // 現在フォーカスがあたっているビューの操作
    context.previouslyFocusedView?.backgroundColor = nil // ひとつ前にフォーカスがあたっていたビューの操作
}

最初にフォーカスされるビューの指定

override var preferredFocusedView: UIView? {
    return ボタン名
}

ボタンが押された時の処理

ボタン名.addTarget(self, action: #selector(呼び出すメソッド), forControlEvents: UIControlEvents.PrimaryActionTriggered)

わからないこと

  • スワイプでフォーカスが移動しない場合の対応
  • 左右タップの取得方法 (取得できる?)

参考

Apple TVアプリを作るために下調べ

やること

やったこと

プログラミングガイドを読む

ターゲット追加

  • プログラミングガイドに以下のようにあるので、iOSのリソース使うかわからないが既存プロジェクトにターゲットを追加した
  • Bundle IDとかどうなるのかよくわかっておらずProduct Nameをどうしたものか迷ったが既存プロジェクト名TVとTVを後ろにつけてみた

既存のプロジェクトをtvOS用に移行する場合、Xcodeプロジェクトに新しくターゲットを追加することにより、既存リソースの共有が容易になりますが、ストーリーボードは新たにtvOS用のものを作成する必要があります。

Provisioning Profiles作成

  • プログラミングガイドに以下のようにあったが、iOS用とBundle IDをわけるのかよくわからなかった
  • とりあえずtvOS用にProvisioning Profileを作る
  • App IDはiOS用のものを選択する
  • Provisioning profile does not match bundle identifierとエラーがでた (WatchOSの時は相違しててもOKな気もしたが)
  • Bundle IDをあわせたらArchivesができたので大丈夫かな

Apple TV用アプリケーションの開発や配布に当たっては、Apple TVに対応した新しいプロビジョニングプロファイルが必要です。既存のiOS開発用/配布用署名IDとともに使うことになります。

必要なリソースを確認

Assets.xcassetsを覗いてみる

  • 初期のAssets.xcassetsには以下のImage Setが並んでいる
  • App Icon - Large
  • App Icon - Small
  • Top Shelf Image
  • LaunchImage
  • +ボタンには以下のようなものが並んでいる (TV系のみ抜粋)
  • New Apple TV Image Stack
  • New Apple TV Image Stack Layer
  • Game Center > New Apple TV Dashboard Image
  • Game Center > New Apple TV Leaderboard
  • Game Center > New Apple TV Leaderboard Set
  • どこまでが必須か、なにに使われるものかよくわからない

ヒューマンガイドラインをナナメ読み

  • Apple TV Human Interface Guidlinesを確認
  • レイアウト
  • 1920 x 1080pixels (1080p)で作りましょう
  • @1xで作りましょう
  • 上下60pixels、左右90pixelsをあける
  • アイコン
  • 2〜5層のレイヤがもてる
  • グラデーションは上が明るく下が暗い
  • Small(ホームスクリーン用)とLarge(ストア用)が必要
  • Small: 400 x 240px(Focused/Safe zone size: 370x 222px, Unfocused size: 300 x 180px)
  • Large: 1280 x 768px
  • Top Shelf
  • 1920 x 720px
  • Game Center
  • Achievement Icon: 320 x 320px(直径200pxの円にトリミング)
  • Dashboard Artwork: 923 x 150px(最大値)
  • Leaderboard Artwork: 659 x 371px (Focused/Safe zone size:618 x 348px, Unfocused size: 548 x 309px)
  • Leaderboard Artworkは1〜3層で作る
  • Launch Image
  • 1920 x 1080px

画面サイズと必要なリソースまとめ

  • (数字はすべてピクセル)
  • レイアウト
  • 画面サイズ: 1920 x 1080 (16:9)
  • 上60、下60、左90、右90をあける
  • Icon
  • App Icon - Large: 1280 x 768
  • App Icon - small: 400 x 240
  • 2〜5層にわける
  • Top Shelf
  • 1920 x 720
  • Launch Image
  • 1920 x 1080
  • Game Center
  • Dashboard Artwork: 923 x 150
  • Leaderboard Artwork: 659 x 371 (1〜3層で作る)

SpriteKitでNodeを点滅させる

  • 点滅の動きをSKAction.sequenceで作る
  • SKAction.repeatActionForeverでループさせる
  • runActionで実行する
override func didMoveToView(view: SKView) {
    let rect = SKShapeNode(rectOfSize: CGSizeMake(50.0, 50.0))
    rect.fillColor = UIColor.redColor()
    rect.position = CGPointMake(self.frame.midX, self.frame.midY)
    self.addChild(rect)

    // 点滅の場合
    let blinking = SKAction.sequence([
        SKAction.unhide(),
        SKAction.waitForDuration(0.2),
        SKAction.hide(),
        SKAction.waitForDuration(0.2)])

//        // フェードの場合
//        let fade = SKAction.sequence([
//            SKAction.fadeAlphaTo(0.0, duration: 1.00),
//            SKAction.waitForDuration(0.2),
//            SKAction.fadeAlphaTo(1.0, duration: 1.00)])

    let loop = SKAction.repeatActionForever(blinking)
    rect.runAction(loop)
}

try! Swiftの感想

感想

3月2〜4日、Swiftのカンファレンスtry! Swiftに参加した。

  • 1トーク25分なことと、こまめに休憩が入るので、トークに集中しやすかった
  • 休憩時間には、参加者/スピーカーの方々と交流することが出来て楽しかった
  • コーヒーやジュース、軽食、ランチが充実していて、満足できた
  • 同時通訳やWi-Fiが快適だった
  • niwatakoさんの聞き起こしがすごかった

プログラムを触りだして半年程度なので、参加に際しては少し悩んだのだが、とても楽しい3日間となってよかった。

iOSアプリを作る際に必要なアイコン種類のメモ

  • iOS8以上の場合
  • 必須じゃない種類も含む
  • iPad用も含む

icon

  • icon-29.png: 29x29
  • icon-29@2x.png: 58x58
  • icon-29@3x.png: 87x87
  • icon-40.png: 40x40
  • icon-40@2x.png: 80x80
  • icon-40@3x.png: 120x120
  • icon-60@2x.png: 120x120
  • icon-60@3x.png: 180x180
  • icon-76.png: 76x76
  • icon-76@2x.png: 152x152
  • icon-83.5@2x.png: 167x167
  • iTunesArtwork@2x.png: 1024x1024

AdMobメディエーションでi-mobileバナーを表示する

環境

AdMobメディエーション設定

  • AdMob管理画面でi-mobileの広告IDを登録 (詳細省略)
  • 参考

AdMob SDK組み込み

  • 通常のAdMob実装と同様に行う
  • 参考

リンカフラグの追加

  • 参考ページにはリンカフラグの追加が指示されているが、すでに追加されていた
  • Google Analytics、AdMobの設定の途中で追加された?
  • ここにはメディエーションIDを指定となっているが、見当たらないので、通常の広告ユニットIDを指定した
  • 説明ページがいろいろあってややこしい
  • 参考

バナーサイズの指定

  • 下記のようになると思われる
  • kGADAdSizeSmartBannerPortraitを指定すると、AdMob: スマートバナー、i-mobile: 320x50
  • kGADAdSizeBannerを指定すると、AdMob: 320x50、i-mobile: 320x50
  • ここには、以下のように書かれているのでkGADAdSizeSmartBannerPortraitを指定していいかは不明

AdMob 広告ネットワーク メディエーションでは現在のところ、スマート バナーは完全にサポートされていません。

i-mobile SDK組み込み

  • ここからSDKをダウンロード
  • ここここを参考に作業
  • Briding-Headerに以下の行を追加
  • SDKについてくるヘッダーファイルの記述ではエラーがでるのでここを参考に書き換えた
// for i-mobile SDK
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "ImobileSdkAds/ImobileSdkAds.h"

// for admob mediation
#import <GoogleMobileAds/GoogleMobileAds.h>
#import <GoogleMobileAds/GADBannerViewDelegate.h>
  • ImobileSdkAds.frameworklibAdapterIMobile.aをプロジェクトに組み込む
  • Add Files to "プロジェクト名"から追加したらDestinaion : Copy items if neededを聞かれずにエラーになったので、ドラッグアンドドロップで追加した

ワーニングがでる

  • App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.のメッセージがでた
  • ここには、SDK2.0.13以降はATSの設定は不要となっているが、メディエーションの場合必要なのだろうか、設定をしたらワーニングが消えた

備考/その他

  • ここに国別の設定などがのっているがまだ試していない
  • インタースティシャルは未対応らしい*
  • i-mobileバナーをスマートバナーにできない
  • 表示確認のみで、集計は未確認

iOSアプリにGoogle Analyticsを入れる

環境

  • Xcode: 7.2
  • GoogleAnalytics: 3.14.0

Google Analyticsの設定

  • 省略

ライブラリのインストール

  • ここを参考に実装をすすめる
  • cocoaPodsを利用する
  • Podfileは以下の通り
source 'http://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!

pod 'Google/Analytics', '~> 1.0.0'

target 'プロジェクト名' do

end

設定ファイルの作成

  • ここの「設定ファイルを取得」から作成
  • プロジェクトに追加する

アナリティクスの初期化

BridgingHeaderの追加

  • ナビゲータエリア > プロジェクト名のフォルダを右クリック > New File... > iOS > Source > Header Fileからヘッダーファイルを追加(ファイル名: プロジェクト名-Bridging-Header.h
  • TARGETS > プロジェクト名 > Build Settings > Swift Compiler - Code Generation > Objective-C Bridging Header$(SRCROOT)/$(PRODUCT_NAME)/プロジェクト名-Bridging-Header.hを追加
  • ヘッダーファイルの中身は#import <Google/Analytics.h>とする

didFinishLaunchingWithOptionsに設定追加

  • 参考通りに以下のコードを追加 (Xcodeの指示でvarletに変更)
// [START tracker_swift]
// Configure tracker from GoogleService-Info.plist.
var configureError:NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
        
// Optional: configure GAI options.
let gai = GAI.sharedInstance()
gai.trackUncaughtExceptions = true  // report uncaught exceptions
gai.logger.logLevel = GAILogLevel.Verbose  // remove before app release
// [END tracker_swift]

スクリーントラッキングの追加

  • 参考通りにwillAppearを追加
  • 参考にはlet name = "Pattern~\(self.title!)"で名前を取り、valueにnameをいれていたが、fatal error: unexpectedly found nil while unwrapping an Optional valueとエラーが出てしまうため、文字列を入力する形にした
override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(true)
    
//        let name = "Pattern~\(self.title!)"
        
    // The UA-XXXXX-Y tracker ID is loaded automatically from the
    // GoogleService-Info.plist by the `GGLContext` in the AppDelegate.
    // If you're copying this to an app just using Analytics, you'll
    // need to configure your tracking ID here.
    // [START screen_view_hit_swift]
    let tracker = GAI.sharedInstance().defaultTracker
    tracker.set(kGAIScreenName, value: "ViewController")
        
    let builder = GAIDictionaryBuilder.createScreenView()
    tracker.send(builder.build() as [NSObject : AnyObject])
    // [END screen_view_hit_swift]
}