Today Extension(widget)看我就够了

2024-06-17 02:38
文章标签 extension widget today

本文主要是介绍Today Extension(widget)看我就够了,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、介绍
1、app extension、containing app及host app

app extension

extension不能单独存在,必须有一个包含它的containing app,它有一个包含在app bundle中的独立bundle,extension的bundle后缀名是.appex。其生命周期也和普通app不同。

extension需要用户手动激活,不同的extension激活方式也不同。Today中的widget需要在Today中激活和关闭;Custom keyboard需要在设置中进行相关设置;Photo Editing需要在使用照片时在照片管理器中激活或关闭;Storage Provider可以在选择文件时出现;Share和Action可以在任何应用里被激活,但前提是开发者需要设置Activation Rules,以确定extension需要在合适出现。

containing app

extension,不能单独存在,必须依赖主app,主app即containing app, extension会随着containing app的安装/卸载而安装/卸载。

host app

能够调起extension的app被称为host app,比如widget的host app就是Today。

extension和host app之间可以通过extensionContext属性直接通信(该属性是UIViewController类别)实际上extension和host app之间是通过IPC(interprocess communication)实现的。 containing app和host app之间没有任何直接关系,也从来不需要通信。extension和containing app之间的关系最复杂,因为extension依赖与containing app。

2、widget的生命周期

extension是针对某项功能的扩展,不是单独存在的。它的生命周期与app的生命周期的各自独立,为两个进程。

  • 开始:在用户通过host app点击extension时,系统实例化extension,extension的生命周期开始。

  • 执行:extension启动后,执行自己的任务。

  • 消失:任务执行结束或用户通过host app结束任务,又或者系统会将其杀掉,extension的生命周期结束。

    img

二、widget原理
1、widget和containing app
  • widget通过openURL的方式启动containing app

  • 数据交互,使用使用NSUserDefaults或者NSFileManager

    img

2、widget刷新机制

由于,系统会自动保存widget的快照,直到新的数据或UI刷新。短时间内重复展示widget页面,widget的执行路径直接只会执行viewWillAppear方法。而在第一次下拉或超过2s再显示widget页面时,widget的执行路径是viewDidLoad->viewWillAppear

3、widget和app共享资源
  • 共享数据

    开启App Groups, 然后使用 app groups来实现二者共享。开启后 NSUserDefaults 或者 NSFileManager 利用 App Groups 共享数据

  • 代码共享

    (1)在Build Phases下的Compile Sources中添加需要的文件,注意添加想要使用的.m文件的同时,也需要添加该文件中引入的类的.m文件,适用于共用代码少的情况

    (2)创建framework。可参考博文中framework创建部分、Sharing Code with an Embedded Framework

三、遇到的问题及解决方案
1、在widget中,右上方的展开、折叠具体实现

在NSExtensionContext中,新添了widgetLargestAvailableDisplayMode属性,来确认当前widget是展开还是折叠状态。所以,先在viewWillAppear中设置widget的mode为展开。
self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
    然后,就是展开和折叠的处理了。在NCWidgetProviding协议中,新添了这么个方法

