好久没有更新博客了,我现在是做阅读APP的,产品经理让我加一个widget书架功能,在widget的列表中添加我们自己分栏,分栏显示最近阅读三本小说的信息,由于是临时加的功能所以一开始没有调研走了很多弯路,现在开发完成,所以与大家分享下,希望可以你其他猿们有所帮助,如果有建议可以通过以下方式回复我
联系方式:
QQ:931637933
163邮箱:jutiefeng123@163.com
微信:j136845
如果大家有意向可以加入我的 QQ群:255217300
好了言归正传,上码。
首先我们先新建一个工程,这一步就省略了,接下来我们增加一个target,选择Today Extension
图1
图2
创建完之后如图
这个时候运行会看到
Xcode默认创建MainInterface.storyboard来构建UI。
采用Xcode默认模板创建Widget时会自动把ViewController文件命名设置为“TodayViewController”.当然这个ViewController命名其实是可以修改的,唯一值得注意的修改该ViewController文件命名后还需要设置NSExtensionPrincipalClass的值与其保持一致即可.不然Widget编译时会报找不到对应入口.
如果想纯代码编写UI,可以删除storyboard文件采用纯代码方式来进行构建,删除完后之后注意需要找到Supporting Files下面的Info.plist中NSExtension字段做如下两个操作:
A:直接删除NSExtensionMainStoryboard字段
B:添加NSExtensionPrincipalClass字段 并设为TodayViewController
调整布局
Widget里面的视图默认居左居下都会有一定距离的间隔,可以采用如下方式取消间隔,使布局区域填充整个Widget
//一般默认的View是从图标的右边开始的...如果你想变换,就要实现这个方法
- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets {
// 系统默认的布局是 UIEdgeInsetsMake(0.0,48, 39, 0);
NSLog(NSStringFromUIEdgeInsets(defaultMarginInsets));
returnUIEdgeInsetsZero;
}
NEXT
我们看下containing app跟extension如何共享数据,例如我containing app里的数据,我要在extension显示。在这之前,我们要先讲下app groups,它主要用于同一group下的app共享同一份读写空间,以实现数据共享。我们看下工程中如何开启app groups,首先们选择targets,然后选择containing app,->Capabilities,打开app groups的开关,如下图:
点下面的加号按钮,新建一个group,例如:group.com.kedll.TestWight,如下图:
创建完后如下图:
同理,选择targets为extension,同样创建一个app groups,选择跟containing app一样的名字,就是containing app里的app groups跟extension里的app groups名字相同,如下图:
app groups创建好后,就可以实现数据共享了,
第一种方法是通过NSUserDefaults,存数据代码如下:
注意事项:
因为Widget和APP相当于两个项目,所以呢,在创建文件的时候,要注意如果你创建的文件是处理Widget和APP之间数据共通的,那么请记住以下选择
一定要两个都勾选
代码呢就很简单了,那我个人是比较喜欢数据封装到一个manager类里面
注意事项:这个groupID 一定要和刚才你项目plist表中的名字一样不然你是无法正确操作数据的
App中保存数据调用save方法,
在Widget的todayviewController(Widget默认视图控制器)里面,这个controller的didloadview方法一开始运行的时候运行一次,willapear里面是下拉一次today走一次,所以你的getWidgetData方法可以写在这个里面,那么页面刷新就可以写在这个getWidgetData方法调用后面,记得
self.preferredContentSize = CGSizeMake(SCREEN_WIDTH, self.widgetArr.count*70);
这行代码一定要写,除非你不想显示你Widget你app分组下的页面,不然你必须要设置这个值
那么怎么从Widget进入app?
首先设置白名单,URLtype,设置scheme:KentWidget
答案只有一句API
NSString *widgetURL = [NSString stringWithFormat:@"KentWidget://"];
NSURL*url = [NSURL URLWithString:widgetURL];
[self.extensionContext openURL:url completionHandler:^(BOOL success) {
}];}
//后面可以传一些你要的参数,不好意思的是只能传递string那么它的回调方法,和回调数据在哪怎么处理呢
毫无疑问白名单的回调一定在appdelegate里
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
ELog(@"url:%@",url);
return [self appCallbackWithopenUrl:url];
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)option
{
return [self appCallbackWithopenUrl:url];
}
以上两个方法区别于不同版本,具体的大家自己试一下,这里给大家一个小小的悬念吧,勿喷啊
-(BOOL)appCallbackWithopenUrl:(NSURL *)url{
if ([url.schemeisEqualToString:@"KentWidget"]){
if (!_homeController.isWidgetFlag)
{
self.widgetHost = url.host;
[self pushReadForWidget];
}
}
return YES;
}
总结一下,大家需要注意以下几点:
1,groupID保持一致
2,添加文件和创建类的时候记得勾选Widget
3,刷新数据需要在todayviewController的didload和willapear里面都要写
4,self.preferredContentSize一定要设置
5,打包出来后,widget的icon一直不显示,找了半天,后来把widget隐藏,在弄出来,妹的,icon又显示了。原来我是通过itools导进手机的,widget默认显示,widget没加载,所以icon就显示不出来了这个只是尝试设置,和这个没关系
联系方式:
QQ:931637933
163邮箱:jutiefeng123@163.com
微信:j136845
如果大家有意向可以加入我的 QQ群:255217300