Today Extension是ios8开始推出的一个重大更新,它与宿主工程是相互独立的,到目前已经有不少app实现了这一功能,可是该功能在ios10系统上才得以真正的发挥。
extension规定不能直接与它的宿主工程host app进行通信,也不能共享之间的代码,可是能够经过添加framework
共享代码块。
在ios八、9中today extension没有折叠和展开功能,在这两个系统中只有下拉刷新;而后在ios10系统中,today extension是经过右滑界面而出现的,此时只要实现折叠、展开这两项就能实现该功能。
同时ios八、ios9与ios10中的toaday extension界面有些区别,iOS10之前的版本中today extension 的背景颜色是黑色带有磨砂效果的;而ios10及以上系统是白色带磨砂的
Extension可使用的内存远远低于app可使用的内存,所以当内存吃紧的时候,会优先杀死extension。因此在开发的过程当中应该注意内存的使用
开发过程当中,有些API接口不可用与Extension中,在系统中使用NS_EXTENSION_UNAVAILABLE
标明html
先建立宿主功能,若在已有的工程上添加today extension可忽略第一步ios
项目
--->General
---> +
编程
此时运行工程后,加载extension便可显示Hello World字样是工程原配的bash
我的比较喜欢纯代码开发,storyboard在多人合做时,容易产生冲突和矛盾。
步骤:网络
storyboard
以及Info.plist
中的NSExtension
->NSExtensionMainStoryboard
Info.plist
中的NSExtension
添加NSExtensionPrincipalClass
字段,对应的value值TodayViewController
注意:宿主工程中的App Groups
必须与Extension中的App Groups
保持一致app
在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取出数据显示ide
#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时,就会跳转到宿主工程ui
#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
的更新操做
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
-
completionHandler(NCUpdateResultNewData);
}复制代码
一样Today Extension
给咱们提供了代理方法,以肯定内容的偏移
-(UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets{
return UIEdgeInsetsZero;
}复制代码
当咱们须要收缩扩展功能的时候,首先须要肯定视图刚开始显示的时候,添加状态的显示。
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
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);
}
}复制代码
在使用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复制代码