iOS学习笔记EdisoniOS

从0到1思考与实现iOS-Widget

2017-03-22  本文已影响2647人  si1ence

讲述之前首先看下demo效果图:

基本的展开收起、本App本体交互

然后再展示几个效果不错的 Widget app


毒物 && Keep ESPN PCalc Musixmatch Fantastical 2 Carrot Weather

demo 地址在此!欢迎star

比心

一、Widget总览


二、Widget代码实现

// 取消widget默认的inset,让应用靠左
- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets {
    return UIEdgeInsetsZero;
}
/**
 activeDisplayMode有以下两种
     NCWidgetDisplayModeCompact, // 收起模式
     NCWidgetDisplayModeExpanded, // 展开模式
 */
- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize {
    if(activeDisplayMode == NCWidgetDisplayModeCompact) {
        // 尺寸只设置高度即可,因为宽度是固定的,设置了也不会有效果
        self.preferredContentSize = CGSizeMake(0, 110);
    } else {
        self.preferredContentSize = CGSizeMake(0, 310);
    }
}

当然有些第三方包含 source 文件的可能还需要别的操作,最简单粗暴的方式就是-->拖进去!


三、与 App 本体交互

与本体 app 进行交互之前,要明白的一个概念是:Widget 与 app 本身 是两个target,appId 也是独立的,因此 Widget 与本体 app 是通过 app group 进行交互

1、设置群组关系

在 本体 App 的 target > Capabilities添加 container 标识符

这个写好之后,再去扩展的target做相同的操作,标识符一定要一样!! 切换 target 的方法在这里
2、设置 scheme 进行交互
// 扫一扫按钮的点击事件
- (void)scanBtnTapped:(UIButton *)sender {
    [self.extensionContext openURL:[NSURL URLWithString:@"wpfWidgetTest://action=richScan"] completionHandler:^(BOOL success) {
        NSLog(@"scanBtnTapped   open url result:%d",success);
    }];
}
// 处理 Widget 相关事件
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    
    NSString* prefix = @"wpfWidgetTest://action=";
    NSString *urlString = [url absoluteString];
    
    if ([urlString rangeOfString:prefix].location != NSNotFound) {
        NSString *action = [urlString substringFromIndex:prefix.length];
        if ([action isEqualToString:@"richScan"]) {
            // 进入到扫一扫页面
            [self.rootVC transferToRichScanVC];
        } else if ([action isEqualToString:@"web"]) {
            // 进入到 web 活动页
            [self.rootVC transferToWebVCWithUrlString:@"webTest"];
        } 
    }
    return  YES;
}
// widget项目里取数据
+ (NSString*)widgetStringForKey:(NSString*)defaultName {
     NSUserDefaults*shared = [[NSUserDefaultsalloc] initWithSuiteName:@"group.com.widgetTest"];
     return[shared stringForKey:defaultName];
}

// 主项目里存数据
+ (void)widgetSetObject:(id)value forKey:(NSString*)defaultName {
    NSUserDefaults*shared = [[NSUserDefaultsalloc] initWithSuiteName:@"group.com.widgetTest"];
    [shared setObject:value forKey:defaultName];
    [shared synchronize];
}

#warning 涉及到大量数据交互也可以使用 NSFileManager 进行数据共享

在demo中,实现了从Widget入口 点击未读消息后,下次不再展示该未读消息项



四、关于刷新时机

五、关于 iOS8 适配

iOS8效果图

六、其他注意点

  1. 当程序内存不足时,苹果优先会杀死扩展,因此需要注意内存的管理。

  2. 在配置team是账号需要一致(免费账号不行,需要付费的账号),上传包的时候一定注意选择 Product -> Archive -> ** 选择 distribution 模式!**

  3. 3D touch 对应的也有Widget!?答案是 YES!,只要设置了3D touch,Widget的第一栏就会自动显示。但是如果有多个widget的话,还需要在 info.plist 指定相应的main target!

Extension 证书配置指南
官网说明
一直很心仪的app --> Things 关于widget的介绍
几个精致的 Widget app
在模拟器上进行3D touch 测试


再次附上 demo Github 地址,欢迎star
上一篇下一篇

猜你喜欢

热点阅读