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

Being a tvOS developer

Being a tvOS developer

Presenting what my daily development looks like as a tvOS dev.
The talk was took place at yidev meetup, in Yokohama, Japan.

Avatar for toshi0383

toshi0383

March 05, 2016
Tweet

More Decks by toshi0383

Other Decks in Technology

Transcript

  1. Toshihiro Suzuki 4 ླ໦ ढ़༟ 4 @toshi0383 4 iOS/Mac/tvOS develper

    4 currently at NEXTSCAPE 4 try! Swift attendee © Toshihiro Suzuki 2016 2
  2. Toshihiro Suzuki 4 Drives go-kart so fast too farious 4

    Drummer/Trumpetter 4 Snowboarder 4 used to be a Pokemon Master © Toshihiro Suzuki 2016 3
  3. Will talk about what it means to be a tvOS

    developer © Toshihiro Suzuki 2016 4
  4. tvOS is a new platform We can use the newest

    APIs © Toshihiro Suzuki 2016 5
  5. has very sofistcated user interface. It's much easier than iOS

    to write great apps. © Toshihiro Suzuki 2016 9
  6. Today's topics will be 4 What my daily development look

    like 4 What my codebase look like © Toshihiro Suzuki 2016 13
  7. The App 4 is kind of like Netflix. 4 Already

    available on iOS/Android, AndroidTV, TVs 4 SI, not own app. 4 We're middle of development. © Toshihiro Suzuki 2016 15
  8. Development I will cover ... - Managing Libraries - Testing

    - Beta Distributing - Shipping © Toshihiro Suzuki 2016 17
  9. Carthage $ cat Cartfile github "ReactiveKit/ReactiveUIKit" "master" github "ReactiveKit/ReactiveKit" "master"

    github "ReactiveKit/ReactiveFoundation" "master" github "rs/SDWebImage" "master" github "ReactKit/SwiftState" ~> 4.0.0 github "cbpowell/MarqueeLabel-Swift" github "duemunk/Async" github "ikesyo/Himotoki" ~> 1.5 github "ishkawa/APIKit" ~> 1.1.2 github "realm/realm-cocoa" github "radex/SwiftyUserDefaults" "master" github "malcommac/SwiftDate" I checkin Carthage/Build/tvOS to repo. Update once in a while. ! git history data gets larger " CI build is fast © Toshihiro Suzuki 2016 19
  10. Plain XCTest and UITest 4 runs on Bitrise on every

    git-push 4 mostly tests for models 4 trying to write some for PlayerViewController © Toshihiro Suzuki 2016 23
  11. PlayerViewControllerTests.swift func test003DidAppear() { let root = UIViewController() let nav

    = UINavigationController(rootViewController: root) UIApplication.sharedApplication().keyWindow?.rootViewController = nav let ex = expectationWithDescription("PlayerViewController viewDidAppear") nav.presentViewController(vc, animated: true) {[unowned self] in XCTAssert(self.vc.machine.state == .Preparing) ex.fulfill() } waitForExpectationsWithTimeout(2.0, handler: nil) } © Toshihiro Suzuki 2016 24
  12. UITest fails a lot due to 4 Server introduced API

    bug 4 assertionFailure() or fatalError() 4 Unstable Simulator © Toshihiro Suzuki 2016 26
  13. Solution for force crashing /// Calls assertionFailure unless isRunningTests() is

    true /// This is useful in such case like when /// unstable API causes UITests failure. (which happens like always...) /// - parameter msg: func assertionError(msg: String = "") { if !isRunningTests() { assertionFailure(msg) } } © Toshihiro Suzuki 2016 27
  14. isRunningTests() /// Detects if app is running xctest /// -

    returns: true if running xctest func isRunningTests() -> Bool { let env = NSProcessInfo.processInfo().environment if let _ = env["UITest"] { return true } if let path = env["XCInjectBundle"] { return NSString(string: path).pathExtension == "xctest" } return false } © Toshihiro Suzuki 2016 28
  15. "UITest" env variable /// HogeUITests.swift func setup() { ... let

    app = XCUIApplication() app.launchEnvironment["UITest"] = "" © Toshihiro Suzuki 2016 29
  16. tvOS Simulator often hangs up Also, DerivedData causes weird compile

    errors sometimes © Toshihiro Suzuki 2016 30
  17. Solution # ~/.bashrc export DERIVED=~/Library/Developer/Xcode/DerivedData alias resetd='rm -rf $DERIVED/*' alias

    resetdd='resetd && snapshot reset_simulators' export SNAPSHOT_FORCE_DELETE=true I run this at least 10 times a day. © Toshihiro Suzuki 2016 31
  18. Makefile TEST_DESTINATION=-destination "platform=tvOS Simulator,name=Apple TV 1080p,OS=latest" TEST=xcodebuild $(XCODEFLAGS) -scheme $(SCHEME)

    clean test $(TEST_DESTINATION) .PHONY: test beta release archive clean ipa-beta ipa ship test: set -o pipefail $(TEST) © Toshihiro Suzuki 2016 36
  19. Makefile archive: ./script/check-xcode-version.sh if [ $? -ne 0 ];then exit

    1;fi ./script/prepare_for_release.sh if [ ! -d $(BUILD_DIR)/script ];then mkdir -p $(BUILD_DIR)/script;fi xcodebuild -project $(PROJECT).xcodeproj -scheme $(SCHEME) \ -destination "generic/platform=tvOS" \ -xcconfig ./config/App-tvOS.xcconfig \ -archivePath $(ARCHIVE_PATH) \ PROVISIONING_PROFILE=$(PROVISIONING_PROFILE) \ -verbose \ archive | xcpretty --color ipa: xcodebuild -exportArchive -archivePath $(ARCHIVE_PATH) -exportPath $(BUILD_DIR) \ -exportOptionsPlist $(EXPORT_OPTION_PLIST) \ PROVISIONING_PROFILE=$(PROVISIONING_PROFILE) \ -destination "generic/platform=tvOS" © Toshihiro Suzuki 2016 37
  20. cmake is actually useful Comparing to fastlane, - less dependencies

    (plain xcodebuild commands) - runs faster It gets the job done. © Toshihiro Suzuki 2016 38
  21. GitHub release page fastlane ios upload ipa:$(IPA_PATH) My boss will

    download this app and hand it to testers. © Toshihiro Suzuki 2016 41
  22. How to install a beta app to device You always

    need a Xcode © Toshihiro Suzuki 2016 42
  23. make ship (haven't shipped yet) 4 Create ipa. 4 Copy

    howtobuild.txt and Makefile. 4 Zip all of above and ship it to customer. 4 A Resign.sh is embedded. Looks like sigh resign works for tvOS, too. Detailed post in Japanese © Toshihiro Suzuki 2016 44
  24. Use typealias for important types typealias JSON = [String: AnyObject]

    typealias ProductId = String typealias GenreId = String struct Product: Decodable { let productId: ProductId? let productQualityType: ProductQuality? © Toshihiro Suzuki 2016 49
  25. Write comment, write tests You will forget everything in next

    week. I guarantee. © Toshihiro Suzuki 2016 50
  26. It's okay. enum RequestSortType: Int { case ৽ணॱ = 1,

    ̑̌Իॱ = 3, ਓؾॱ = 4 } switch sortType { case .৽ணॱ: break case .̑̌Իॱ: break case .ਓؾॱ: break } © Toshihiro Suzuki 2016 51
  27. Reactive // ReactiveKit (going to switch to RxSwift) func startLaunchSequence()

    { combineLatest(validateDeviceTime, agreement, updateDatabase()) .observe(on: ImmediateExecutionContext) {[weak self] e in switch e { case .Next(let value): LOG("next: \(value)") case .Failure(let error): LOG("error: \(error)") self?.launchCompletion(.Failure(error)) case .Success: LOG("success") self?.launchCompletion(.Success()) } }.disposeIn(rbag) } © Toshihiro Suzuki 2016 52
  28. Separate public APIs into small extensions // MARK: Public API

    extension APICacheBatch { static var CompletedNotification = "APICacheBatchCompletedNotification" static func updateAllImmediately() { sharedInsance.updateAll(force: true) } } © Toshihiro Suzuki 2016 53
  29. Wrap Up what it means to be a tvOS developer

    4 daily development 4 codebase © Toshihiro Suzuki 2016 54
  30. BTW, if you want a TVML and native hybrid tvOS

    app I've heard of TVMLKitchen. © Toshihiro Suzuki 2016 60