1.创建一个简单的app,主页面如下

2.添加扩展Target
2.1点击File-->New-->Target...,然后选择iOS中Application Extension中的Today Extension

2.2Today Extension文件结构如下

2.3运行Today Extension这个Target,可以看到一个默认的Hello World

2.4使用代码开发Today Extension
2.4.1删除DMTodayWidgetExtension下的MainInterface.storyboard文件
2.4.2修改DMTodayWidgetExtension下的Info.plist文件
修改之前

删除NSExtension中的NSExtensionMainStoryboard字段
添加NSExtensionPrincipalClass字段并设为TodayViewController
修改之后

2.5iOS10,today 多了展开和折叠两种模式
typedef NS_ENUM(NSInteger, NCWidgetDisplayMode) {
NCWidgetDisplayModeCompact, // Fixed height
NCWidgetDisplayModeExpanded, // Variable height
} NS_ENUM_AVAILABLE_IOS(10_0);
通过widgetLargestAvailableDisplayMode属性设置模式,
self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;//支持折叠和展开
设置折叠和展开显示区域
- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize
{
if (activeDisplayMode == NCWidgetDisplayModeCompact) {
self.preferredContentSize = maxSize;
} else if (activeDisplayMode == NCWidgetDisplayModeExpanded) {
self.preferredContentSize = CGSizeMake(0, 400);
}
}

2.6使用应用中的图片
选中Assets.xcassets,在File Inspector中的Target Membership中勾选Today Extension,如下图

效果图如下

2.7在应用和扩展中共享数据- App Groups
2.7.1在应用中开启App Groups
选中应用DMTodayWidget,打开它的Capabilities选项卡,找到App Groups 并打开开关

点击+,输入group的名字

2.7.2在扩展中打开App Groups,并勾选刚才创建的group

2.7.3在应用中写入内容
NSUserDefaults *introductionShare = [[NSUserDefaults alloc] initWithSuiteName:@"group.DMTodayWidgetSharedDefaults"];
[introductionShare setObject:@"💗💗小妖超超💗💗" forKey:@"com.diandi86.name"];
2.7.4在扩展中读取
NSUserDefaults *introductionShare = [[NSUserDefaults alloc] initWithSuiteName:@"group.DMTodayWidgetSharedDefaults"];
NSString *tempName = [introductionShare objectForKey:@"com.diandi86.name"];
[self.view addSubview:self.btn];
self.btn.frame = CGRectMake((self.view.bounds.size.width - 220)/ 2.0, 10, 220, 40);
[self.view addSubview:self.nameLabel];
self.nameLabel.text = tempName;
self.nameLabel.frame = CGRectMake(10, 60, self.view.bounds.size.width - 20, 40);

2.8在应用和扩展间共享代码 - Framework
2.8.1点击File-->New-->Target...,然后选择iOS中Framework&Library 选择 Cocoa Touch Framework

2.8.2在Framework中新建文件DMPersonModel.h/m
#import <Foundation/Foundation.h>
@interface DMPersonModel : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *sex;
@end
在DMPersonModelKit.h中加入
// In this header, you should import all the public headers of your framework using statements like #import <DMPersonModelKit/PublicHeader.h>
#import "DMPersonModel.h"
将DMPersonModel.h移动到Public中,如下图

2.8.3在应用中使用
导入文件
#import <DMPersonModelKit/DMPersonModelKit.h>
self.dianDi86.name = @"点滴86";
self.dianDi86.sex = @"Boy";
- (DMPersonModel*)dianDi86
{
if (_dianDi86 == nil) {
_dianDi86 = [[DMPersonModel alloc] init];
}
return _dianDi86;
}
2.8.4在扩展中使用
导入文件
#import <DMPersonModelKit/DMPersonModelKit.h>
self.xiaoYao.name = @"小妖超超";
self.xiaoYao.sex = @"Girl";
- (DMPersonModel*)xiaoYao
{
if (_xiaoYao == nil) {
_xiaoYao = [[DMPersonModel alloc] init];
}
return _xiaoYao;
}
扩展可以编译通过,但是会有如下警告

2.9通过扩展启动主体应用
2.9.1扩展中的关注按钮响应事件
#pragma mark - event response
- (void)btnClicked:(id)sender
{
[self.extensionContext openURL:[NSURL URLWithString:@"DMTodayWidget://TodayExtension"] completionHandler:nil];
}
2.9.2主体应用中修改 URL Types

2.9.3主体应用AppDelegate中修改
添加如下代码
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return [self appHandleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application openURL:(nonnull NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(nonnull id)annotation
{
return [self appHandleOpenURL:url];
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
return [self appHandleOpenURL:url];
}
#pragma mark - private method
- (BOOL)appHandleOpenURL:(NSURL *)url
{
if([url.scheme compare:@"DMTodayWidget" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
if ([url.host compare:@"TodayExtension" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
ViewController *vc = [[ViewController alloc] init];
[(UINavigationController*)self.window.rootViewController pushViewController:vc animated:YES];
}
return YES;
}
return NO;
}
点击关注按钮就可以调起主体应用啦...
2.10其它NCWidgetProviding协议
在Xcode扩展中NCWidgetProviding代理生成的模板文件要求扩展刷新界面
#pragma mark - NCWidgetProviding method
- (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
completionHandler(NCUpdateResultNewData);
}
Today Widget 扩展就到此结束啦...
网友评论