Upgrade to Pro — share decks privately, control downloads, hide ads and more …

📺

 📺

Introduction to tvOS development, given at try! Swift 2016 in Tokyo. 🇯🇵

9d2ea021919ff81e02d48530aae191bd?s=128

Boris Bügling

March 02, 2016
Tweet

Transcript

  1. ! TRY! SWIFT, MARCH 2016 BORIS BÜGLING - @NEONACHO

  2. None
  3. COCOAPODS

  4. CONTENTFUL

  5. None
  6. “‘I’d like to create an integrated television set that is

    completely easy to use,’ he told me. [...] ‘It will have the simplest user interface you could imagine. I finally cracked it.’”
  7. OCTOBER 21, 2011

  8. SEPTEMBER 9, 2015

  9. None
  10. None
  11. The future of TV is iOS

  12. 1 1 https://twitter.com/davidolesch/status/656126103921160192

  13. WEBKIT

  14. MULTIPEERCONNECTIVITY

  15. STORAGE LIMITATIONS ▸ app is limited to 200 MB ▸

    500 KB of persistent storage (NSUserDefaults) ▸ Use iCloud ▸ Use On-Demand resources
  16. PORTING EXISTING APPS

  17. COCOAPODS ▸ Supports tvOS since 0.39.0 ▸ New platform: platform

    :tvos, '9.0'
  18. PODS NOT SUPPORTING TVOS If you are adventurous ! https://github.com/orta/cocoapods-expert-difficulty

  19. SPRITEKIT EXAMPLE

  20. None
  21. DOOM CLASSIC ▸ UIKit changes (UIAlertView, UISlider) ▸ AudioSession isn't

    available ▸ Newer C++ compiler
  22. NIBS ! If you don't feel like copy-pasting stuff between

    NIBs ! https://github.com/neonichu/bohne
  23. NO DIRECT MANIPULATION

  24. FOCUS ENGINE UIButton().canBecomeFocused() // == true or false UIButton().focused //

    == true or false UIScreen.mainScreen().focusedView // nil or the view in focus
  25. DEMO

  26. REACTING TO FOCUS CHANGES func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator)

    context.nextFocusedView // the view which gets the focus context.previouslyFocusedView // the view which had the focus func addCoordinatedAnimations(_ animations: (() -> Void)?, completion completion: (() -> Void)?)
  27. CUSTOMFOCUSVIEW class CustomFocusView: UIView { override func canBecomeFocused() -> Bool

    { return true } }
  28. CUSTOMFOCUSVIEW override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) { coordinator.addCoordinatedAnimations({

    // ... }, completion: nil) }
  29. CUSTOMFOCUSVIEW let duration = UIView.inheritedAnimationDuration() UIView.animateWithDuration(duration, animations: { if context.nextFocusedView

    == self { self.backgroundColor = UIColor.redColor() } if context.previouslyFocusedView == self { self.backgroundColor = UIColor.whiteColor() } })
  30. DEBUGGING FOCUS print(view.performSelector("_whyIsThisViewNotFocusable")) e.g. for a UILabel Unmanaged<AnyObject>(_value: ISSUE: This

    view has userInteractionEnabled set to NO. Views must allow user interaction to be focusable. ISSUE: This view returns NO from -canBecomeFocused. )
  31. GOOD PLACES FOR BREAKPOINTS func shouldUpdateFocusInContext(_ context: UIFocusUpdateContext) -> Bool

    func didUpdateFocusInContext(_ context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator)
  32. GESTURES AND BUTTON PRESSES let tapRecognizer = UITapGestureRecognizer(target: self, action:

    "tapped:") let pressTypes = [NSNumber(integer: UIPressType.PlayPause.rawValue)] tapRecognizer.allowedPressTypes = pressTypes; self.view.addGestureRecognizer(tapRecognizer) let swipeRecognizer = UISwipeGestureRecognizer(target: self, action: "swiped:") swipeRecognizer.direction = .Right self.view.addGestureRecognizer(swipeRecognizer)
  33. LOWER-LEVEL API: UIPress Very similar to UITouch-based API in iOS

    func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) func pressesEnded(presses: Set<UIPress>, withEvent event: UIPressesEvent?) func pressesChanged(presses: Set<UIPress>, withEvent event: UIPressesEvent?) func pressesCancelled(presses: Set<UIPress>, withEvent event: UIPressesEvent?)
  34. TEXT INPUT

  35. SIRI?

  36. HANDOFF IS ALSO NOT SUPPORTED

  37. https://github.com/rsattar/Voucher

  38. GAME CONTROLLERS

  39. None
  40. SIRI REMOTE IS ALSO A GAME CONTROLLER ▸ Profile GCMicroGamepad

    ▸ Touch surface is a dpad ▸ Two action buttons ▸ Motion (GCMotion) ▸ Seems not to work in the simulator
  41. NSNotificationCenter.defaultCenter().addObserverForName(GCControllerDidConnectNotification, object: nil, queue: nil) { (note) in if let

    controller = note.object as? GCController { if let microPad = controller.microGamepad { microPad.dpad.valueChangedHandler = { (_, x, y) in if let paddle = self.childNodeWithName("Paddle") { paddle.position.y += CGFloat(y) } } } } }
  42. GAME CONTROLLERS WORK WITH UIKIT COMPONENTS

  43. 2.27 If your app’s core functionality doesn’t work with the

    Siri remote it will be rejected. The app may, however, provide enhanced functionality in connection with a game controller or other peripheral
  44. None
  45. A maximum of two game controllers (plus one remote) can

    be connected to an Apple TV at any given time.
  46. DEMO

  47. TVML

  48. CONCLUSION ▸ tvOS works very well ▸ If you know

    UIKit, it's easy to start ▸ Think about interaction
  49. RESOURCES ▸ https://developer.apple.com/tvos/human-interface-guidelines/ ▸ "Ich glotz TV", @avbelow, Macoun 2015

    ▸ https://speakerdeck.com/toco/intro-to-tvos ▸ http://nerds.airbnb.com/tvos-focus-engine/ ▸ https://eternalstorms.wordpress.com/2015/10/05/pair-the-apple- tv-developer-kit-siri-remote-with-xcodes-simulator/
  50. THANKS!

  51. @NeoNacho boris@contentful.com http://buegling.com/talks