iOS开发(OC)iOS Developer

iOS widget的基本使用(为你的应用创建一个分身)

2018-03-12  本文已影响50人  liangZhen

iOS8.0之后,苹果支持了扩展(Extension)的开发,开发者可以通过系统提供给我们的扩展接入点 (Extension point) 来为系统特定的服务提供某些附加的功能。当时Widget扩展应用不温不火,iOS10之后官方对Widget进行了大幅度的优化,配合3Dtouch Widget逐渐火了起来。本文简单的介绍了Widget的使用。

本地大致按照以下四个步骤介绍widget
1.在宿主工程添加widget target
2.构建UI界面
3.唤醒宿主App
4.与宿主App共享数据
1.在宿主工程添加widget target

打开宿主工程,Flie->New->Target->Today Extension->Next,如下图。


这样创建一个widget target
这个时候需要注意两点

1.在当前的widget target基本配置里面将Deployment Target设置为你要兼容的iOS最低版本。

因为创建出来的时候,这里是默认是iOS最高版本,如果不更改,你自己的手机iOS版本比Deployment Target低的话就会导致运行而不出现widget情况。

2将你需要的图片资源拖入当前的target内

因为widget 与 宿主App是两个不容的进程,资源是不能共享的,如果不推入widget会导致不能加载资源。当然你也可以创建一个xcassets再把图片资源拖入。


2.构建UI界面

系统默认是用storyboard的形式,如果你使用纯代码需要在当前target的info.plist首先将原有NSExtensionMainStoryboard字段删除,添加字段NSExtensionPrincipalClass,value是你所写的controller的名称,一般默认的都是TodayViewController,如下图


纯代码info操作

如果使用SB那就忽略上面的操作。
iOS10以上支持widget的折叠与展开。
在初始化UI的时候加入下面的代码,告诉系统你的widget是可折叠的样式。

 if (@available(iOS 10.0, *)) {
        self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
    }

重写切换展开及折叠布局时的方法,处理用户点击折叠与展开的操作。

- (void) widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize {
    NSLog(@"maxWidth %f maxHeight %f",maxSize.width,maxSize.height);
    if (@available(iOS 10.0, *)) {
        if (activeDisplayMode == NCWidgetDisplayModeCompact) {
            //折叠
            self.preferredContentSize = CGSizeMake(maxSize.width, 100);
            //处理一些操作
        } else {
            //展开
            self.preferredContentSize = CGSizeMake(maxSize.width, 200);
            //处理一些操作
        }
    } else {
        // Fallback on earlier versions
    }
}

这里注意加载数据完毕后,渲染UI时一定要在主线程操作。

3.唤醒宿主App

widget 与 宿主App属于两个独立的进程。可以理解为两个不同的App,如果唤醒宿主,可以通过schemes的方式唤醒。
1.在宿主App内设置url schemes
在宿主项目的target->info->URLTypes点击加号增加内容,然后在URL Schemes定义一个Schemes,例如为widgetDemo,如下图



2.处理widget的点击事件
在需要跳转的时候加入以下代码

 //点击了内容,要跳转到宿主app
    NSURL *URL = [NSURL URLWithString:@"widgetDemo://data=123456"];
    [self.extensionContext openURL:URL completionHandler:^(BOOL success) {
        if (success) {
            NSLog(@"打开成功");
        }
    }];
4.与宿主App共享数据

1.通过schemes传递参数
如果数据量不大,仅仅是参数的一些传递的话,利用schemes即可,如上面的代码所示widgetDemo://后面的data=123456即是参数,可以携带少量的信息。
2.通过App Groups来共享数据
(1.)去开发者账号Identifiers->App Groups 点击+号增加一个App Groups total.如下图:



(2.)然后去宿主App的appId点击Edit->点击App Groups的Edit,选中刚才创建的App Groups total->Continue.点击如下图



(3.)分别去Xcode中的宿主Targrt 与 widget Target,打开App Groups对刚才创建的App Groups total打钩,无任何错误,证明添加成功,如下图。

当然你也可以忽略前两步直接进行第三步,点击+号分别在宿主Targrt 与 widget Target中增加一个App Groups total,可能会因为格式不对,而无法添加成功。
分别在widget 内添加写入代码,在宿主app内添加读取代码。即可完成App Groups内数据共享

//widget内存入数据
- (void)wirteData:(NSData *)data {
    NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.widgetdemo.message"];
    [userDefaults setObject:data forKey:@"widgetImage"];
    BOOL isok = [userDefaults synchronize];
    NSLog(@"写入成功?%d",isok);
}
//宿主app内读取数据
- (void)readMessage {
    NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.widgetdemo.message"];
    NSData * date = [userDefaults objectForKey:@"widgetImage"];
    _imageView.image = [UIImage imageWithData:date];
}

至此widget的简单使用完成,Demo戳这里,下面有一些注意点:
1.widget与宿主细胞分别是两个不同的进程,相当于是两个不同的app,上架的时候需要创建证书,配置文件等。
2.widget与宿主细胞分别是两个不同的进程,图片等资源不能直接使用宿主app的资源。
3.widget target基本配置里面将Deployment Target设置为你要兼容的iOS最低版本。一定比你真机的iOS系统版本低,否者不能显示出来。

上一篇 下一篇

猜你喜欢

热点阅读