简介
Today Extension是ios8开始推出的一个重大更新,它与宿主工程是相互独立的,到目前已经有很多app实现了这一功能,但是该功能在ios10系统上才得以真正的发挥。
extension规定不能直接与它的宿主工程host app进行通讯,也不能共享之间的代码,但是可以通过添加framework
共享代码块。
在ios8、9中today extension没有折叠和展开功能,在这两个系统中只有下拉刷新;然后在ios10系统中,today extension是通过右滑界面而出现的,此时只要实现折叠、展开这两项就能实现该功能。
同时ios8、ios9与ios10中的toaday extension界面有些区别,iOS10以前的版本中today extension 的背景颜色是黑色带有磨砂效果的;而ios10及以上系统是白色带磨砂的
Extension可以使用的内存远远低于app可以使用的内存,因此当内存吃紧的时候,会优先杀死extension。所以在开发的过程中应该注意内存的使用
开发过程中,有些API接口不可用与Extension中,在系统中使用NS_EXTENSION_UNAVAILABLE
标明
创建Today Extension
一、宿主工程
先创建宿主功能,若在已有的工程上添加today extension可忽略第一步
二、创建Extension
项目
--->General
---> +
此时运行工程后,加载extension即可显示Hello World字样是工程原配的
三、纯代码开发Extension
个人比较喜欢纯代码开发,storyboard在多人合作时,容易产生冲突和矛盾。
步骤:
- 删除Extension中的
storyboard
以及Info.plist
中的NSExtension
->NSExtensionMainStoryboard
- 在
Info.plist
中的NSExtension
添加NSExtensionPrincipalClass
字段,对应的value值TodayViewController
四、与宿主工程产生关联
1.创建证书中的APP Groups
2.配置宿主工程的App Groups
3.配置Extension中的App Groups
注意:宿主工程中的App Groups
必须与Extension中的App Groups
保持一致
五、与宿主工程的数据共享
在extension中可以用NSUserDefault
、NSFileManager
、NSFileCoordination
、CoreData
、Sqlite
等进行数据共享。
官方建议在iOS8.2以上系统中使用UIDocument
来协调共享数据,在ios9以上系统中使用NSFileCoordinator
类进行数据共享,但是当应用程序扩展转换到后台时,必须删除NSFilePresenter
对象
首先我们在宿主工程中,存点数据
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.dyTodayExtension"];
[userDefault setObject:@"tips" forKey:@"group.dyTodayExtension.tips"];
}
@end
在Extension取出数据显示
#import "TodayViewController.h"
#import <NotificationCenter/NotificationCenter.h>
@interface TodayViewController () <NCWidgetProviding>{
UILabel *_textLabel;
UIView *_subView;
}
@end
@implementation TodayViewController
- (void)viewDidLoad {
[super viewDidLoad];
//设置extension的size
self.preferredContentSize = CGSizeMake(0, 150);
_subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 150)];
_subView.backgroundColor = [UIColor grayColor];
[self.view addSubview:_subView];
_textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, _subView.frame.size.width, 50)];
_textLabel.numberOfLines = 0;
_textLabel.textAlignment = NSTextAlignmentCenter;
_textLabel.backgroundColor = [UIColor brownColor];
_textLabel.textColor = [UIColor greenColor];
[_subView addSubview:_textLabel];
NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.DonYau.today"];
NSString *textStr = [userDefault valueForKey:@"group.DonYau.today.tips"];
_textLabel.text = textStr;
}
此时运行工程,可以看到我们在宿主工程保存的数据,在Extension中也可以获取到
六、跳转宿主工程
在宿主工程中配置URL Schemes
,然后添加点击事件,当我们点击button时,就会跳转到宿主工程
#import "TodayViewController.h"
#import <NotificationCenter/NotificationCenter.h>
@interface TodayViewController () <NCWidgetProviding>{
UILabel *_textLabel;
UIView *_subView;
}
@end
@implementation TodayViewController
- (void)viewDidLoad {
[super viewDidLoad];
//设置extension的size
self.preferredContentSize = CGSizeMake(0, 150);
_subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 150)];
_subView.backgroundColor = [UIColor grayColor];
[self.view addSubview:_subView];
_textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, _subView.frame.size.width, 50)];
_textLabel.numberOfLines = 0;
_textLabel.textAlignment = NSTextAlignmentCenter;
_textLabel.backgroundColor = [UIColor brownColor];
_textLabel.textColor = [UIColor greenColor];
[_subView addSubview:_textLabel];
NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.DonYau.today"];
NSString *textStr = [userDefault valueForKey:@"group.DonYau.today.tips"];
_textLabel.text = textStr;
UIButton *openApp = [[UIButton alloc] initWithFrame:CGRectMake(0, 60 , _subView.frame.size.width, 30)];
openApp.backgroundColor = [UIColor blueColor];
[openApp setTitle:@"打开app" forState:UIControlStateNormal];
[openApp setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[_subView addSubview:openApp];
[openApp addTarget:self action:@selector(openApp) forControlEvents:UIControlEventTouchUpInside];
}
- (void)openApp{
[self.extensionContext openURL:[NSURL URLWithString:@"todayExtension:"] completionHandler:^(BOOL success) {
}];
}
我们可以在宿主工程中通过AppDelegate的代理方法获取从Extension传过来的数据
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
return YES;
}
七、监控Today Extension的更新
我们创建好Today Extension
时,工程已经自动创建好更新的回调,因此我们可以在该代理方法中监控Today Extension
的更新操作
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
-
completionHandler(NCUpdateResultNewData);
}
八、Today Extension偏移的控制
同样Today Extension
给我们提供了代理方法,以确定内容的偏移
-(UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets{
return UIEdgeInsetsZero;
}
九、显示收缩、扩展功能
当我们需要收缩扩展功能的时候,首先需要确定视图刚开始显示的时候,添加状态的显示。
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
//该处目前只能设置NCWidgetDisplayModeCompact,界面初始显示的时候,只能是收缩状态
self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeCompact;
}
当我们在willAppear中设置该属性后,运行工程即可看到收缩、扩展
功能按钮
然后遵循代理,以便在状态发生变化时,更新界面
-(void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize{
if (self.extensionContext.widgetActiveDisplayMode == NCWidgetDisplayModeCompact) {
self.preferredContentSize = CGSizeMake(0, 150);
}else{
self.preferredContentSize = CGSizeMake(0, 300);
}
}
10、Cocoapods库的共用
在使用Today Extension
的过程中,或者我们在extension使用的工具类刚好在宿主工程中也需要使用,这个时候cocoapods
就帮上我们的大忙了
比如需要在宿主工程和Extension中使用AFN框架获取一些网络的数据,这时候我们只需配置Podfile
文件即可共享工具类
platform :ios, ‘8.0’
use_frameworks!
def shared_pods
pod 'AFNetworking', '~> 3.1.0'
end
target 'DYTodayDemo' do
shared_pods
end
target 'DYTodayExtensionDemo' do
shared_pods
end
当执行pod install
后,工程的配置如图
遇到的问题
- 当运行工程的出现
error: Embedded binary's bundle identifier is not prefixed with the parent app's bundle identifier
的错误时,是因为宿主工程和Extension
的bundle identifier
不符合规范。
在Extension
中的identifier应该是在宿主工程的bundle identifier
后面加上后缀,比如
宿主工程 bundle identifier : com.todayDemo.Example
Extension bundle identifier : com.todayDemo.Example.today
推荐文章
App Extension编程指南(iOS8/OS X v10.10)中文版
App Extension Programming Guide
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。