Upload
yuichi-yoshida
View
1.602
Download
9
Embed Size (px)
DESCRIPTION
yidev #16で発表した資料です.
Citation preview
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
自己紹介2tchの中の人
• iOS好きです • 2tch(2ちゃんねるビューア) • iOS SDK Hacksなど
• 研究 • コンピュータビジョン • 機械学習
• 研究・開発 • 画像検索サービス • 車向けのサービスやハードウェア
Demo2tch version 6.3.1
What is Handoff?継続って訳すのやめて欲しい
Handoffの種類
• Safariを呼ぶ • URLを渡すだけ
• ネイティブアプリケーション • 受信側にコードが必要 • インストールされていれば自動起動する
• Safariからネイティブアプリケーションを呼ぶ • 署名した対応アプリ一覧JSONが必要
?
準備• 対応ハードウェアを買う
• 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世代)
準備
• iCloudに登録する • Bluetoothをオンにする • Wi-Fiをオンにする
準備
• iCloudに登録する • Bluetoothをオンにする • Wi-Fiをオンにする
DemoSafariで試す
ネイティブアプリからSafariへ
• とっても簡単 • NSUserActivityクラス • - webpageURL
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
[_activity becomeCurrent];
[_activity invalidate];
ネイティブアプリケーション• Info.plist
• NSUserActivityTypesに受け取る識別子を追加 • 逆ドメイン形式 • com.sonson.HandoffSample
• UIApplicationDelegate(NSApplicationDelegate) • application:willContinueUserActivityWithType: • application:didFailToContinueUserActivityWithType:error: • application:continueUserActivity:restorationHandler:
• OSXの場合 • 署名必須(Developer IDでもよいみたい)
NSUserActivity
_activity = [[NSUserActivity alloc] initWithActivityType:@"com.sonson.OSX.HandoffSample"]; _activity.title = @"Browsing"; _activity.userInfo = @{@"ImageSize":@(_imageBinary.length)}; [_activity becomeCurrent];
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; }
ViewController restoration
• UIResponder • - 新しいデリゲートメソッド • - restoreUserActivityState:
• void(^)(NSArray *restorableObjects) • restoreするUIResponderのサブクラスをつっこむ • 自動的にrestoreUserActivityState:が呼ばれる • 引数はNSUserActivityオブジェクト
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
うまくいかない?Bug?
• 対応機種ですか? • iCloudは同じアカウントになっていますか? • NSUserActivityのインスタンスはありますか? • 他の機器とHandoffが混線していませんか?
Further more, HandoffCommunicate with.……
• ブラウザからHandoff経由でアプリを起動する • Webページ閲覧中にiOSデバイスのアプリを起動
• 3つのデータ送受信 • userInfo • iCloud • NSStream
Further more, HandoffSafariからのHandoff
• iOS側のentitlementにサーバのドメインを追加 • JSONを作る • JSONに署名する
• iOSの持つリストに入ってる認証局の証明書が必要 • 実はApple自身が認証局になってる • なのでAppleの開発者の署名でおk
• httpsで通信できるサーバにJSONを置く • ルートに置く必要がある
Further more, Handoff大きなデータはどうするか?
• userInfo • NSArray, NSData, NSDate, NSDictionary, NSNull,
NSNumber, NSSet, NSString, NSURL
• iCloud • UIDocumentが自動的にNSUserActivityを生成 • CFBundleDocumentTypes
• NSUbiquitousDocumentUserActivityType
• NSStream • 簡単
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];
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; }
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 }
DemoHandoff from Safari Send a picture via NSStream
まとめYou get to try it.
• Handoff • 使えるデバイスは限定される • SafariにURLを渡すHandoff • ネイティブアプリケーション同士のHandoff • Safariから渡すHandoff • 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