LIFULL Creators Blog

「株式会社LIFULL(ライフル)」の社員によるブログです。

WWDC 2017 - DAY FOUR -

昨日の記事に引き続きこんにちは。iOS開発Gの塙です。 4日目ともなると現地のエンジニアは今回発表された機能の実装をだいぶ進めているみたいです。 外のベンチにはただ空を眺めている方、俯く方、頭を抱える方。十人十色です。美しいですね。

皆さんも実装が詰まって何時間も考える時があると思います。 そんな時WWDCでは問題解決をしてくれるスペシャリストが待機している場所があるのです。 今回はその場所の話とセッションの話をメインで書きたいと思います。

f:id:LIFULL-hanawat:20170609151658j:plain

これは通称"小田原"と呼ばれているオレンジジュースで、ほぼ毎年WWDCで配られています。ジョブスが好きだったとか。ではまずセッションのお話から。

Focus Interaction in tvOS 11

今回KeynoteではAmazon Prime Videoの話しかされなかったtvOSですが、API Referenceを見るとそれなりに変更があったので聴きに行きました。 セッションの席がガラガラですね、大丈夫でしょうか。

※ LIFULL HOME’S アプリはtvOSにも対応しています。

最新バージョンではCoreBluetoothFlyoverに対応しております。AppleTVをお持ちの方はぜひダウンロードしてみてください。

f:id:LIFULL-hanawat:20170609151917j:plain

Focus Update Notifications

  • Focusに対して更新処理が走る時に通知を受け取れるようになった
  • Focusの移動に失敗した場合の通知も追加されている
static let UIFocusDidUpdate: NSNotification.Name

static let UIFocusMovementDidFail: NSNotification.Name

Protocol Extensions

UIFocusItemプロトコルが拡張されて、自身が今Focusされているか確認できます。

var isFocused: Bool { get }

UIFocusEnvironmentプロトコルが拡張されて、自身が他のFocusEnvirionmentに含まれているか確認できます。

func contains(_ environment: UIFocusEnvironment) -> Bool

Focus Animations

Focusの移動時にアニメーションを定義できます。

// for focusing item
func addCoordinatedFocusingAnimations(_ animations: ((UIFocusAnimationContext) -> Void)?,
                           completion: (() -> Void)? = nil)

// for unfocusing item
func addCoordinatedUnfocusingAnimations(_ animations: ((UIFocusAnimationContext) -> Void)?,
  completion: (() -> Void)? = nil)

Runs the specified set of animations together with the system animations for adding focus to an item.

今まで下記のようにやっていた処理との違いはシステムの定義したアニメーションと一緒に行うかどうかでしょうか。

func didUpdateFocus(
  in context: UIFocusUpdateContext,
    with coordinator: UIFocusAnimationCoordinator) {

  if context.nextFocusedView is Self {

    coordinator.addCoordinatedAnimations({
      // Focused Animation
    }, completion: nil)

  } else if context.previouslyFocusedView is Self {

    coordinator.addCoordinatedAnimations({
      // Unfocused Animation
    }, completion: nil)
  }
}

またFocusの移動スピードに合わせてアニメーションの早さを調節されるそうです。

Custom Focus Sounds

  • フォーカス移動時に流れる音をカスタマイズできるようになった
  • UIFocusSystemというクラスが追加されたことによって可能になった

UIFocusSystem

現在のユーザーインタフェース上にあるフォーカスの状態を管理するクラス。 今まではupdateFocusIfNeededのように自身のフォーカスの更新しかできませんでしたが、このクラスは全てのフォーカスの更新ができます。

func requestFocusUpdate(to environment: UIFocusEnvironment)

func updateFocusIfNeeded()

また、現在フォーカスされているオブジェクトやどのFocusEnvirionmentに含まれているかもチェックもできます。

weak var focusedItem: UIFocusItem? { get }

class func environment(_ environment: UIFocusEnvironment,
  contains otherEnvironment: UIFocusEnvironment) -> Bool

