Dmo鏈接
一谎势、什么是today widget
蘋果官方關(guān)于 today widget 的介紹(點擊鏈接查看詳情)
?App extensions in the Today view are called?widgets. Widgets give users quick access to information that’s important right now. For example, users open the Today view to check current stock prices or weather conditions, see today’s schedule, or perform a quick task such as marking an item as done. Users tend to open the Today view frequently, and they expect the information they’re interested in to be instantly available.
A Today widget can appear on the lock screen of an iOS device if the user has enabled this. They do so in the “Allow Access When Locked” area by going to Settings > Touch ID & Passcode > Notifications View.
? ? ? 今日視圖中的 app擴展叫做widget 错沃,widget 可以為用戶提供當前所需簡明扼要的信息 ,例如用戶打開今日查看股票價格或者天氣狀況礼饱,今天的日程表夯膀,待辦事等等。用戶趨向于頻繁的打開widget 以便獲取最新的重要的信息溺健。同時用戶能夠設(shè)置中是否允許 ?today widget ?在鎖屏上出現(xiàn),钮蛛。
二鞭缭、創(chuàng)建一個帶today widget 的工程
打開一個已經(jīng)創(chuàng)建好的程序,選擇File>New>Target> Today Extension ? ?操作如下圖 ? ? ?圖2-1 ?圖2-2
創(chuàng)建完成之后魏颓,我們可以在工程里面看到這幾個文件岭辣。
? ? ? today widget 插件是依靠于宿主程序存在的,宿主程序就是普通創(chuàng)建的程序甸饱。
三沦童、today widget插件和宿主程序之間的數(shù)據(jù)共享
Sharing Data with Your Containing App
Even though an app extension bundle is nested within its containing app’s bundle, the running app extension and containing app have no direct access to each other’s containers.
You can, however, enable data sharing. For example, you might want to allow your app extension and its containing app to share a single large set of data, such as prerendered assets.
To enable data sharing, use Xcode or the Developer portal to enable app groups for the containing app and its contained app extensions. Next, register the app group in the portal and specify the app group to use in the containing app. To learn about working with app groups, seeAdding an App to an App Group.
After you enable app groups, an app extension and its containing app can both use theNSUserDefaultsAPI to share access to user preferences. To enable this sharing, use theinitWithSuiteName:method to instantiate a new NSUserDefaultsobject, passing in the identifier of the shared group. For example, a Share extension might update the user’s most recently used sharing account, using code like this:
// Create and share access to an NSUserDefaults object
NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName: @"com.example.domain.MyShareExtension"];
// Use the shared user defaults object to update the user's account
[mySharedDefaults setObject:theAccountName forKey:@"lastAccountName"];
? ? 雖然擴展程序的包是依賴于宿主程序的包存在的仑濒,但是擴展程序是不能直接訪問宿主程序的沙盒。
?? ?但是你仍然可以偷遗,通過開啟 宿主程序的 appGroup 來使宿主程序和擴展程序之間完成數(shù)據(jù)共享墩瞳。當你開啟app group 之后擴展程序和宿主程序可以使用NSUserDefaults? 的initWithSuiteName方法來存儲數(shù)據(jù)。
例如 :NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName: @"com.example.domain.MyShareExtension"];
[mySharedDefaults setObject:theAccountName forKey:@"lastAccountName"];
給宿主app設(shè)置appGroup 的方法如下圖 3-1 所示
然后點擊加加號在彈出框里面輸入appGroup 的名字鹦肿。如下圖3-2
添加完成之后如下圖3-3
然后打開插件的appGroup 如下圖 圖3-4
創(chuàng)建完成之后矗烛,我們就可以將數(shù)據(jù)存入appGroup中,方便插件和宿主程序共享箩溃。在本次示例中,我將采用對象歸檔碌嘀,解檔的方式將數(shù)據(jù)緩存到本地涣旨,數(shù)據(jù)模型在實現(xiàn)<NSCoding>協(xié)議之后可以通過如下的方法將數(shù)據(jù)緩存到本地
NSURL*mURL = [[NSFileManagerdefaultManager] containerURLForSecurityApplicationGroupIdentifier:@"appGroup 的名稱 (如上面的 "group.STTodyaWidget.data")"];
mURL = [mURL URLByAppendingPathComponent:@"保存的名稱"];
Bool? isSaveSuccess = ([NSKeyedArchiver archiveRootObject:xxxmodel toFile:mURL.path]&& result);
從本地取出數(shù)據(jù)
XXXModel ? *xxxmodel =[NSKeyedUnarchiver unarchiveObjectWithFile:mURL.path];
由于插件和宿主app 是兩個相互獨立的程序,所以股冗,在插件中是不能直接訪問宿主程序的類霹陡,如果要創(chuàng)建一個插件和宿主程序都要使用的類可以勾選下面的勾選框如圖3-5
如果插件需要用到宿主程序里面之前建好的類的話,只需要止状,選中類將下圖中的勾選框勾選上就可以了如下圖 圖3-6
四烹棉、today widget插件的布局
Because user interaction with Today widgets is quick and limited, you should design a simple, streamlined UI that highlights the information users are interested in. In general, it’s a good idea to limit the number of interactive items in a widget. In particular, note that iOS widgets don’t support keyboard entry.
NOTE:
Avoid putting a scroll view inside a Today widget. It’s difficult for users to scroll within a widget without inadvertently scrolling the Today view.
iOS.Because Today widgets don’t allow keyboard entry, users need to be able to use the containing app to configure a widget’s content and behavior. In the Stocks widget, for example, users can switch between different representations of a symbol’s value, but they must open the Stocks app to manage the list of symbols.
today widget ?的設(shè)計應(yīng)該遵從能夠以簡潔的界面為用戶提供高質(zhì)量的信息的原則,today widget 不允許鍵盤的彈出怯疤。盡量不要將scrollview 放到widget 上因為用戶很難在這個頁面進行滑動浆洗。
?4.1 使用sb
我們在創(chuàng)建完today widget 之后,Xcode 會為我們創(chuàng)建好MainInterface.storyboard集峦。我們可以使storyboard 來進行布局伏社。如下圖 圖4-1
運行效果如下 圖4-2
?在viewDidLoad中添加這段代碼可以使用折疊效果
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
}
然后實現(xiàn)代理方法
- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize
{
if (activeDisplayMode == NCWidgetDisplayModeCompact) {
self.preferredContentSize = maxSize;
} else if (activeDisplayMode == NCWidgetDisplayModeExpanded) {
CGFloat height = 你要設(shè)置的展開時候的高度;
self.preferredContentSize = CGSizeMake(0,height );
}
}
如果在10以下的系統(tǒng)我們需要在-(void)viewWillAppear:(BOOL)animated塔淤;里面設(shè)置today widget 的高度摘昌。
if (stsystemVersion < 10.0) {
CGFloat height = self.eventListModel.eventList.count * cellH ;
height? ? ? ? = height > cellH ? height : cellH;
[self setPreferredContentSize:CGSizeMake(0, height+ 30)];
}
如果你想設(shè)置today widget 的內(nèi)邊距可以在這個代理方法中設(shè)置
- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets
{
return? UIEdgeInsetsMake(0, 40, 0, 0);
//? ? return UIEdgeInsetsZero;
}
?4.2使用純代碼
五、today widget跳轉(zhuǎn)到宿主程序
打開宿主程序的 plist 文件 添加URL types 如下圖
然后在today widget 中添加這段代碼高蜂,然后就可以從widget跳轉(zhuǎn)到宿主程序
[self.extensionContext openURL:[NSURL URLWithString:@"STTodayWidget://GOTOEventListVC"] completionHandler:^(BOOL success) {
NSLog(@"open url result:%d", success);
}];
在appdelegate 中添加下面的方法
// 9.0 以后
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options {
}
// 9.0 以前
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
}