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

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系统版本低,否者不能显示出来。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容