创建
在当前工程里新建target
选择Today Extension
独立应用
widget虽做为应用的扩展, 但却是两个完全独立的应用
widget上线需要单独申请 AppID 和 Bundle Identifier , 需要配置 证书 和 Provisioning Profiles(配置文件)
第三方pod导入, 也的重新导入一份
target 'MMWidget' dopod 'Masonry'
endtarget 'widgetDemo' dopod 'Masonry'
end
使用到的文件需要导入:
或者这样:
页面实现
默认是storyboard实现页面, 若想使用代码实现需对widget的配置文件进行修改:
<key>NSExtension</key><dict>
<!-- storyboard 实现 --><key>NSExtensionMainStoryboard</key><string>MainInterface</string><!-- 纯代码 实现 --><key>NSExtensionPrincipalClass</key><string>TodayViewController</string><key>NSExtensionPointIdentifier</key><string>com.apple.widget-extension</string></dict>
以上俩key保留一个就好.
打开应用
创建URL Schemes:
- (void)openApp {[self.extensionContext openURL:[NSURL URLWithString:@"wenwen://"] completionHandler:^(BOOL success) {NSLog(@"open url result: %d",success);}];
}- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options {if ([url.scheme isEqualToString:@"wenwen"]) {return YES;}
}
展开/折叠
- (void)viewDidLoad {[super viewDidLoad];// iOS10 later supportif (@available(iOS 10.0, *)) {self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;self.preferredContentSize = CGSizeMake(0, 110);}
}#pragma mark - 点击 展开/折叠
- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize {if (activeDisplayMode == NCWidgetDisplayModeCompact) {self.preferredContentSize = CGSizeMake(0, 110);} else {// 最多显示屏高self.preferredContentSize = CGSizeMake(0, 1000);}
}
数据共享
1.在开发者网站注册App Groups
2. 在主应用和拓展应用中将App Groups打开, 选中需要共享数据的group
3. 共享数据的两种方式
(1)NSUserDefaults 因拓展App无法访问主App的沙盒文件, 所以需要搭配App groups实例化UserDefaults
NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.momo.widget"];// 存
[userDefault setValue:@"momo" forKey:@"key"];// 取
label.text = [NSString stringWithFormat:@"%@", [userDefauct valueForKey:@"key"]];
(2)FileManager
NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.momo.widget"];containerURL = [containerURL URLByAppendingPathComponent:@"Library/Caches/widget"];NSError *error = nil;// 写入BOOL result = [string writeToURL:containerURL atomically:YES encoding:NSUTF8StringEncoding error:&error];if (result) {NSLog(@"写入成功");} else {NSLog(@"写入失败 %@", error.description);}// 读取NSString *string = [NSString stringWithContentsOfURL:containerURL encoding:NSUTF8StringEncoding error:&error];if (error) {NSLog(@"读取失败 %@", error.description);} else {NSLog(@"读取成功");}
Demo下载地址
遇到的问题:
1. 我们的项目widget数据分析失败, 最后找到原因, 是因为项目里有俩entitlements文件, 需要配置
2. framework not found *****
Targets -> General -> Linked Farmeworks and Libraries
将你需要分framework手动导入就行
3. 可能很多人会问widget新建工程默认实现的方法widgetPerformUpdateWithCompletionHandler是做什么的?
最后搜到这篇文章, 大致知道了: 文章地址
#pragma mark - 定时更新机制// 但widget长时间显示, 而有些数据需要实时更新时, 可以通过这个方法更新数据- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {// 判断当前数据是否是最新的// 例:NSArray *devices = [[WWTKGroupDataManager shareInstance] readDevices];// 不是则刷新if (self.devices.count < devices.count) {self.devices = devices;[self.tableView reloadData];}completionHandler(NCUpdateResultNewData);}