iOS8中Today Extension(Widget)的使用

擴(kuò)展(Extension)是iOS 8中新引入的特性。iOS 8系統(tǒng)有6個支持?jǐn)U展的系統(tǒng)區(qū)域,分別是

  • 今日插件(Today widget)
  • 分享(Share)
  • 操作(Action)
  • 圖片編輯(Photo Editing)
  • 文檔管理(Document Provider)
  • 自定義鍵盤(Custom keyboard)

支持?jǐn)U展的系統(tǒng)區(qū)域也被稱為擴(kuò)展點。對于賽事比分,股票、天氣、快遞,位置信息等需要實時獲取的信息,可以在通知中心的Today視圖中創(chuàng)建一個Today擴(kuò)展實現(xiàn)。Today擴(kuò)展又稱為Widget,本文主要是介紹Today Extension的用法。
蘋果文檔:https://developer.apple.com/library/ios/documentation/General/Conceptual/ExtensibilityPG/NotificationCenter.html
如圖就是Widget效果(UC瀏覽器的)

E221C469511CDE6687B26BC7F6A49362.png

Widget的創(chuàng)建直接在targets里點擊下邊添加就可以了
3CE808F1-1E39-4892-886A-DD00386682AF.png

Xcode6新建的是自帶SB的,直接在模擬器運行,注意圖中箭頭處

379887E7-8DF6-4C99-892D-E85138424B3A.png

運行效果,熟悉的Hello World

B8A41B2A-B787-45A7-BF35-CFA822F561C2.png

博主習(xí)慣了沒有用SB,修改Info.plist文件,刪除SB即可


094C49C8-5D98-49AF-BE78-043E645535E1.png

在TodayViewController的- (void)viewDidLoad方法種添加

self.preferredContentSize = CGSizeMake(0, 200);
self.view.backgroundColor = [UIColor redColor];

運行是如圖效果


7EE8AABD-8624-4BBA-949F-1E99446510A9.png

值得注意:
1、盡量不要使用背景,默認(rèn)的毛玻璃效果很好,也比較統(tǒng)一;
2、盡量保持默認(rèn)的縮進(jìn),即左邊會空幾個像素。
如果想改變默認(rèn)縮進(jìn),有一個方法:

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

在TodayViewController里面實現(xiàn)以下,縮進(jìn)就沒有了,下面說幾點關(guān)鍵的

1.共享數(shù)據(jù)

插件和主應(yīng)用是獨立的兩個進(jìn)程,以前是無法共享數(shù)據(jù)的,現(xiàn)在可以通過AppGroup來共享數(shù)據(jù),同屬于一個group的App可以共享數(shù)據(jù)

C2108126-AF89-412D-86F8-54F5C63369EE.png

target里選擇主應(yīng)用打開App Group,如果之前沒有,則新加group,id格式可如圖,創(chuàng)建之后,在你的Widget里同樣地方勾選上即可,程序間共享數(shù)據(jù)使用的是

//存
NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.xxxx.app"];
[shared setObject:@"value" forKey:@"key"];
[shared synchronize];

獲取數(shù)據(jù)

//取
NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.xxxx.app"];
[shared objectForKey:@"key"];

Name的名字跟上邊添加的App Group需要一致

2.跳轉(zhuǎn)到主應(yīng)用

在widget里按鈕添加點擊事件,跳轉(zhuǎn)到主app不同頁面,widget里是沒有UIApplication類的,所以相關(guān)方法都不能用,所以self.extensionContext代指當(dāng)前widget

- (void)skip:(UIButton *)button
{
   if (button.tag == 1) {
       [self.extensionContext openURL:[NSURL URLWithString:@"iOSWidgetApp://action=GotoHomePage"] completionHandler:^(BOOL success) {
    }];
}
   else if(button.tag == 2) {
       [self.extensionContext openURL:[NSURL URLWithString:@"iOSWidgetApp://action=GotoOtherPage"] completionHandler:^(BOOL success) {
    }];
   }
}

主app里添加協(xié)議


EF825E95-5B33-4063-AF42-7E9008807147.png

然后主app里解析

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    NSString* prefix = @"iOSWidgetApp://action=";
    if ([[url absoluteString] rangeOfString:prefix].location != NSNotFound) {
        NSString* action = [[url absoluteString] substringFromIndex:prefix.length];
        if ([action isEqualToString:@"GotoHomePage"]) {
        
        }
        else if([action isEqualToString:@"GotoOtherPage"]) {
        
        }
    }
    return  YES;
}

3.國際化問題

建議參考下這微博主http://www.itdecent.cn/p/0efd62ee033a 2.6處所提到的,這點需要注意

4.網(wǎng)絡(luò)請求

常用的AF和MK框架中都有用到UIApplication類,無法編譯通過,可以自行修改相關(guān)地方,也可以直接使用AFHTTPSessionManager類,

164F9181-4802-470B-87C3-AB086896A9CF.png

相關(guān)類這些,都沒有用到UIApplication(AFKit.h和AFHTTPShareRequest.h是我自己寫的兩個類),一個是頭文件合集,一個單例類
AFKit.h
#ifndef AFKit_h
#define AFKit_h
#endif /* AFKit_h */

#ifdef __OBJC__
#import "AFHTTPSessionManager.h"
#import "AFNetworkReachabilityManager.h"
#import "AFSecurityPolicy.h"
#import "AFURLResponseSerialization.h"
#import "AFHTTPSessionManager.h"
#import "AFURLSessionManager.h"
#endif

AFHTTPShareRequest.h
#import "AFHTTPSessionManager.h"

@interface AFHTTPShareRequest : AFHTTPSessionManager

+ (instancetype)sharedClient;

@end

AFHTTPShareRequest.m
#import "AFHTTPShareRequest.h"

@implementation AFHTTPShareRequest

+ (instancetype)sharedClient
{
    static AFHTTPShareRequest *client = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        client = [[AFHTTPShareRequest alloc] init];
    });
    return client;
}
@end

(報錯的話看下是不是少導(dǎo)入哪個類庫了?)
最后再說幾點細(xì)節(jié)的地方
- (void)viewDidLoad
方法并不是每次下拉都會調(diào)用(甚至很少調(diào)用),但是
- (void)viewWillAppear:(BOOL)animated
方法一定是會調(diào)用的,所以數(shù)據(jù)實時更新的代碼最好不要寫在 - (void)viewDidLoad方法里;第二點,斷點調(diào)試時,需要用Today 來運行widget才有用,并且用真機(jī)調(diào)試有時打斷點不一定有用,用模擬器一定有用,我感覺這是個bug,用模擬器調(diào)試時每次改動的代碼需要把模擬器退出再重啟(注意這點)才會生效,真機(jī)不需要。
暫時想到的就這么寫東西。第一次開發(fā)Widget坑其實挺多的,建議下手前先多看幾篇相關(guān)文章,會順利許多,如有疑問,歡迎探討
ps:評論有人提到劃出屏幕后再劃回來不能交互,我測試了下,線上版本,iphone6,6p(9.3.2)、iphone6(8.3)沒有這個問題,但是開發(fā)版本確實有這個問題,不知道是不是開發(fā)版本的bug,如有知道此問題的,歡迎留言

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容