按需加載資源的方式已經發(fā)布很久了,但一直沒有接觸這方面的只是,因為公司的項目瘦身,所以接觸到了按需加載資源。之前項目已經瘦身了兩輪,不過最近有觸發(fā)了Apple的警告,用戶利益比較重要,故此開始了又一輪項目瘦身。
按需加載的類型:
| Type | Asset catalog | File |
|---|---|---|
| Data file | ?? | ?? |
| Image | ?? | ?? |
| OpenGL shader | - | ?? |
| SpriteKit particle | - | ?? |
| SpriteKit scene | - | ?? |
| SpriteKit texture atlas | ?? | ?? |
| Apple TV Image Stack | ?? | ?? |
按需加載代理的好處:
- Smaller app size. 應用體積更小,在上傳至App Store的時候ipa的體積會更小。
- Lazy loading of app resources. 資源延遲加載,app有一些只在特定情景下使用的資源,當應用可能要進入這些場景時,會請求這些資源。例如,在一個有很多關卡的游戲中,用戶只需要當前關卡和下一關卡的資源。
- Remote storage of rarely used resources.不常用資源的遠程存儲,app有一些很少使用的資源,當需要這些資源時會去請求它們。例如,當app第一次打開時會展示一個教程,而這個教程之后就可能不會在用到。app在第一次啟動時請求教程的資源,這之后只在需要展示教程或者添加了新功能才去請求該資源。
- Remote storage of in-app purchase resources. 應用內購買資源的遠程存儲,app提供包含額外資源的應用內購買。app會在啟動完成后請求已購買模塊的資源。例如,用戶在一個鍵盤app內購買了SuperGeeky表情包。應用程序會在啟動完成后請求表情包的資源。
如何開啟On-Demand Resource:

image.png
On-Demand Resource的三種標簽:
- Initial install tags.此種標簽的資源,會隨著App從App Store下載而下載,但是會影響App的ipa大小,也就是說此種資源會包含在ipa內。
- Prefetch tag order.此種標簽會在App下載后,開始下載相應的資源,下載是存在順序的,后面會說明。此種資源并不會影響ipa的大小,也就是說此種資源并不包含在ipa內。
- Dowloaded only on demand. 此種標簽下的資源,會在必要的時候,主動觸發(fā)下載,這是我們開發(fā)者自己控制下載時機的。
如何設置On-Demand Resource:
點擊導航欄的Resource Tags,然后點擊+按鈕,上述的三種Tags可以隨意設置,此處選擇Prefetched Tag Order,因為要App瘦身,也可以選擇Download Only On Demand,區(qū)別不在贅述。

image.png
前面說過,Prefetched Tag Order是按順序下載的,下載順序為自上而下,下圖中順序為:New->New-1,當然你可以隨意切換。
如何添加資源?官網圖片如下:

image.png
圖片中在對應的Tag下創(chuàng)建了多個文件夾,例如:liama、magic、mountain等等。
點擊圖中New tag entry紅框中New文件夾下的+按鈕,會出現(xiàn)供你選擇的對話框。

image.png
被選中的資源文件,在File inspector中可以看到該資源位于哪個Tags下的那個文件夾中,例如:

image.png
如何使用On-Demand Resource:
系統(tǒng)提供了相應的獲取按需加載資源的類,NSBundleResourceRequest,其提供了2個重要的方法:
-
beginAccessingResourcesWithCompletionHandler:會重App Store下載這些資源 -
conditionallyBeginAccessingResourcesWithCompletionHandler:不會下載資源
使用如下:
// Create an NSSet object with the desired tags
NSSet *tags = [NSSet setWithObjects: @"New", @"New-1"];
// Use the shorter initialization method as all resources are in the main bundle
resourceRequest = [[NSBundleResourceRequest alloc] initWithTags:tags];
// Request access to the tags for this resource request
[resourceRequest beginAccessingResourcesWithCompletionHandler:
^(NSError * __nullable error)
{
// Check if there is an error
if (error) {
// There is a problem so update the app state
self.resourcesLoaded = NO;
// Should also inform the user of the error
return;
}
// The associated resources are loaded
self.resourcesAvailable = YES;
}
];
上述tags中的New、New-1為上述在Prefetched Tag Order中創(chuàng)建的標簽名稱。如何沒有錯誤,New、New-1中對應的資源就可以使用了,使用資源文件的方式和正常加載Bundle中的文件沒有任何差異。
-
注:不要使用同一個NSBundleResourceRequest實例多次請求訪問資源,否則讓會Crash。
判斷資源是否已經下載可以使用conditionallyBeginAccessingResourcesWithCompletionHandler:來判斷,如果回調為NO,則可以調用beginAccessingResourcesWithCompletionHandler:來下載資源。
如何調試On-Demand Resource:
在開發(fā)階段,我們將如何調試,這在研究時真的很費勁,官方文檔并沒有確切的文字說明,WWDC視頻有提到,但是不確切。搜集大量針對文檔和視頻的解讀,以及自己不斷試錯,總結如下:
- Initial install tags. :Testflight測試。
- Prefetch tag order.:Testflight測試、直接Debug測試。
- Dowloaded only on demand. 可以使用私有服務區(qū)存儲資源測試,但上架時需要使用APP Store服務。
使用Dowloaded only on demand.時,測試需要使用私有服務器,需要設置服務器地址:
image.png
制作需要存儲的資源流程:
https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/On_Demand_Resources_Guide/GeneratingHostedContent.html#//apple_ref/doc/uid/TP40015083-CH19-SW1
不過Apple已經更新很久了,和現(xiàn)在Xcode歸檔流程不太一樣,現(xiàn)在Archive后,直接導出至本地,查看ipa文件中的內容如下:
image.png
OnDemandResource中的文件就是需要上傳至私有服務的資源。
參考地址:
https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/On_Demand_Resources_Guide/index.html#//apple_ref/doc/uid/TP40015083-CH2-SW1

