getting started with handoff

33
How can I do it? UIKit Yuichi Yoshida Chief engineer, DENSO IT Laboratory, Inc. #yidev20140927 @sonson_twit © 2014 Yuichi Yoshida, all rights reserved. Redistribution or public display not permitted without written permission from Yuichi Yoshida. Getting started with Hando

Upload: yuichi-yoshida

Post on 28-Nov-2014

1.599 views

Category:

Technology


9 download

DESCRIPTION

yidev #16で発表した資料です.

TRANSCRIPT

Page 1: Getting started with Handoff

How can I do it?

UIKit

Yuichi YoshidaChief engineer, DENSO IT Laboratory, Inc.

#yidev20140927

@sonson_twit

© 2014 Yuichi Yoshida, all rights reserved. Redistribution or public display not permitted without written permission from Yuichi Yoshida.

Getting started with Handoff

Page 2: Getting started with Handoff

自己紹介2tchの中の人

• iOS好きです • 2tch(2ちゃんねるビューア) • iOS SDK Hacksなど

• 研究 • コンピュータビジョン • 機械学習

• 研究・開発 • 画像検索サービス • 車向けのサービスやハードウェア

Page 3: Getting started with Handoff

Demo2tch version 6.3.1

Page 4: Getting started with Handoff

What is Handoff?継続って訳すのやめて欲しい

Page 5: Getting started with Handoff

Handoffの種類

• Safariを呼ぶ • URLを渡すだけ

• ネイティブアプリケーション • 受信側にコードが必要 • インストールされていれば自動起動する

• Safariからネイティブアプリケーションを呼ぶ • 署名した対応アプリ一覧JSONが必要

Page 6: Getting started with Handoff
Page 7: Getting started with Handoff
Page 8: Getting started with Handoff
Page 9: Getting started with Handoff

Page 10: Getting started with Handoff

準備• 対応ハードウェアを買う

• MacBook Air (Mid 2011以降) • MacBook Pro (Mid 2012以降) • Retina MacBook Pro (全機種) • iMac (Late 2012以降) • Mac Mini (Mid 2011以降) • Mac Pro (Late 2013以降)

• http://www.ipadmod.netより • iOS

• iPhone 5以降、iPad(第4世代)、iPad Air、iPad mini、iPad

mini Retinaディスプレイモデル、iPod touch(第5世代)

Page 11: Getting started with Handoff

準備

• iCloudに登録する • Bluetoothをオンにする • Wi-Fiをオンにする

Page 12: Getting started with Handoff

準備

• iCloudに登録する • Bluetoothをオンにする • Wi-Fiをオンにする

Page 13: Getting started with Handoff

DemoSafariで試す

Page 14: Getting started with Handoff

ネイティブアプリからSafariへ

• とっても簡単 • NSUserActivityクラス • - webpageURL

Page 15: Getting started with Handoff

NSUserActivity

@interface ViewController () { NSUserActivity *_activity; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; _activity = [[NSUserActivity alloc] initWithActivityType:@"com.sonson.HandoffSample"]; _activity.webpageURL = [NSURL URLWithString:@"http://www.apple.com"]; _activity.title = @"Browsing"; [_activity becomeCurrent]; }

@end

Page 16: Getting started with Handoff
Page 17: Getting started with Handoff

[_activity becomeCurrent];

Page 18: Getting started with Handoff

[_activity invalidate];

Page 19: Getting started with Handoff

ネイティブアプリケーション• Info.plist

• NSUserActivityTypesに受け取る識別子を追加 • 逆ドメイン形式 • com.sonson.HandoffSample

• UIApplicationDelegate(NSApplicationDelegate) • application:willContinueUserActivityWithType: • application:didFailToContinueUserActivityWithType:error: • application:continueUserActivity:restorationHandler:

• OSXの場合 • 署名必須(Developer IDでもよいみたい)

Page 20: Getting started with Handoff

NSUserActivity

_activity = [[NSUserActivity alloc] initWithActivityType:@"com.sonson.OSX.HandoffSample"]; _activity.title = @"Browsing"; _activity.userInfo = @{@"ImageSize":@(_imageBinary.length)}; [_activity becomeCurrent];

Page 21: Getting started with Handoff

UIApplicationDelegate

- (BOOL)application:(NSApplication *)application willContinueUserActivityWithType:(NSString *)activityType { if ([activityType isEqualToString:@"com.sonson.OSX.HandoffSample"]) return YES; return NO; }

