iOS9完整改動: https://developer.apple.com/library/content/releasenotes/General/WhatsNewIniOS/Articles/iOS9.htmlcss
一種可以方便的經過傳統http或https 連接來啓動 APP, 使用相同的網址打開網站和 APP。html
//委託回調 - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{ NSURL *url = userActivity.webpageURL;//webpageURL屬性來獲取URL return YES; }
參考連接: iOS 9學習系列:打通 iOS 9 的通用連接http://www.cocoachina.com/ios/20150902/13321.html iOS 9 通用連接http://www.jianshu.com/p/c2ca5b5f391fios
應用搜索提供新方式以搜索應用內的公開信息,即時設備上還沒有安裝該應用。此類信息可被Handoff,Siri和Spotlight檢索。 任何內容均可經過蘋果公司的服務器索引。設備上的本地內容一開始只能在本地搜索使用,當一樣的檢索發生在多個設備上時,內容將被髮送到蘋果公司的服務器,而且創建索引以供不少設備使用。web
Handoff中使用了一個「活動」的概念,它能夠在多臺設備間傳遞用戶的「活動」。當用戶從一臺設備切換到另外一臺設備後,用戶徹底能夠不中斷原有的「活動」,也不須要從新配置應用程序。在這個過程當中,Handoff將自動在iOS設備和Mac間保持應用程序的同步。 首先,想要活動可以在設備間傳遞,這些設備必須在足夠近的距離(Handoff設備間使用藍牙進行通訊)。除此以外,爲了識別用戶,咱們必須擁有有效的iCloud帳號,且必須是登錄同一個iCloud帳號。在App中使用Handoff,大體分爲如下幾個步驟: (1)建立須要在不一樣設備間傳遞的活動; (2)在用戶活動的過程當中,更新用戶活動的數據; (3)將用戶活動傳遞到其餘設備;json
Handoff操做: https://jingyan.baidu.com/article/73c3ce2809d8f6e50343d9f0.html瀏覽器
Handoff開發: 官方文檔:https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html服務器
下面三種方式將內容提供給應用內搜索: *NSUserActivity類中的新方法和屬性可用於檢索 *Core Spotlight框架將應用的相關內容添加到設備上的索引,而且支持與應用深層連接 *Web標記讓網頁內容可被檢索cookie
1.NSUserActivity網絡
//根據一個已註冊的活動類型建立一個活動 NSUserActivity *activity = [[NSUserActivity alloc]initWithActivityType:@"com.mydomain.plist.activity.type"]; //設置在搜索結果中展現的標題 activity.title = @"iOS 9 Fratures"; //與數據關聯的關鍵詞 keywords屬性用於連接關鍵詞 activity.keywords = [NSSet setWithObjects:@"ios9",@"new features",@"wwdc2017", nil]; //設置一個與活動相關的NSDictionary類型數據 activity.userInfo = @{}; //設置活動可用於搜索 表示數據可用於本地搜索 activity.eligibleForSearch = YES; //設置活動可用於公開索引。數據將會發往蘋果服務器並創建索引。他將會在公開的Spotlight與Safari搜索結果中出現,而且根據人氣指數排名 activity.eligibleForPublicIndexing = YES; //標識應用當前的狀態(激活該活動),一旦完成它將被添加到通用索引(CSSearchableIndex)中。 [activity becomeCurrent];
提供充足的關鍵詞使得內容可被檢索,但切勿濫用。注意,檢索多是本地運行的,多個關鍵詞不只會下降排名,同時也會下降搜索速度 userinfo可用於存儲與活動相關的自定義數據。由於數據將存儲在應用外,因此儘量保持小的體積。這些數據在簡歷索引時會被序列化,而用戶打開搜索結果時會反序列化。數據越多,耗時越長app
2.Core Spotlight
#import <CoreSpotlight/CoreSpotlight.h> //使用Core Spotlight接口須要導入的頭文件 #import <MobileCoreServices/MobileCoreServices.h>//使用UTI類型常量須要導入的頭文件 //CSSearchableItemAttributeSet可用來定義於索引內容相關的屬性 CSSearchableItemAttributeSet *attrs = [[CSSearchableItemAttributeSet alloc]initWithItemContentType:@"SearchAPI"]; //屬性title和ontentDescription控制搜索結果的展現效果 attrs.title = @"Mango"; attrs.contentDescription = @"King of Fruits"; attrs.keywords = @[@"mango",@"fruit",@"vegetation"]; //可被索引的對象 CSSearchableItem *item = [[CSSearchableItem alloc]initWithUniqueIdentifier:@"mango" domainIdentifier:@"com.mydomain.item-domain" attributeSet:attrs]; //CSSearchableIndex是幫助建立索引的主要的類,defaultSearchableIndex是設備上的全局索引 //indexSearchableItems:completionHandler:方法容許異步檢索多個項 [[CSSearchableIndex defaultSearchableIndex]indexSearchableItems:@[item] completionHandler:^(NSError * _Nullable error) { if (error){ //錯誤流程 }else{ } }]; //用戶點擊來自應用的搜索結果時,被調用 -(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{ //activityType在此例中老是CSSearchableItemActionType if([CSSearchableItemActionType isEqualToString:userActivity.activityType]){ NSDictionary *detail = userActivity.userInfo; //必須使用CSSearchableItemActivityIdentifier的鍵來提供以前建立CSSearchableItem使用的惟一ID NSString *tiemID = [detail objectForKey:CSSearchableItemActivityIdentifier]; } return YES; }
性能相關建議 *在title和description中提供充足的信息,但不要使他們過於冗長,不然不但用戶沒法看全數據,並且會影響序列化/反序列化的耗時 *不要過分使用keyword,除了可能招致懲罰,還會影響索引建立和搜索性能 *儘量減小用戶活動的userinfo字典提供的內容,只提供快速展現特意結果所需的數據
官方文檔https://developer.apple.com/documentation/corespotlight/cssearchableitemattributeset?language=objc
3.Web標記 智能應用廣告條:https://apple.co/1NnawJc Applebothttps://support.apple.com/en-us/HT204683 元標籤:https://apple.co/1qMnZ7L
*使用通用連接。網頁和應用應當對同一個連接展現相同的內容。 *對同一內容創建索引時使用同一ID,這將確保對相同內容得到更好的訪問排名。 *使用description屬性提升用戶體驗。 *儘量提供縮略圖。 *明智的選擇關鍵詞。 *以有限狀態機的方式來實現應用,確保引導到應用的搜索結果能夠被優雅地處理。
UIStackView
stackView = [[UIStackView alloc] init]; stackView.backgroundColor = [UIColor orangeColor]; //子控件的佈局方向 stackView.axis = UILayoutConstraintAxisHorizontal; /** UIStackViewDistribution UIStackViewDistributionFill = 0, UIStackViewDistributionFillEqually, UIStackViewDistributionFillProportionally, UIStackViewDistributionEqualSpacing, UIStackViewDistributionEqualCentering, */ //控制視圖的大小。該值的大小和位置沿着UIStackView的座標軸分佈 stackView.distribution = UIStackViewDistributionFill; //間隔距離 stackView.spacing = 10; //iOS11增長可變間距 // stackView.setCustomSpacing(10, after: view1) /** UIStackViewAlignment UIStackViewAlignmentFill, UIStackViewAlignmentLeading, UIStackViewAlignmentTop = UIStackViewAlignmentLeading, UIStackViewAlignmentFirstBaseline, UIStackViewAlignmentCenter, UIStackViewAlignmentTrailing, UIStackViewAlignmentBottom = UIStackViewAlignmentTrailing, UIStackViewAlignmentLastBaseline, */ //控制視圖的對齊方式 stackView.alignment = UIStackViewAlignmentFill; //控制受管理視圖間的垂直間距是否根據基線測量獲得。若是是yes,那麼間距是從一個文字視圖的文字最後一行到其後面視圖的文字第一行計算的。 stackView.baselineRelativeArrangement = YES; //決定StackView平鋪受管理的視圖時是否參照了它的佈局邊距或邊界。默認是no,表示使用邊界 stackView.layoutMarginsRelativeArrangement = NO; stackView.frame = CGRectMake(0, 100, ScreenWidth, 200); [self.view addSubview:stackView]; //添加視圖 [stackView addArrangedSubview:view]; //刪除視圖 [stackView removeArrangedSubview:view]; [view removeFromSuperview];
UIStackView是UIView的非渲染型子類。於UIView的其餘子類不一樣,它不在畫布上進行渲染。所以重寫drawRect:方法,它對最終效果沒有任何影響。改變backgroundcolor等其餘屬性也是同樣的效果
官方文檔:https://developer.apple.com/documentation/uikit/uistackview
iOS9新增的SFSafariViewController,使用Safari瀏覽器的cookie,並在單獨的進程中運行。這意味着,若是用戶使用Safari登錄過,瀏覽操做就能無縫進行。 應用的cookie並不共享給Safari視圖控制器,若是用戶盡在應用中登錄過,那麼還須要再次登錄
//導入頭文件 #import <SafariServices/SafariServices.h> //SFSafariViewControllerDelegate代理 NSString *urlString = @"http://www.baidu.com"; //直接跳轉 SFSafariViewController *sfViewControllr = [[SFSafariViewController alloc] initWithURL:[NSURL URLWithString:urlString]]; sfViewControllr.delegate = self; [self presentViewController:sfViewControllr animated:YES completion:^{ //... }]; //done鍵回調 - (void)safariViewControllerDidFinish:(nonnull SFSafariViewController *)controller { [controller dismissViewControllerAnimated:YES completion:nil]; } //建立添加一些自定義的各種插件式的服務 -(NSArray<UIActivity *> *)safariViewController:(SFSafariViewController *)controller activityItemsForURL:(NSURL *)URL title:(NSString *)title{ UIActivity *action = [[UIActivity alloc]init]; [action activityTitle]; return @[action]; }
官方文檔:https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller?language=objc UIActivity參考:http://www.jianshu.com/p/d500fb72a079
使用Safari或者SFSafariViewController時容許限制內容展現 建立ContentBlocker Extension
- (void)beginRequestWithExtensionContext:(NSExtensionContext *)context { NSItemProvider *attachment = [[NSItemProvider alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"blockerList" withExtension:@"json"]];//過濾定義json文件 NSExtensionItem *item = [[NSExtensionItem alloc] init]; item.attachments = @[attachment]; [context completeRequestReturningItems:@[item] completionHandler:nil]; } //過濾器定義示例 [ { "action": { "type": "block" }, "trigger": { "url-filter": "webkit.svg" } } ]
每次啓動時儘量使用本地文件系統的文件,而不是從網絡上同步 對於動態的過濾器,使用後臺下載,以便與服務器週期性的同步 最小化過濾器條目的數量,這在對複雜網頁進行過濾時會縮小解析時間
參考:http://blog.csdn.net/csr_yang/article/details/49280023 官方文檔:https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/ContentBlocker.html ###3.2Spotlight索引擴展 即使應用不運行時也容許更新設備上應用搜索中的索引。
- (void)searchableIndex:(CSSearchableIndex *)searchableIndex reindexAllSearchableItemsWithAcknowledgementHandler:(void (^)(void))acknowledgementHandler { // Reindex all data with the provided index //調用該方法以觸發索引設備中全部的項 acknowledgementHandler(); } - (void)searchableIndex:(CSSearchableIndex *)searchableIndex reindexSearchableItemsWithIdentifiers:(NSArray <NSString *> *)identifiers acknowledgementHandler:(void (^)(void))acknowledgementHandler { // Reindex any items with the given identifiers and the provided index //調用該方法來觸發驗證指定惟一標示符的項的有效性 acknowledgementHandler(); }
爲下載,安裝應用的目標設備建立和分發變種應用包稱爲分割。 *只下載針對處理器體系結構的可執行文件 *按設備支持能力切分GPU資源 *根據設備類型和分辨率切分圖像。
按需加載資源https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/On_Demand_Resources_Guide/指的是APP store上與下載的應用包分離的應用內容。
從iOS9開始,能夠對特意資源(如圖片和音頻剪輯)加標籤,而後經過標籤來管理這些資源 *隨應用打包的資源 *應用第一次啓動後安裝的資源 *根據一個關鍵詞安裝的全部資源 *根據一個關鍵詞刪除的全部資源
App Store中的資源文件->操做系統:下載資源包:應用根據標籤請求資源 操做系統:下載資源包->留存資源包:應用使用資源包 留存資源包->釋放資源包:資源包使用完畢 釋放資源包-->留存資源包:應用根據標籤請求資源 釋放資源包-->App Store中的資源文件:操做系統清理資源包
設置啓用按需加載資源
下一步在Resource Tags中管理標籤及其關聯的資源
資源文件目錄編輯器關聯標籤
// NSBundleResourceRequest管理按需加載標籤的資源的聲明的週期 NSSet *tags = [NSSet setWithArray:@[@"2"]]; //爲應用但願使用的標籤建立一個NSBundleResourceRequest對象 NSBundleResourceRequest *req = [[NSBundleResourceRequest alloc]initWithTags:tags]; //下載請求,處理出現錯誤或下載成功的場景 //[req beginAccessingResourcesWithCompletionHandler:^(NSError * _Nullable error) { //if (error){ //}else{ UIImage *image = [UIImage imageNamed:@"right_menu_QR"]; //} //}]; //檢查資源在設備上是否可用 [req conditionallyBeginAccessingResourcesWithCompletionHandler:^(BOOL resourcesAvailable) { if (resourcesAvailable){ //資源已經可使用,進行處理 }else{ //不可用,也許還未下載或已被清除,如今下載 beginAccessingResourcesWithCompletionHandler } }]; //通知系統已經完成使用給定標籤的資源 [req endAccessingResources];
當應用以bitcode格式提交到iTunes Connect後,將會在APP store 中以原生格式編譯,而且鏈接到最終的二進制文件。 使用bitcode容許蘋果公司再將來對應用的二進制人間進行二次優化,而不須要從新提交一個新版本到APP store。 bitcode對iOS是可選的,但對watchOS是必須的。