-(void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize 设置不同模式下的widget展现内容的高度。

2、widget处于折叠状态时,然后系统2s刷新后,第一次点击展开失效

这个问题是preferredContentSize的设置问题,确认widget的mode之前,谨慎设置这个值。之后,在点击展开、折叠按钮修改了mode之后,一定要设置对应model的preferredContentSize

3、界面的UI的更新要在主线程操作

dispatch_async(dispatch_get_main_queue(), ^{ //...........; });

4、widget和app共用数据

使用NSUserDefaults或者NSFileManager(ios7,NSFileManager提供了containerURLForSecurityApplicationGroupIdentifier方法,可实现app groups共享数据)

5、widget横竖屏兼容

widget默认为竖屏,但我们不能安照app内处理横竖屏的适配方式来处理widget的横竖屏适配。我们可以使用下面的方式来处理横竖屏的问题。之后根据全局属性isLandscape来判读是否为横屏,然后设置横竖屏的UI布局

//横屏/竖屏重新布局
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{CGSize  screenSize = [UIScreen mainScreen].bounds.size;if (screenSize.width > screenSize.height) {self.isLandscape = YES;}else{self.isLandscape = NO;}
}

也可以在- (void)viewWillLayoutSubviews或者- (void)viewDidLayoutSubviews方法中判断是否为横屏(这两个方法都是viewWillAppear方法必然执行的)

6、containing app能够控制extension的出现和隐藏

如果隐藏extension,用户在Today的展示页面看不到隐藏的extension,但是在编辑设置页面可以看到extension还是存在的,这样容易给用户错觉。

//让隐藏的插件重新显示 
-(void)showTodayExtension 
{ [[NCWidgetController widgetController] setHasContent:YES forWidgetWithBundleIdentifier:@"com.app.extension"]; 
} //隐藏插件 
-(void)hiddeTodayExtension 
{ [[NCWidgetController widgetController] setHasContent:NO forWidgetWithBundleIdentifier:@"com.app.extension"]; 
}

注意:

  • 调用隐藏方法之后,需要调用展示方法才可以再次展示该extension

  • 该方法在App Extension和Containing App中都可以调用,需要导入<NotificationCenter/NotificationCenter.h>头文件。

7、widget不显示

检查下 widget 的 Deployment Target 是不是小于等于你的真机版本

8、设置extension的名字

在extension target下的info.plist下设置

9、3DTouch效果增加widget,在app图标上touch之后展示一个widget

在app 的 info.plist 文件中增加一组key-value,即Home Screen Widget–widget的bundleID

10、天气、新闻类app,当数据发生改变需要及时更改widget页面,展示最新数据。

我们首先想到的是使用 Timer 来实现,根据与后台协商好的时间,定时获取数据更新widget那么我们在什么时机下触发、销毁timer,由于widget 中controller 特殊的生命周期,为了适应用户不同的操作,我们在控制器的viewWillAppear方法中出发timer,在viewDidDisappear方法销毁timer。

11、国际化
  • widget名字的国际化:New file选择Strings file,然后更名为InfoPlist,生成InfoPlist.strings文件后点击右边中Localize…,在弹窗中选择自己支持的多语言即可;在生成的多语言文件中写app的名称

    CFBundleDisplayName = “简体”/“繁體”/“English”

  • widget内容多语言:New file选择Strings file,然后更名为Localizable,生成Localizable.strings文件后点击右边中Localize…,在弹窗中选择自己支持的多语言即可;在生成的多语言文件中写支持的多语言即可。

12 widget隐藏

​ NCWidgetController *widgetController = [NCWidgetController widgetController];

​ [widgetController setHasContent:NO forWidgetWithBundleIdentifier:WB_BUNDLE_ID_FOR_HOTWEIBO_WIDGET_STRING];

添加这行代码后,在app第一次运行的时候,widget会隐藏,但是在设置页面还会有,但是即使再移除、在添加,在today extension界面也不会显示该widget。

扩展
1、如果Container app数据发生改变需要Extension马上更新应该怎样操作?
  • 方案研究如下

(1)NSNotificationCenter 仅在 app 内部起作用,在 apps 之间不起作用。

(2) UserDefaults(KVO)的方式是在main app 与 extension 之间起作用,apps之间无用。

(3)使用 NSFileCoordinator 和 NSFilePresenter 实现,虽可实现但有点复杂。

(4)使用 CFNotificationCenterGetDarwinNotifyCenter 实现。

  • 原理

    CFNotificationCenterGetDarwinNotifyCenter 是 core foundation中系统级别的通知,使用它需要用到Toll-Bridge的知识与CoreFoundation相关的类进行桥接。

参考链接

  • MMWormhole第三方库,用于Container app 与 entension 之间传递数据信息

  • CFNotificationCenterGetDarwinNotifyCenter使用方法

  • App与Extensions间通信共享数据

参考

Entitlement Key Reference

App Extension Programming Guide(Today Extension)

这篇关于Today Extension(widget)看我就够了的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1068259

相关文章

如何在Qt的widget上右键显示菜单

如何在Qt的widget上右键显示菜单 今天早上一来,我老大叫我在widget上点击右键加上一个菜单,并相应其响应的功能,因为我成刚接触Qt,所以看了下QtGUI编程这本书,做出来,记录下来,说不定哪天还用得上啊! 废话不多说,直接上代码: 方法一: m_text = QTextCodec::codecForLocale(); ui->tableWidget->addAction(ne

QT窗体Widget使用的若干问题

这里介绍的是widget 窗体的属性 最完整的属性请查看qt自带的帮助文档,这里之拿了一部分做说明 窗体属性: object name:物件名称 qwidget:enable 使能本部件 geometry:窗口位置和大小设置 sizepolicy: 1. Fixed: 大小不能改变 2. Minimum: 已经是最小, 不能再被缩小, 但

cannot be cast toandroid.widget.HeaderViewListAdapter

在做上拉刷新的时候,想要在下拉到底部的时候通过addFooterView给listview添加一个view,遇到这个异常 网上找到解决方法之后,记录下。 ---------------------------------------------- cannot be cast toandroid.widget.HeaderViewListAdapter 用listview设置h

VirtualBox安装VirtualBox Extension Pack,支持USB No USB devices connected after upgrade

安装步骤及出现问题解决No USB devices connected after upgrade: 一、本要主机ubuntu14.04,安装virtualbox,支持usb设置步骤: 1.安装VirtualBox. 可以从https://www.virtualbox.org官方站点下载或者从软件中心。 2.在VirtualBox里安装Windows; 3.为USB2.0,你需要

today extension 扩展使用

http://blog.csdn.net/ralbatr/article/details/44194389 效果图:

iOS10通知及通知拓展Extension使用详解(附Demo)

1.1-iOS10拓展简介 1.2-iOS10通知使用 1.3-iOS10通知拓展Extension使用 1.4-效果演示 如果对开发有兴趣的可以来黑马学习iOS开发:黑马程序员源代码下载地址:Deme下载 1.1-iOS10拓展简介 iOS10系统最大的一个亮点就是增加了系统应用的拓展功能Extension Extension功能可以理解为自定义系统界面本小节我们就以自定义系统通

java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.widget.

java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.widget.LinearLayout$LayoutParams 报错原因: ImageView image =(ImageView) findViewById(R.id.imageView1)

HDU 2112 Today (Dijkstra)

http://acm.hdu.edu.cn/showproblem.php?pid=2112 HDU Today Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 16490    Accepted Submission(s): 3

Inconsistency detected. Invalid item position 5(offset:5).state:10 android.support.v7.widget.Recycle

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 5(offset:5).state:10 android.support.v7.widget.RecyclerView 错误原因:在使用recycleView 的adapter.notifyDataSetChange()的时候出现的

记录java使用selenium驱动谷歌浏览器中的坑(二)unknown error: cannot get automation extension

信息: Detected dialect: OSS org.openqa.selenium.WebDriverException: unknown error: cannot get automation extension Starting ChromeDriver (v2.9.248315) on port 22005三月 11, 2020 1:44:30 下午 org.openqa.s