戴維營教育原創(chuàng)文章,轉(zhuǎn)載請注明出處。我們的夢想是做最好的iOS開發(fā)培訓(xùn)!
創(chuàng)新互聯(lián)公司是一家做網(wǎng)站、成都做網(wǎng)站,提供網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,網(wǎng)站制作,建網(wǎng)站,按需定制網(wǎng)站,網(wǎng)站開發(fā)公司,從2013年開始是互聯(lián)行業(yè)建設(shè)者,服務(wù)者。以提升客戶品牌價值為核心業(yè)務(wù),全程參與項目的網(wǎng)站策劃設(shè)計制作,前端開發(fā),后臺程序制作以及后期項目運營并提出專業(yè)建議和思路。
與iOS 9和watchOS 2一起,蘋果引入了一套新的內(nèi)容分發(fā)API,以便節(jié)約設(shè)備空間,這就是按需加載資源。通過使用按需加載資源,我們可以將特定的應(yīng)用程序資源托管在蘋果的服務(wù)器上,然后在需要的時候進行加載。在這個教程中,我將通過開發(fā)一個圖片查看應(yīng)用介紹一下按需加載資源的基本用法。
這個教程需要使用Xcode 7+并且熟悉iOS開發(fā)。可以到Github上下載初始項目。
iOS 9和watchOS 2引入按需加載資源的主要目的是減少單個應(yīng)用程序所占的空間。另外一個好處是我們的應(yīng)用程序能夠更快的被用戶下載下來并且啟動。
通過使用Xcode中的asset pack所唯一分配的tags來獲取按需加載資源。這些資源包可用包含任何asset中的內(nèi)容(圖片、SpriteKit紋理、數(shù)據(jù)等),甚至其它文件如OpenGL和Metal的著色器、SpriteKit和SceneKit的場景文件以及粒子系統(tǒng)。
當(dāng)我們將應(yīng)用提交到App Store時,這些資源也會被上傳和托管,以便需要的時候下載。程序運行的時候,只要使用在Xcode中設(shè)置的tag就可以非常方便的獲取到資源。
使用按需加載資源最多的兩個方面是app bundle,包含可執(zhí)行代碼和重要的資源,例如UI圖標(biāo)和asset packs。
在Xcode中可以將這些資源分為三個主要的類別:
初始安裝: 第一次運行需要的內(nèi)容,過后可以刪除。一般可以包含游戲的開始幾關(guān),當(dāng)游戲進度足夠遠的時候就可以刪除了。
預(yù)取: 這個類別的內(nèi)容在安裝完應(yīng)用后就需要立即下載。這個類型的數(shù)據(jù)應(yīng)該應(yīng)用在那些非必需的資源上,但是如果安裝了可以獲取更好的用戶體驗。比如游戲的新手教程。
按需加載: 在程序運行過程中下載,不會影響程序的運行。這是我們使用最多的按需加載類型。
支持按需加載資源的應(yīng)用程序需要遵循以下限制:
iOS應(yīng)用程序不能超過2GB
初始安裝的tag不能超過2GB
預(yù)取tag不能超過2GB
正在使用的資源不能超過2GB。這一點只有當(dāng)應(yīng)用正在運行并且使用了按需加載資源的時候才起作用。
每個asset pack不能給你超過512MB。如果超過了這個限制,Xcode將給出警告并且允許我們繼續(xù)測試和開發(fā)程序,但是提交到App Store時會失敗。
蘋果為每個應(yīng)用提供最多20GB的空間進行托管,這也是每個程序一次最多可以下載的資源數(shù)量。當(dāng)然,應(yīng)用程序一次最多只能使用2GB的資源。
注意20GB的限制是所有應(yīng)用程序分片的總和,而是總共20GB。那什么是應(yīng)用程序分片呢?應(yīng)用程序分片是iOS 9引入的,用于降低應(yīng)用大小的一個特性。當(dāng)應(yīng)用被安裝后,它只會查找與設(shè)備對應(yīng)的資源。例如,當(dāng)資源被正確使用的時候,iPhone 6 Plus或6s Plus只會加載3x的圖標(biāo),而不會下載1x和2x的。所以整個按需加載資源的總的大小是20GB,包含我們上傳到App Store服務(wù)器的所有設(shè)備類型需要的資源總和。除此以外其它限制條件都是針對特定的設(shè)備類型單獨設(shè)置的。
已經(jīng)下載的按需加載資源只有當(dāng)設(shè)備空間不夠時才會被清理。當(dāng)空間不夠時,按需加載資源系統(tǒng)會查看設(shè)備上的所有應(yīng)用,并且根據(jù)資源的最后使用時間決定刪除哪個。如果應(yīng)用程序正在運行,它擁有的資源永遠都不會被清理。
使用Xcode打開啟動項目并且在模擬器中運行程序。它包含一組圖片,由三種顏色(紅、綠、藍)和四種形狀(圓、正方形、星形和六邊形)組合而成。當(dāng)程序運行的時候,選擇Colors > Red,我們可以看到一個紅色的圓。
我們在程序中設(shè)置7個asset pack,每個包含一種顏色和一個形狀。按需請求資源的另外一個特性是每個資源可以設(shè)置多個Tag。比如紅色的圓可以同時是Red和Circle包的一部分。
按需請求資源API對同一個資源不會下載兩次。換句話說,就是如果已經(jīng)下載Red包,那么在下載Circle包的時候,不會再次下載紅色圓形這個圖片。
在Xcode中,打開Assets.xcassets。我們可以看到12張圖片。
下一步,選擇藍色方塊圖片集,并且打開Attributes Inspector。
在Attributes Inspector中包含一個新的On Demand Resource Tags組,可以用來設(shè)置資源的標(biāo)簽(Tag)。我們給藍色方塊設(shè)置Blue和Square標(biāo)簽。
設(shè)置好資源的Tag后,打開Xcode左側(cè)的Project Navigator,點擊Resource Tags標(biāo)簽并且選擇Prefetched進行過濾。
我們可以非常方便的看到每個資源包的大小以及里面所包含的內(nèi)容。Prefetched中顯示每個類別中的資源,并且允許在不同的類別中進行移動:
初始安裝
預(yù)取
按需下載
這正是我之前所提到的三個類別。Prefetched Tag Order組中的資源在顯示的時候自動開始下載。
設(shè)置好了所有的圖片資源后,就可以開始訪問這些內(nèi)容了。
我們使用NSBundleResourceRequest
獲取App Store服務(wù)器托管的資源包。使用需要獲取的資源的Tag創(chuàng)建request對象。它會告訴系統(tǒng)我們所需要使用的資源包是哪個。而釋放這些對象則告訴系統(tǒng)我們不再需要這些資源包了。一定要注意不能超過2GB的資源限制。
在項目中,打開DetailViewController.swift并且在DetailViewController
中添加一下屬性。
var request: NSBundleResourceRequest!
下一步,替換viewDidAppear(_:)
方法。
override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) request = NSBundleResourceRequest(tags: [tagToLoad]) request.beginAccessingResourcesWithCompletionHandler { (error: NSError?) -> Void in // Called on background thread if error == nil { NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in self.displayImages() }) } }}
剛才的代碼中我們用Tag初始化了一個request
對象。tagToLoad
屬性是在前一個頁面設(shè)置的,表示我們要顯示的內(nèi)容是什么。
下一步,我們通過調(diào)用beginAccessingResourcesWithCompletionHandler(_:)
開始下載特定Tag標(biāo)明的資源包。這個方法自動訪問Tag對應(yīng)的所有資源,并且開始下載。一旦獲取到資源后,其它代碼一切照舊。
注意,如果我們只希望訪問已經(jīng)下載的資源,而不想繼續(xù)加重內(nèi)容。可以調(diào)用conditionallyBeginAccessingResourcesWithCompletionHandler(_:)
。
需要提醒的是,上面方法的執(zhí)行完后,handler是在子線程中執(zhí)行的,因此需要切換到主線程再更新UI。
我們已經(jīng)成功的在程序里使用了按需加載資源,簡單吧!
Xcode 7的有一個重要的調(diào)試特性就是能夠查看當(dāng)前下載了那些資源包。點開Debug Navigator并且選擇Disk就可以看到了。
我們可以改變一下資源的下載優(yōu)先級,這樣有些內(nèi)容就會總是立馬下載。同時還可以改變資源的保存優(yōu)先級,比如Hexagon和Star會在Circle和Square之前清理。將代碼改成一下樣子:
override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) request = NSBundleResourceRequest(tags: [tagToLoad]) request.loadingPriority = NSBundleResourceRequestLoadingPriorityUrgent NSBundle.mainBundle().setPreservationPriority(1.0, forTags: ["Circle", "Square"]) NSBundle.mainBundle().setPreservationPriority(0.5, forTags: ["Hexagon", "Star"]) request.beginAccessingResourcesWithCompletionHandler { (error: NSError?) -> Void in // Called on background thread if error == nil { NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in self.displayImages() }) } }}
初始化request對象后,我們可以設(shè)置loadingPriority
屬性為NSBundleResourceRequestLoadingPriorityUrgent
。當(dāng)然,也可以設(shè)置0-1之間的任意值來表明加載優(yōu)先級。
這個常量自動設(shè)置請求為最高加載優(yōu)先級,但是這取決于當(dāng)前的CPU活動情況。在某些情況下,如果CPU任務(wù)繁忙,資源的下載可能會被推遲。
下一步我們通過mainBundle的setPreservationPriority(_:forTags:)
設(shè)置四個形狀的保存優(yōu)先級。這時我們就可以確認,一旦按需加載系統(tǒng)需要清理一些資源的時候,就會先刪除Hexagon和Star。
現(xiàn)在我們知道了如何在iOS應(yīng)用里使用按需加載資源。下面我想給大家介紹一些需要注意的地方。
為了減少資源的加載時間,使得每個資源更容易訪問,應(yīng)該讓每個資源包保持盡可能的小。這樣就不會導(dǎo)致被過度清理。
例如,系統(tǒng)本身需要釋放50MB的空間,但是如果最合適被刪除的包是400MB,這樣就會導(dǎo)致350MB的內(nèi)容被不必要的刪除。這就意味著下次需要的時候又要多下350MB。建議每個資源包的大小應(yīng)該接近64MB。
如果你的應(yīng)用有一個非常容易預(yù)見的用戶操作過程,最好是提前就開始下載資源。這樣可以提高用戶體驗,而不需要他們等待太久。
游戲是一個非常常見的場景。如果一個玩家已經(jīng)完成了前5關(guān),我們最好在他玩第6關(guān)的時候,開始下載第7關(guān)。
如果不在需要訪問某個資源包,確保釋放NSBundleResourceRequest
對象或者調(diào)用endAccessingResources
方法。
這樣不僅可以防止我們的應(yīng)用達到2GB的限制,而且可以幫助系統(tǒng)知道什么時候需要訪問這些資源,從而更好的決定如何刪除資源來獲取更多空間。
在我的另外一篇關(guān)于tvOS的博客提到tvOS的應(yīng)用限制。比如最大程序大小為200MB,因此更應(yīng)該使用按需方法資源。
tvOS和iOS的按需訪問資源的其它限制是一樣的,只是要注意tvOS僅使用1x的圖片,因此并不會因為應(yīng)用程序分片的存在而減少空間。
iOS 9和tvOS上的按需加載資源是用來減少程序大小和提供更好用戶體驗的一個非常重要的方法。它非常容易使用和設(shè)置,但是要注意它的加載時間和數(shù)據(jù)清理所帶來的一些問題。
戴維營學(xué)院(高級開發(fā)視頻): http://v.diveinedu.com
潛心俱樂部(iOS面試必備): http://divein.club
網(wǎng)站題目:Ios和tvos按需請求資源簡介
分享URL:http://aaarwkj.com/article10/pccjdo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、定制網(wǎng)站、網(wǎng)站排名、網(wǎng)站收錄、網(wǎng)站制作、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)