Widget简单体验

前言

对于一款应用来说,想要获得更多关注,想要更频繁的出现在用户的视野中,推送、widget都是必不可少的,推送在实际开发中,是很常见的,那我们就来玩一玩不常见的widget吧!

创建一个TodayExtension

新创建一个项目,创建完成后,再在项目中新加入一个target。target选Today Extension。


新建target

选择todayExtension

  当然TodayExtension作为一个单独的target,也是需要证书的,为了demo方便,我们就直接自动管理了。


需要证书

  创建成功后,你会发现,新的target里面多了一个controller,这个controller就是我们所能看到的widget,而且他继承自UIViewController,所以我们可以正常的像开发其他功能一样来做widegt,不过widget是有内存限制的,请尽量做些简单的功能。
  观察iOS10的widget你会发现,他有两种状态,分别是折叠、展开。
展开折叠

  我们在TodayViewController加入折叠的支持。首先在viewWillAppear中加入折叠的代码。当然折叠特性是iOS10新加入的,需要做下版本区分,防止非iOS10设备崩溃。

- (void)viewWillAppear:(BOOL)animated {
    // 设置widget的状态为展开
    self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
}

然后有个协议方法需要实现,协议为:


协议

  方法为:

- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize {
    if (activeDisplayMode == NCWidgetDisplayModeCompact) {
        self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 110);
    } else {
        self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300);
    }
}

该方法,指定折叠和展开两个状态下的widget大小。现在再运行,你就可以正常添加我们制作的widget到通知中心了。

调起主程序

通过上面的步骤,你就可以正常的创建任何你想做的widget插件了。但我们最关心的不是widget该怎么做,因为它作为一个UIViewController,以我们的开发经验想创造出各种页面,都是没问题的。
  我们最关心的是,如何通过widget,将用户引导到我们的APP中,也就是应用跳转。以支付宝为例,对支付宝进行3D Touch操作,你会发现,它的快捷widget有四个可跳转到APP内部各个功能的按钮。


支付宝的widget

  那么这是怎么实现的呢?实际上iOS8开始引入的Extension,相对于母体APP,都是独立的,Extension管理自己的数据,母体APP管理自己的数据。那如何调起母体APP呢?其实很简单,正如我们自己的APP调起其他APP一样,比如微信、支付宝、微博等,那就是利用URL Scheme。
  我们先为我们的母体APP加入一个URL Scheme。


为母体APP添加URL Scheme

  widget中想调起母体APP,直接使用下面的OpenUrl就搞定了。
- (void)openApp {
    NSURL *url = [NSURL URLWithString:@"todayDemo://"];
    [self.extensionContext openURL:url completionHandler:nil];
}

这里有一个需要注意的点就是,widget作为一个Extension,是不存在Application的概念的,所以不能用传统的[UIApplication sharedApplication]的方式来进行openUrl操作。使用self.extensionContext,即可获取当前Extension上下文,也就是我们的widget。
  母体APP需要在AppDelegate中的openUrl方法中拦截到widget的openUrl。我们看看获取到的url(下面的方法在iOS10舍弃了,但还是可以用的):

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    
    UIAlertView *av = [[UIAlertView alloc] initWithTitle:[url absoluteString] message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:nil, nil];
    [av show];
    
    return YES;
}

运行项目,点击widget后调起母体APP的效果为:


接收到的url

  跟我们openUrl时填写的url一模一样。这样我们就可以在这个url后面拼接上各种参数,告诉母体APP跳转到哪个页面了。大致样式是这样的:

todayDemo://?params=gotoSomeView

跟一般的get请求的网址类似,可以拼接各种参数进去,在母体APP获取到url时,直接[url query]就能获取到"?"后面的所有参数。

与母体APP组成APP Group

我们的主要目的还是想widget和母体APP共享数据,在很多笔记APP中,widget和母体APP是共享笔记的,那我们就要用到APP Group了。我们先在母体APP中创建一个APP Group:


创建Group

  创建完成后,再来到我们的Extension的target下。你会发现APP Group下多了之前我们在母体添加的Group,将它勾选上,则我们的Extension就和母体APP组成了APP Group。


Paste_Image.png

  这个时候,两个程序,就可以共享一些数据了。我们以NSUserDefault为例,在母体中保存一个字段,然后在Extension中读取这个字段,识别到后,将widget的颜色变成红色。
  首先在母体APP的ViewController中获取APP Group的UserDefault,并存储一个字段。
- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 创建一个UserDefault
    NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.MyTodayGroup"];
    
    // 存储一个颜色
    [userDefaults setObject:@"redColor" forKey:@"color"];
    
    // 同步
    [userDefaults synchronize];
}

这里需要注意的是,我们平时项目中用的都是[NSUserDefaults standardUserDefaults],但这个UserDefault实际上是无法跟Extension互通的,我们需要找到APP Group所对应的UserDefault,注意initWithSuiteName后面接的名字,一定是我们之前创建的APP Group的名字。
  然后我们来到widget中的controller,还记得之前我们遵守的协议吗,里面还有一个方法,就是更新widget的一个方法。方法中completionHandler之前的代码,就是我们正常的逻辑操作,匹配到字段后,将背景色替换为红色,然后completionHandler(NCUpdateResultNewData)这句,则是告诉widget我们处理完了,做了NCUpdateResultNewData的处理,更新了数据。这是个枚举值,具体含义可以点进去看下系统的注释。

- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
    // Perform any setup necessary in order to update the view.
    
    // If an error is encountered, use NCUpdateResultFailed
    // If there's no update required, use NCUpdateResultNoData
    // If there's an update, use NCUpdateResultNewData

    // 拿到主程序的NSUserDefault
    NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.MyTodayGroup"];
    
    NSString *color = [userDefaults objectForKey:@"color"];
    if ([color isEqualToString:@"redColor"]) {
        self.view.backgroundColor = [UIColor redColor];
    }
    
    completionHandler(NCUpdateResultNewData);
}

先运行母体APP,再运行widget,看下效果:


效果

总结

以上的包括widget的UI、调起母体APP、与母体APP数据互通这些特性组合在一起,便可满足我们正常的开发需求了。所以还等什么呢,快为你的APP加入widget特性吧!

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

推荐阅读更多精彩内容