关于Today Extension

第一次写有关技术的博客,有错误的地方请及时纠正。

扩展介绍

效果图:

最近写了一个app需要用到app扩展(App Extension),本次主要讲的是Today这个扩展,关于Toady的官方介绍自己先看,废话不多说直接写代码,竟然写了那就从申请appID开始:


1.先新建一个项目。。。。。

2.申请ID:


然后点击注册完成;

3申请App Groups



然后点击继续按钮,在点击注册,就会出现以下界面


去iOS App IDs这个界面找到Name为:BlobBlobWidget的ID,点击编辑

然后

点击assign就可以了

4.找到ID发现下面都变绿说明配置成功了,如果不是的话,估计你得重复在来一次


5开始代码项目中的配置

新建扩展


先配置General

在配置Capabilities


好了以上是宿主app也就是主app配置完成。

6.下面配置TodayExtension


在配置Capabilities


以上都配置完了运行以下,正常了就是正常的,不正常就是不正常了,顺便自己看看哪里出的问题,bug在哪里自己心里最清楚,别人都是爱莫能助啊。

7.关于调试

在调试的时候xcode会弹出一个调试框框,让你选择一个主APP。主APP就是要选择你建立的APP;

不知道看懂没有。

8数据的共享

8.1通过用NSUserDefaults共享数据


存储:

#pragma mark存储data

- (void)saveData:(UITextField*)TF{

NSUserDefaults* defaults = [[NSUserDefaultsalloc]initWithSuiteName:@"group.DSLBlobWidget"];

[defaultssetObject:TF.textforKey:@"DSL"];

[defaultssynchronize];

}

获取:

#pragma mark从app那里加载数据以便达到数据共享的目的

- (NSString*)getDatafromMainAPP{

NSUserDefaults*defaults = [[NSUserDefaultsalloc]initWithSuiteName:@"group.DSLBlobWidget"];

return[defaultsobjectForKey:@"DSL"];

}

8.2通过NSFileManger存图片

//copy image to Library

- (void)copyImageToLibrary{

NSString * path = [[NSBundle mainBundle]pathForResource:@"DSL.png" ofType:nil];

NSFileManager * manger = [NSFileManager defaultManager];

NSString * documentPath = [NSHomeDirectory() stringByAppendingPathComponent:@"/Library/Caches/DSL.png"];

NSLog(@"%@",documentPath);

NSError * error = nil;

if (path != nil) {

if (![manger fileExistsAtPath:documentPath]) {

[manger copyItemAtPath:path toPath:documentPath error:&error];

if (error) {

NSLog(@"==copy error==%@",[error

localizedDescription]);

}

}

}else{

NSLog(@"sourcePath is nil");

}

[self copyImage];

}

#pragma mark从app那里加载数据以便达到数据共享的目的(NSFileManger 存图片)

- (void)copyImage{

NSError * error = nil;

NSURL * contentURL = [[NSFileManager defaultManager]containerURLForSecurityApplicationGroupIdentifier:@"group.DSLBlobWidget"];

NSString * newPath = [contentURL URLByAppendingPathComponent:@"/Library/Caches/DSL.png"].path;

[[NSFileManager

defaultManager]copyItemAtPath:[NSHomeDirectory()

stringByAppendingPathComponent:@"/Library/Caches/DSL.png"]

toPath:newPath error:&error];

if (error) {

NSLog(@"copy error==%@",[error localizedDescription]);

}

}






9.代码的共享

第一步:和创建APP Extension一样,New->Target,选择Cocoa Touch Framework来创建framework

第二部:起名字,我的起的名字是DSLWidgetFramework

第三步:


10在APP Extension中不能使用的API

10.1Access a sharedApplication object, and so cannot use any of the methods on that object

不能获取sharedApplication对象

10.2Use any API marked in header files with theNS_EXTENSION_UNAVAILABLEmacro, or similar unavailability macro, or any API in an unavailable framework,For example, in iOS 8.0, the HealthKit framework and EventKit UI framework are unavailable to app extensions.

