Getting started with Handoff
-
Upload
yuichi-yoshida -
Category
Technology
-
view
1.601 -
download
9
description
Transcript of Getting started with Handoff
![Page 1: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/1.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/2.jpg)
自己紹介2tchの中の人
• iOS好きです • 2tch(2ちゃんねるビューア) • iOS SDK Hacksなど
• 研究 • コンピュータビジョン • 機械学習
• 研究・開発 • 画像検索サービス • 車向けのサービスやハードウェア
![Page 3: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/3.jpg)
Demo2tch version 6.3.1
![Page 4: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/4.jpg)
What is Handoff?継続って訳すのやめて欲しい
![Page 5: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/5.jpg)
Handoffの種類
• Safariを呼ぶ • URLを渡すだけ
• ネイティブアプリケーション • 受信側にコードが必要 • インストールされていれば自動起動する
• Safariからネイティブアプリケーションを呼ぶ • 署名した対応アプリ一覧JSONが必要
![Page 6: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/6.jpg)
![Page 7: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/7.jpg)
![Page 8: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/8.jpg)
![Page 9: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/9.jpg)
?
![Page 10: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/10.jpg)
準備• 対応ハードウェアを買う
• 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](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/11.jpg)
準備
• iCloudに登録する • Bluetoothをオンにする • Wi-Fiをオンにする
![Page 12: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/12.jpg)
準備
• iCloudに登録する • Bluetoothをオンにする • Wi-Fiをオンにする
![Page 13: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/13.jpg)
DemoSafariで試す
![Page 14: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/14.jpg)
ネイティブアプリからSafariへ
• とっても簡単 • NSUserActivityクラス • - webpageURL
![Page 15: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/15.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/16.jpg)
![Page 17: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/17.jpg)
[_activity becomeCurrent];
![Page 18: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/18.jpg)
[_activity invalidate];
![Page 19: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/19.jpg)
ネイティブアプリケーション• 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](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/20.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/21.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/22.jpg)
ViewController restoration
• UIResponder • - 新しいデリゲートメソッド • - restoreUserActivityState:
• void(^)(NSArray *restorableObjects) • restoreするUIResponderのサブクラスをつっこむ • 自動的にrestoreUserActivityState:が呼ばれる • 引数はNSUserActivityオブジェクト
![Page 23: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/23.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/24.jpg)
うまくいかない?Bug?
• 対応機種ですか? • iCloudは同じアカウントになっていますか? • NSUserActivityのインスタンスはありますか? • 他の機器とHandoffが混線していませんか?
![Page 25: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/25.jpg)
Further more, HandoffCommunicate with.……
• ブラウザからHandoff経由でアプリを起動する • Webページ閲覧中にiOSデバイスのアプリを起動
• 3つのデータ送受信 • userInfo • iCloud • NSStream
![Page 26: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/26.jpg)
Further more, HandoffSafariからのHandoff
• iOS側のentitlementにサーバのドメインを追加 • JSONを作る • JSONに署名する
• iOSの持つリストに入ってる認証局の証明書が必要 • 実はApple自身が認証局になってる • なのでAppleの開発者の署名でおk
• httpsで通信できるサーバにJSONを置く • ルートに置く必要がある
![Page 27: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/27.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/28.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/29.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/30.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/31.jpg)
DemoHandoff from Safari Send a picture via NSStream
![Page 32: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/32.jpg)
まとめYou get to try it.
• Handoff • 使えるデバイスは限定される • SafariにURLを渡すHandoff • ネイティブアプリケーション同士のHandoff • Safariから渡すHandoff • Handoffの通信方法
![Page 33: Getting started with Handoff](https://reader033.fdocuments.us/reader033/viewer/2022050722/547e89c3b4af9faf158b5642/html5/thumbnails/33.jpg)
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