一、创建today widget插件工程
today widget工程需要依赖于主工程(“宿主工程”),所以前提需要有一个能够运行的项目。然后打开工程File -> New -> Target -> Today Extension 如下图:
创建today widget工程.png
输入名称创建之后,项目中会多出以下文件夹:
(注:创建的today Extension和宿主程序的版本号需要一致,否则在上架审核的时候回报错)
创建 today widget后新增的文件夹.png
文件中的.storyboard已经被在下删除了,并且将plist文件中的NSExtensionPrincipalClass修改为页面名称:
增加拓展页面名称.png
到此,编译工程,就能够编译通过了。模拟器上能够正常运行并且看到today中有了该插件。。但是真机中还不行,因为证书不对啊。需要去开发者中心创建today widget对应的证书 (证书还需要加入APP Group,才能实现today widget与宿主程序之间的数据共享,后面会讲到)
二、从today widget打开APP
Today Extension只能通过openURL的方式调起APP,所以需要配置URL types。
1、首先,在宿主程序中增加URL Types:
宿主程序中增加URL Types.png
2、其次,在today Extension程序中的plist文件中增加url types选项:(注意:URL identifier为宿主程序的Bundile id ; URL Schemes为上一步添加的Schemes)看下图
today Extension程序中的plist文件中增加url types选项.png
完成上面两个步骤之后,就可以实现从today Extension中打开APP了,在TodayViewController.m中增加个按钮,点击进入APP:实现如下:
TodayViewController.m
//打开app (//通过openURL的方式启动Containing APP)
- (void)openURLContainingAPP:(UIButton *)sender{
//打开类型(用于宿主程序内部控制跳转逻辑,比如是要跳转到首页还是要跳转到个人中心等等)
NSString *schemeSubString = @"typeHome";
//scheme为app的scheme
NSString *scheme = [NSString stringWithFormat:@"此处写入上面创建的Schemes://?type=%@",schemeSubString];
[self.extensionContext openURL:[NSURL URLWithString:scheme] completionHandler:^(BOOL success) {
NSLog(@"open url result:%d",success);
}];
}
然后再宿主程序的AppDelegate方法中实现协议,监听url,
- (BOOL)application:(UIApplication *)app openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<NSString *,id> *)options
{
//TODO:打开逻辑控制
NSDictionary *type = [url URLParameter];
if ([[type objectForKey:@"type"] isEqualToString:@"typeHome"]) {//打开首页
[[AppDelegate sharedDelegate].tabBarController setSelectedIndex:0];
}else if ([[type objectForKey:@"type"] isEqualToString:@"typeOrder"]){//打开菜单
[[AppDelegate sharedDelegate].tabBarController setSelectedIndex:1];
}
return YES;
}
三、today Extension与宿主程序之间的数据共享
首先需要去苹果开发者中心的APP Groups中创建一个APP Group,命名方式"group.com.companyName.xxx",
完成之后你还要做以下修改
1、编辑你的contain app的APP ID,Service中选中App Groups,并且点击右边的Edit按钮选中刚刚创建的group,返回后,点击Done完成APP ID的编辑
2、此时contain app的Provisioning Profiles文件会显示为无法使用,需要更新下文件,并且下载下来覆盖安装
3、在宿主程序中添加APP Groups(名称为:你在App Store添加创建的group的名称)
image.png
4、同样在today Extension中勾选刚添加的group
[图片上传中...(image.png-2f0d77-1539332876378-0)]
完成App Groups添加之后就可以实现数据共享(通过App Groups提供的同一group内app共同读写区域,可以用NSUserDefaults和NSFileManager两种方式实现Today Extension和containing app之间的数据共享。)
//在宿主程序中存储数据
//测试与todayWidget数据共享
NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"这里填写你的group名称"];
[userDefault setObject:@"存储的内容,就是我 -松小宝-" forKey:@"key_todayWidget_appName"];
[userDefault synchronize];
//测试与todayWidget数据共享
下面是在today Extension中读取数据
//获取宿主程序的数据
- (void)getLuckyClientData{
//从宿主程序获取共享数据
NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"这里填写你的group名称"];
NSString *appName = [userDefault objectForKey:@"key_todayWidget_appName"];
NSLog(@"%@",appName);
}
下面为使用NSFileManager共享数据的方式
#pragma mark - 通过NSFileManager共享数据
- (BOOL)saveDataByNSFileManager
{
NSError *error = nil;
NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.xxx.xxx"];
containerURL = [containerURL URLByAppendingPathComponent:@"Library/Caches/test"];
NSString *value = @"test";
BOOL result = [value writeToURL:containerURL atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (!result) {
NSLog(@"%@",error);
} else {
NSLog(@"save value:%@ success.",value);
}
return result;
}
- (NSString *)readDataByNSFileManager
{
NSError *error = nil;
NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.xxx.xxx"];
containerURL = [containerURL URLByAppendingPathComponent:@"Library/Caches/test"];
NSString *value = [NSString stringWithContentsOfURL:containerURL encoding:NSUTF8StringEncoding error:&error];
return value;
}
四、让APP Extension共享宿主程序第三方库或者头文件和资源文件
1、PROJECT --info --configurations,将对应的Debug和Release 设置成pods-你的Xcode项目名.debug和pods-你的Xcode项目名.release。
image.png
2、TARGETS--Build Phases --Link Binary With Libraries,将pods的.a文件引入
image.png
3、如果想引用宿主程序中的头文件或者资源文件,将Target Menbership中打勾对应的程序即可
打勾该项之后,today Extension就能使用Assets.xcassets中的资源.png
最后,上一张效果图:
today widget效果图.png
五、添加3D Touch
//在didFinishLaunchingWithOptions方法中添加3D Touch选项
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
//快捷菜单的图标
UIApplicationShortcutIcon *icon1=[UIApplicationShortcutIcon iconWithTemplateImageName:@"cart_bar_select"];
//快捷菜单
UIApplicationShortcutItem *item1=[[UIApplicationShortcutItem alloc] initWithType:@"1"
localizedTitle:@"购物车"
localizedSubtitle:nil
icon:icon1
userInfo:nil];
//设置app的快捷菜单
[[UIApplication sharedApplication] setShortcutItems:@[item1]];
}
//3D Touch按压程序图标的快捷项时触发的方法
-(void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler{
if([shortcutItem.type isEqualToString:@"1"]){
//打开应用,并跳转到购物车
[[AppDelegate sharedDelegate].tabBarController setSelectedIndex:3];
}
}
加入3DTouch后可以再桌面长按图标显示快捷选项和today widget视图.
网友评论