固予iCoder

iOS的Extension Widget开发:Today

2016-12-07  本文已影响160人  大斌小姜

[TOC]

1、Tips

2、纯代码需要配置info.plist的俩项参数

移除NSExtensionMainStoryboard键,并添加NSExtensionPrincipalClass键,使用view controller的名字作为值。

3、UI样式

- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets: (UIEdgeInsets)defaultMarginInsets {      
    return UIEdgeInsetsZero;
}

4、与主App进行交互

// 
[self.extensionContext openURL:[NSURL URLWithString:@"跳转链接"] completionHandler:^(BOOL success) {
   NSLog(@"open url result:%d",success);
}];

02.png

跳转链接示例:iMyApp://为跳转页面做标识

// iOS 9+
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options {
   // [url.absoluteString hasPrefix:@"iMyApp://"]
   if ([url.host isEqualToString:@"iMyApp"]) {
       // 操作
      return YES;
   }
   return YES;
}
// iOS 7、iOS 8
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
      // [url.absoluteString hasPrefix:@"iMyApp://"]
      if ([url.host isEqualToString:@"iMyApp"]) {
        // 操作
       return YES;
      }
   return YES;
}

5、与主App共享数据

03.png
NSUserDefaults* userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.iMyApp"];
[userDefault setBool:YES forKey:@"islogin"];
NSUserDefaults *myDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.iMyApp"];
BOOL isLogin = [myDefaults objectForKey:@"islogin"];

6、 - (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult result))completionHandler 方法说明

对于扩展App,即使扩展App现在不可见 (即用户没有拉开通知中心),系统也会时不时地调用实现了 NCWidgetProviding 的扩展的这个方法,来要求扩展刷新界面。
这个机制和 iOS 7 引入的后台机制是很相似的。在这个方法中我们一般可以做一些像 API 请求之类的事情,在获取到了数据并更新了界面,或者是失败后都使用提供的 completionHandler 来向系统进行报告

7、定时更新机制(通过增加定时更新的NSTimer)

把NSTimer fire触发代码调用放到viewWillAppear方法中来(viewDidLoad方法并不是每次都执行).同理当Widget关闭后在viewDidDisappear方法取消NSTimer invalidate定时更新即可。

8、关闭today widget中扩展App的显示

有时候在没有数据的时候需要隐藏扩展,可以使用以下方法:

NCWidgetController *widgetController = [NCWidgetController widgetController];
[widgetController setHasContent:NO forWidgetWithBundleIdentifier:@"扩展的id"];

9、iOS10 的适配- 展开、折叠按钮

在NSExtensionContext中,新添了widgetLargestAvailableDisplayMode属性,来确认当前widget是展开还是折叠状态。所以,先在viewWillAppear中设置widget的mode为展开。

self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;

展开和折叠状态变化时的处理

-(void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize {    
  if (activeDisplayMode == NCWidgetDisplayModeCompact) {
    self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 110);    
    // 处理~~    
  } else {        
    self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300);     
    // 处理~~    
  }
}

Xcode 7没有iOS 10,可以通过KVC来解决这个问题

[self.extensionContext setValue:@"1" forKey:@"widgetLargestAvailableDisplayMode"];
  if (activeDisplayMode == 0) {        
    self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 110);    
  } else {        
    self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300);    
  }
} 
//通知主线程刷新
dispatch_async(dispatch_get_main_queue(), ^{    
    //...........;
});
上一篇 下一篇

猜你喜欢

热点阅读