iOS之widget开发(Today Extension)

前言

extension是iOS8新开放的一种对几个固定系统区域的扩展机制,它能够在必定程度上弥补iOS的沙盒机制对应用间通讯的限制。javascript

extension的出现,为用户提供了在其它应用中使用咱们应用提供的服务的便捷方式,好比用户能够在Today Extension中查看应用展现的简略信息,而不用再进到咱们的应用中,一样能够快捷操做app的功能,这将是一种全新的用户体验。java

今天咱们介绍一下给工程添加Today Extension的步骤。git

添加Today Extension工程

在原有的工程基础上,想要使用Today Extension,咱们须要建立一个新的target,点击File-->New-->Target-->Today Extention,以下图所示:github

添加Target

选择Today Extension

添加成功后项目的目录会以下图所示:app

工程目录

运行项目会看到以下图所示的效果:ide

运行效果

定制UI

因为我习惯使用纯代码写UI,因此我会选择删除默认建立的MainInterface.storyboard,并在info.plist中删除NSExtensionMainStoryboard,添加NSExtensionPrincipalClass为TodayViewController,以下图所示:
学习

配置controller

咱们能够使用如下方法配置视图的大小

//配置Today Extension展现视图的大小
self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 100);复制代码

实现下面的协议,配置边距,不然会发现一个问题:绘制的内容与左侧边界有必定距离。ui

- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets {

    //配置边距为0
    return UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0);

}复制代码

咱们建立一个lable来充满视图,而且点击可打开咱们的appatom

//Today Extension的页面加一个可点击打开containingAPP的label
UILabel *openAppLabel = [[UILabel alloc] init];
openAppLabel.textColor = [UIColor colorWithRed:(97.0/255.0) green:(97.0/255.0) blue:(97.0/255.0) alpha:1];
openAppLabel.backgroundColor = [UIColor clearColor];
openAppLabel.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 100);
openAppLabel.textAlignment = NSTextAlignmentCenter;
openAppLabel.text = @"点击打开app";
openAppLabel.font = [UIFont systemFontOfSize:15];
[self.view addSubview:openAppLabel];

openAppLabel.userInteractionEnabled = YES;
UITapGestureRecognizer *openURLContainingAPP = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(openURLContainingAPP)];
[openAppLabel addGestureRecognizer:openURLContainingAPP];复制代码

打开app

Today Extension只能经过openURL的方式来调起app,而且须要在info.plist文件中配置参数URL types,
app工程中配置以下url

app schemes

Today Extension以下图

跳转URL types设置

URL identifier为app的bundle ID,URL Schemes配置为app的scheme
而且调用如下代码来打开app

//经过openURL的方式启动Containing APP
- (void)openURLContainingAPP
{
    //scheme为app的scheme
    [self.extensionContext openURL:[NSURL URLWithString:@"scheme://xxxx"]
                 completionHandler:^(BOOL success) {
                     NSLog(@"open url result:%d",success);
                 }];
}复制代码

demo代码,因为后面的步骤是须要苹果开发者帐号才能操做,因此demo的代码到这里为止。

数据共享

首先须要去苹果开发者中心的APP Groups中建立一个APP Group,命名方式"group.com.companyName.xxx",以下图

建立App Group

完成以后你还要作如下修改

  1. 编辑你的contain app的APP ID,Service中选中App Groups,而且点击右边的Edit按钮选中刚刚建立的group,返回后,点击Done完成APP ID的编辑
  2. 此时contain app的Provisioning Profiles文件会显示为没法使用,须要更新下文件,而且下载下来覆盖安装

Today Extension工程与app工程的配置都以下图所示

App Groups设置

经过App Groups提供的同一group内app共同读写区域,能够用NSUserDefaults和NSFileManager两种方式实现Today Extension和containing app之间的数据共享。

经过NSUserDefaults共享数据

- (void)saveDataByNSUserDefaults
{
    NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.xxx.xxx"];
    [shared setObject:@"test" forKey:@"widget"];
    [shared synchronize];
}

- (NSString *)readDataFromNSUserDefaults
{
    NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.xxx.xxx"];
    NSString *value = [shared valueForKey:@"widget"];

    return value;
}复制代码

经过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;
}复制代码

这样就实现了Today Extension与app的数据共享

真机调试与打包

咱们把Today Extension看成一个单独的app,各自有本身的App ID和Provisioning profile. 在Xcode里是两个Target给不一样的target设置本身的bundleID和Provisioning profile。因此你须要按如下步骤操做,才能真机调试以及打包

苹果开发者中心操做如下步骤

  1. 须要为Today Extension建立一个APP ID,通常命名方式为你的contain app的bundle id加上你建立的Today Extension工程名"com.companyName.xxx.xxx",App Services中勾选上App Groups,完成建立。以下图
    Today Extension APP ID设置
  2. 去Provisioning Profiles中建立Today Extension对应的profile文件,下载下来,安装,真机调试和打包须要用到,以下图
    Today Extension profile文件
  3. 将Today Extension的bundleID修改成刚刚为Today Extension建立的APP ID
  4. Today Extension版本号与contain app配置一致,不然审核上传的时候会有警告
  5. 打包或者真机调试的时候contain app与Today Extension选择各自的profile文件。

完成以上的准备工做以后,咱们就能够开始真机调试以及打包了。

总结

本篇暂时只是Today Extension简单的功能实现,我会在后面更新iOS10的适配,以及其余功能使用。若是有错误的地方欢迎指出~谢谢~

扩展阅读

  1. WWDC2014之App Extensions学习笔记

但愿对您有帮助,若是文章中有问题,欢迎评论留言~,谢谢支持~欢迎关注,我会在空余时间更新技术文章~

相关文章
相关标签/搜索