在最新的WWDC14上面,蘋果發布了iOS8的一些新特性,而其中最讓程序員興奮的特性莫過於Extension,或者稱之為Widget。
下面就來嘗鮮試驗一把。
一、Extension簡介
首先,蘋果只支持下面這種類型的Extension Point,也不支持第三方應用自己設置Extension Point 。
Extension point |
Example extension that helps users: |
Today (iOS and OS X) |
Get a quick update or perform a quick task in the Today view of Notification Center (A Today extension is called a widget) |
Share (iOS and OS X) |
Post to a sharing website or share content with others |
Action (iOS and OS X) |
Manipulate or view content within the context of another app |
Photo Editing (iOS) |
Edit a photo or video within the Photos app |
Finder (OS X) |
Use a remote file storage service in OS X |
Storage Provider (iOS) |
Choose a document from among the set of documents the current iOS app can access |
Custom keyboard (iOS) |
Replace the iOS system keyboard with a custom keyboard for use in all apps |
今天,我們只聚焦於Today的Extension。Notification Center是在iOS5的時候推出的,在推出之時,開發者就在想是否可以進行定制,是否可以在上面添加一些應用相關的資訊,三年后,iOS8的推出終於完成了這個使命。
Extension和App不一樣,他相當於一個輕量的App。在每個程序的安裝包里面都可以帶上多個Extension,每一個Extension是一個target。
Extension的生命周期是比較短的,基本如下同所示:
對於一個NoficationCenter Extension而言,當用戶拉下NoficationCenter的時候開始運行,當用戶關閉NoficationCenter的時候會結束,所以必須保證每一個Extension必須是輕量而且快。所以在你完成你的更新操作之后,系統會使用上一次退出時的截圖來做顯示,這個邏輯和App是一樣的。
而Extension和App之間的通信只能通過OpenURL和Shared Resources的方式來通信,因為往往在運行Extension的時候App可能沒有在運行,所以只能通過一共享資源池的文件進行交互,如下圖:
二、一個簡單的DEMO
下面我們來寫一個簡單的Extension:
第一步,我們來創建一個新的Target,然后選擇Extension,再選擇Today:
我們可以看到,基本上一個Extension就是一個ViewController,所以ViewController中的ViewWillAppear等的回調在這里也是生效的,完全可以當做一個ViewController來處理.
我們運行一下並且在NotificationCenter添加我們的Extension后可以看到,系統創建了Hello World的內容了:
如果你需要定制化你的ViewController的高度的話,可以使用AutoLayout或者調用ViewController的preferredContentSize來設置你需要的大小。
第二步,獲取內容
僅僅是這樣一個Extension並不能做些什么,所以我們需要一些必須的數據做展示,而數據的內容可以通過Extension自身去網絡獲取,也可以通過App來獲取,這里說一下App獲取怎么做。
首先,要通信的App和Extension必須在同一個App Group里面,在Xcode的項目配置里面的Capabilities里面找到App Group這一項,打開,並且通過開發賬戶登錄來生成一個App Group,並且將App和Extension都加入這同一個App Group。
然后,在本地創建一個純文本,里面打上需要在Extension上面顯示文字,然后在啟動的時候加入下面的代碼,其中的GroupIdentifier是創建的App Group的標識符。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
NSURL * fileURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.notificationcenter.extension.com" ] ;
NSURL * sourceURL = [NSURL fileURLWithPath: [[ NSBundle mainBundle ] pathForResource:@"helloextension" ofType:@"txt"] ] ;
NSURL * targetURL = [ NSURL URLWithString:[ [fileURL absoluteString] stringByAppendingString : @"helloextension.txt" ] ] ;
[[ NSFileManager defaultManager] moveItemAtURL:sourceURL toURL:targetURL error:nil ] ;
return YES;
}
然后在Extension里面加入以下代碼:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSURL * fileURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.notificationcenter.extension.com" ] ;
NSURL * targetURL = [ NSURL URLWithString:[ NSString stringWithFormat:@"%@/helloextension.txt" , [fileURL absoluteString] ] ] ;
NSString* nsString = [ NSString stringWithContentsOfURL:targetURL encoding:NSUTF8StringEncoding error:nil] ;
_label.text = nsString ;
[_label sizeToFit ] ;
}
運行就得到如下效果:
當然,這個DEMO只是簡單地描述了怎么去完成一個Extension,在實際過程中需要面對如何復用Framework,如何處理多進程同時讀寫同一個文件,和一些安全認證的問題,這里只是簡單地試驗了一把。
【參考資料】