Imrazor's Blog

Stay Hungry, Stay Foolish

Hand Off初探

iOS8的一个新功能是hand off,这个功能可以允许用户在多端继续他的某个任务,比如iPhone上写笔记写了一半,到家后使用iPad,从锁屏或后台打开程序自动导航到记笔记界面,并且可以继续刚才的笔记内容写。

Alt text

Hand off功能要求用户的几个设备有相同的iCloud账号,打开蓝牙。对于开发者,我们的应用必须是在同一个team ID下,程序拥有相同的iCloud container。

Hand off中一个很重要的类就是NSUserActivity,通过这个类的对象,我们可以把A设备当前的活动传给B设备。

这个类有着非常简单易用的API,分别为创建、对流的支持、activity数据及activity的传送。下面的代码就创建了一个NSUserActivity:

1
2
3
4
    self.activity = [[NSUserActivity alloc] initWithActivityType:@"io.github.volcan1987.test"];
    self.activity.delegate = self;
    self.activity.webpageURL = [NSURL URLWithString:@"http://www.baidu.com"];
    self.activity.userInfo = @{@"data":textField.text};

对象创建好后,让我们调用[self.activity becomeCurrent];的时候,如果另一个设备安装了响应此activity的App,那么另一台设备的锁屏下或是后台就会显示这个程序的图标,否则就会显示safari的图标(因为我们指定了webpageURL)

如果要让App响应对应的activity,需要在AppDelegate里实现如下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (BOOL)application:(UIApplication *)application
continueUserActivity: (NSUserActivity *)userActivity
 restorationHandler: (void (^)(NSArray *))restorationHandler {

    BOOL handled = NO;

    // Extract the payload
    NSString *type = [userActivity activityType];
    NSString *title = [userActivity title];
    NSDictionary *userInfo = [userActivity userInfo];

    // Assume the app delegate has a text field to display the activity information
    NSLog(@"User activity is of type %@, has title %@, and user info %@", type, title, userInfo);

    restorationHandler(@[self.window.rootViewController]);

    handled = YES;

    return handled;
}

其中restorationHandler参数中的对象应该实现restoreUserActivityState:这个方法来进行后续的动作,在这里,我的root view controller只是简单的将数据显示出来

1
2
3
4
- (void)restoreUserActivityState:(NSUserActivity *)activity
{
    self.field.text = activity.userInfo[@"data"];
}

到此,一次完整的activity交互就完成了。通过观察,数据的交互应该是通过蓝牙传输的。本文的demo可以在 这里 找到

Comments