擴展是iOS8後系統開發給開發者的新開發思路與接口,每個擴展均可以理解爲一個簡單的小應用程序,只是其不是獨立存在的,要寄附於某一個主應用上。介紹iOS8擴展與Today插件的專題見以下博客:網絡
iOS8中擴展與Today插件:http://my.oschina.net/u/2340880/blog/485533。app
上述博客中只是簡單的介紹擴展的應用場景與建立Today擴展插件的方法,在實際開發中,因爲擴展是寄附於某個應用程序之上的,所以其一般須要和宿主APP進行數據交互。建立Today擴展Target後,Xcode模板會自動幫助開發者生成一個ViewController做爲主界面,開發者能夠向其中添加展現UI或者交互控件,十分強大的是,Today擴展中是支持對UIViewController的切換的。須要注意,擴展與原APP是在不一樣的目錄結構中的,默認狀況下,擴展與原APP的數據並不共享,代碼也不能複用。例如原APP中可能有網絡請求,數據持久化存儲等結構框架,擴展中不能夠直接使用,擴展須要提供本身的網絡請求框架愛,數據持久化結構框架等。框架
若是項目是使用Pod進行的管理,則能夠經過手動設置,使擴展中可使用繼承的Pod庫,步驟以下:測試
完成上面兩張圖中的步驟,便可在擴展中使用Pod庫了。ui
Xcode擴展模板建立的ViewController會自動遵照NSWidgetProviding這個協議,這個協議中的方法和意義以下,開發者能夠根據需求選擇實現:url
//數據更新時調用的方法 系統會按期更新擴展 - (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult result))completionHandler; //設置擴展UI邊距 注意 在使用Storyboard時,若要所見即所得 這個方法中須要返回UIEdgeInsetsZero - (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets;
注意:Today擴展有其本身的plist配置文件,若須要對擴展進行配置,注意不要與宿主工程的plist文件混淆。spa
在Today擴展中打開原宿主APP使用openURL的方式,示例以下:.net
[viewController.extensionContext openURL:[NSURL URLWithString:[NSString stringWithFormat:@"MyApp://action=%@",@"action"]] completionHandler:nil];
上面打開原宿主APP的代碼中,MyApp是宿主APP配置的url Schemes,配置方式以下圖:插件
能夠經過爲url配置參數的方式來進行Today擴展與原宿主APP的信息交互,當擴展使用openURL的方式打開原宿主APP時,宿主APP會調用AppDelegate中的以下方法:調試
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{ //能夠拿到url作相應邏輯處理 UIAlertView * alert = [[UIAlertView alloc]initWithTitle:url.absoluteString message:nil delegate:nil cancelButtonTitle:@"肯定" otherButtonTitles:nil, nil]; [alert show]; return YES; }
上面介紹的openURL的方式只是進行跳轉交互,參數傳遞,並不能完成數據共享的需求,而且經過openURL的方式傳遞的數據是單向的。實際上,擴展和原宿主APP共享數據的應用場景十分普遍,例如電商類宿主APP中拉取到一批商品信息,Today擴展中也須要這些信息進行展現,若是數據不共享,一樣的數據將在宿主APP內部和擴展都都請求一次,十分浪費,難很難同步。系統還提供了另外一種方式來使宿主APP和Today擴展能夠共享一塊存儲空間,這須要使用App Group技術來實現。開發者在進行App Group相關功能的測試時,必須與AppID進行關聯。
首先,須要開啓宿主APP的App Group,示例圖以下:
在Today擴展中,選擇相同的App Group,以下:
開啓了App Group功能後,Xcode會自動生成一套匹配的權限文件,以下:
配置工做完成後,能夠經過兩種方式共享數據存儲空間,示例以下:
//使用數據共享的NSUserDefaults 這個NSUserDefaults是宿主APP與擴展所共享的 NSUserDefaults * defaults =[NSUserDefaults alloc]initWithSuiteName:@"開發者設置的AppGroup名稱"]; //使用數據共享的文件目錄 NSFileManager * manager = [NSFileManager defaultManager]; //共享目錄 NSURL * baseURL = [manager containerURLForSecurityApplicationGroupIdentifier:@"開發者設置的AppGroup名稱"]; //找文件 NSURL * filePath = [baseURL URLByAppendingPathComponent:@"file"];
注意:還有一點細節須要注意,擴展與原宿主APP素材文件也是互相獨立的,要在擴展中使用的素材必須添加進擴展Target。
小提示:使用Xcode調試擴展時,須要運行擴展的Target,開發者有時會發現斷點失效,將模擬器上的應用刪掉,從新運行擴展便可解決。
Demo地址:http://pan.baidu.com/s/1bp0ZcYF。
截圖:
專一技術,熱愛生活,交流技術,也作朋友。
——琿少 QQ羣:203317592