その中にひとつだけフォーカス時の音を変更するメソッドがあります。 ローカルのサウンドファイルのURLと識別子を指定するだけでアプリ内にグローバルに反映されます。ただし、サウンドファイルは30秒未満でなくてはいけません。

class func register(_ soundFileURL: URL,
  forSoundIdentifier identifier: UIFocusSoundIdentifier)

下記のようなサウンドの調整も行われるようです。

  • スピードに合わせて音量が変更される
  • フォーカスの移動方向(左右)によっても異なる

また、オブジェクトがフォーカスを更新するタイミングでカスタムとデフォルトとなしの切り替えもできます。例えばサイズの異なるオブジェクトになる場合は音を変えるというのは良いプラクティスだそうです。

// UIFocusEnvironment Protocol
optional func soundIdentifierForFocusUpdate(in context: UIFocusUpdateContext) -> UIFocusSoundIdentifier?

Support for SceneKit

SceneKitとSpriteKitでもフォーカスを扱えるようになった UIFocusItemの継承クラスにSKNodeSCNodeが追加されている。

Focus Update Logging

-UIFocusUpdateLoggingEnabled=YESの設定をXcode上で行うとフォーカスに関するログを吐く。

UIFocusDebugger

フォーカスをデバッグするためのクラスが追加されました。 po UIFocusDebugger.foo()でFocusの状態を見たり検証したりできます。

  • status(): フォーカスされているオブジェクトに関する情報
  • simulateFocusUpdateRequest(from: _): 特定のFocusEnvirionmentからフォーカスの更新を試せる
  • checkFocusability(for: _): Focusできるかチェックできる(できない場合は理由も分かる)
  • help(): 使用できるコマンド(メソッド)全部出してくれる

結構やりたかったことや実装が面倒だった部分が解消されている気がします。何より捉えにくいフォーカスをデバッグしやすくなったのは嬉しいです。

qiita.com

Lab

普段実装で躓いたことはありませんか?ない人なんていないですよね。 このWWDC期間中であれば、そのUIKit、Foundation、iOS、watchOS…などの開発者に相談できるんです。 そこで答えが出ないなら諦めがつきますもんね。頭を抱えて作業が進まない状況を無くせます。

f:id:LIFULL-hanawat:20170609151720j:plain

ラボにも色々な種類があり、昨日の記事で紹介したUIデザインラボもその中のひとつです。 基本的に技術系のラボは予約はいらず、その場でじっくり実装しながら聞いたりできます。

Design and Accessibility

  • User Interface Design
  • Accessibility Design

App Store

  • App Review
  • Apple Developer Program Support
  • Apple Marketing Communications
  • Business and Marketing
  • Export Compliance
  • iTunes Connect
  • Search Ads

Podcast

  • Apple Podcasts Studio

Develop

  • Core Image Lab
  • Source Control, Simulator, Testing, and Continuous Integration with Xcode Lab
  • Game Center Lab
  • Installer Lab
  • ClockKit and WatchKit Lab, etc…

もっともっとあります。キリがないくらい様々な技術情報のラボがあります。 え?英語が話せない?もちろん私も話せません。ですが、最初の質問を準備していけばあとはノリとコードで伝わります。 私は質問していく時に毎回このようなフォーマットで持って行きました。

    func foo() {
        /*
         ここに現状の実装の説明とやりたいことを書く
         */
        doSomething()
    }

    func bar() {
        /*
         ここにトライしたけどダメだったことを書く
         実装はコメントアウトしておく
         */
        // doAnything()
    }

Appleのデベロッパーと話せる機会なんてそうそうないのでWWDCに行くときはぜひ質問を投げに行ってみてください。 では、最終日も楽しく元気に学びましょう。

f:id:LIFULL-hanawat:20170609151742j:plain

今日はよくわからないファミレスのような場所で書いています。このタコスのようなポテト素敵な味がします。アディオス。