不能使用API的标志性头文件 和 theNS_EXTENSION_UNAVAILABLE 宏定义,还有一些不能用的框架API,例如HealthKit framework and EventKit UI framework。

10.3Access the camera or microphone on an iOS device (an iMessage app, unlike other app extensions, does have access to these resources, as long as it correctly configures theNSCameraUsageDescriptionandNSMicrophoneUsageDescriptionInfo.plistkeys)

不能获取麦克风和照相机的权限(iMessage 不同于其它的应用扩展,只要配置相关的应用权限就可以直接使用了)

10.4Perform long-running background tasks

不能长期的在后台运行

10.5Receive data using AirDrop

不能使用AirDrop接收相关的数据

以上个人翻译,建议查看官方文档

11 .TodayExtension的进入设置的快捷方式

//打开Wi-Fi

[self.extensionContextopenURL:[NSURLURLWithString:@"Prefs:root=WIFI"]completionHandler:^(BOOLsuccess) {

}];

//打开蜂窝网络

[self.extensionContextopenURL:[NSURLURLWithString:@"Prefs:root=MOBILE_DATA_SETTINGS_ID"]completionHandler:^(BOOLsuccess) {

}];

更多方式请点击这里

请尽量按照以上方式避免被拒绝。

12.与主APP的交互

在扩展中的代码:

- (void)OpenAcstion{

[self.extensionContextopenURL:[NSURLURLWithString:@"DSLTodayWidget://SecondVC"]completionHandler:^(BOOLsuccess) {

}];

}

在主APP中的代码:

AppDelegate

- (BOOL)application:(UIApplication*)app openURL:(NSURL*)url options:(NSDictionary *)options

{

NSLog(@"=====%@",url.scheme);

NSLog(@"===%@===%@",url.host,url.absoluteString);

if([url.absoluteStringhasPrefix:@"DSLTodayWidget"]) {

if([url.hostisEqualToString:@"SecondVC"]) {

//判断是否是直接跳入到添加页面

//self.window.rootViewController = [[SecondVC alloc]init];

UIViewController*rootNav = (UIViewController*)self.window.rootViewController;

[rootNavpresentViewController:[[SecondVCalloc]init]animated:YEScompletion:nil];

}

}

returnYES;

}

13.折叠与展开

首先折叠与展开只有iOS10才有,

所以先要判断系统的版本

if ([[UIDevice currentDevice].systemVersion integerValue]>=10) {

self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;

}

然后实现协议,点击展开或者是折叠会触发这个协议就是NCWidgetProviding协议

- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize

{

//    NCWidgetDisplayModeCompact, // Fixed height

//    NCWidgetDisplayModeExpanded,

if (activeDisplayMode == NCWidgetDisplayModeCompact ) {

//高度最低为110

self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width ,110);

}else{

//因为机子型号不一样所以最大搞多可能不一样,这里设置最大

self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width ,MAXFLOAT);

}

}

除了上面的协议外还有一个协议就是更新扩展UI界面的协议

该协议的具体用法,我没有探究,需要更新这个界面的时候就在这方法里面写

- (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);

}

14.关于使用StoryBoard或者是代码

14.1使用StryBoard如果使用自己定义的类的StoryBoard的话,需要修改info文件


14.2如果是代码的话

你得把NSExtensionMainStoryboard字段删除,添加NSExtensionPrincipalClass字典,value为是你自己建立的类的名称


使用这个方法不要忘记在todayViewController的ViewDidLoad中设置preferredContentSize属性调整大小。

14关于上架,上架的时候扩展app一定是单独的appID,且命名时比如:主appID是com.DSLWidget那么扩展appID是com.DSLWidget.widExten这样尽量按照这个格式来,不要问我为什么之前上架踩过的坑

本次关于Today Extension之旅结束。随后补充。有错请立即通知我,谢谢。

我叫董诗磊就是一码农。

相关代码 


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容