- (BOOL)application:(NSApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray *restorableObjects))handler {

// Obtained information from userInfo. NSNumber *imageSize = userActivity.userInfo[@"ImageSize"];

handler(@[]); // restore view controllers return YES; }

Page 22: Getting started with Handoff

ViewController restoration

• UIResponder • - 新しいデリゲートメソッド • - restoreUserActivityState:

• void(^)(NSArray *restorableObjects) • restoreするUIResponderのサブクラスをつっこむ • 自動的にrestoreUserActivityState:が呼ばれる • 引数はNSUserActivityオブジェクト

Page 23: Getting started with Handoff

Restoration- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray *restorableObjects))restorationHandler { // get or create view controller objects. id viewControllerA = nil; // left pain id viewControllerB = nil; // right pain // start to restore restorationHandler(@[viewControllerA, viewControllerB]); return YES; }

@implementation ViewControllerAClass - (void)restoreUserActivityState:(NSUserActivity *)activity { // restore left pain view using NSUserActivity object } @end

@implementation ViewControllerBClass - (void)restoreUserActivityState:(NSUserActivity *)activity { // restore right pain view using NSUserActivity object } @end

Page 24: Getting started with Handoff

うまくいかない?Bug?

• 対応機種ですか? • iCloudは同じアカウントになっていますか? • NSUserActivityのインスタンスはありますか? • 他の機器とHandoffが混線していませんか?

Page 25: Getting started with Handoff

Further more, HandoffCommunicate with.……

• ブラウザからHandoff経由でアプリを起動する • Webページ閲覧中にiOSデバイスのアプリを起動

• 3つのデータ送受信 • userInfo • iCloud • NSStream

Page 26: Getting started with Handoff

Further more, HandoffSafariからのHandoff

• iOS側のentitlementにサーバのドメインを追加 • JSONを作る • JSONに署名する

• iOSの持つリストに入ってる認証局の証明書が必要 • 実はApple自身が認証局になってる • なのでAppleの開発者の署名でおk

• httpsで通信できるサーバにJSONを置く • ルートに置く必要がある

Page 27: Getting started with Handoff

Further more, Handoff大きなデータはどうするか?

• userInfo • NSArray, NSData, NSDate, NSDictionary, NSNull,

NSNumber, NSSet, NSString, NSURL

• iCloud • UIDocumentが自動的にNSUserActivityを生成 • CFBundleDocumentTypes

• NSUbiquitousDocumentUserActivityType

• NSStream • 簡単

Page 28: Getting started with Handoff

Further more, Handoff送信側

_activity = [[NSUserActivity alloc] initWithActivityType:@"com.sonson.OSX.HandoffSample"]; _activity.title = @"Browsing"; _activity.userInfo = @{@"ImageSize":@(_imageBinary.length)}; _activity.supportsContinuationStreams = YES; _activity.delegate = self; [_activity becomeCurrent];

Page 29: Getting started with Handoff

Further more, Handoff受信側

- (BOOL)application:(NSApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray *restorableObjects))restorationHandler {

[userActivity getContinuationStreamsWithCompletionHandler: ^(NSInputStream *inputStream, NSOutputStream *outputStream, NSError *error) { if (error == nil) { _inputStream = inputStream; _outputStream = outputStream; [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [_outputStream open]; [_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [_inputStream open]; // communicate... } else { // error handling } }]; return YES; }

Page 30: Getting started with Handoff

Further more, HandoffNSUserActivityDelegate

- (void)userActivity:(NSUserActivity *)userActivity didReceiveInputStream:(NSInputStream *)inputStream outputStream:(NSOutputStream *)outputStream {

_outputStream = outputStream; [_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [_outputStream open]; // send data }

Page 31: Getting started with Handoff

DemoHandoff from Safari Send a picture via NSStream

Page 32: Getting started with Handoff

まとめYou get to try it.

• Handoff • 使えるデバイスは限定される • SafariにURLを渡すHandoff • ネイティブアプリケーション同士のHandoff • Safariから渡すHandoff • Handoffの通信方法

Page 33: Getting started with Handoff

More Information

Yuichi Yoshidahttp://github.com/sonsongithub/@sonson_twit

sonson.jphttp://sonson.jp

Apple Handoff プログラミングガイドhttps://developer.apple.com/jp/devcenter/ios/library/ documentation/HandoffProgrammingGuide.pdf