iOS - 资源按需加载 - ODR

一、瘦身技术大图

二、On-Demand Resources 简介

将其保存管理在苹果的服务器,按需使用资源、优化包体积,实现更小的应用程序。ODR 的好处:

  • 应用体积更小,下载更快,提升初次启动速度
  • 资源会在后台下载
  • 操作系统将会在磁盘资源不够的时候清理 ODR

三、实现

3.1、创建标签

标签的理想大小小于或等于64 MB。这种尺寸在下载速度和本地存储空间之间提供了良好的平衡,以便在设备的本地存储空间不足时进行清理。

  • Initial install tags:初始安装标签,资源与应用程序同时下载;
  • Prefetch tag order.:预取标签顺序,安装应用程序后,资源开始下载;
  • Dowloaded only on demand:仅按需下载。当应用程序要求时,标签会下载;

3.2、pod组建引用

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| s.on_demand_resources = { 'Tag1' => 'file1.png' } s.on_demand_resources = { 'Tag1' => 'file1.png', 'file2.png' } s.on_demand_resources = { 'Tag1' => { :paths => 'file1.png', 'file2.png', :category => :download_on_demand } } s.on_demand_resources = { 'Tag1' => { :paths => 'file1.png', 'file2.png', :category => :initial_install } } |

3.3、访问和下载资源

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| - (NSBundleResourceRequest *)requestOdrWithTags:(NSSet<NSString *> *)tags { NSBundleResourceRequest *request = \[NSBundleResourceRequest alloc initWithTags:tags]; /// 检查设备上是否已有标签 request conditionallyBeginAccessingResourcesWithCompletionHandler:\^(BOOL resourcesAvailable) { if (!resourcesAvailable) { /// 资源不在本地 \[request beginAccessingResourcesWithCompletionHandler:\^(NSError \* _Nullable error) { if (error) { /// 下载失败 \[self failRetryWithTags:tags; } else { /// 下载成功 self.retryDelay = 0; } }]; } else { /// 资源已存在 self.retryDelay = 0; } }]; return request; } |

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| @interface IMYOdrManager () /// 持有 NSBundleResourceRequest,资源才会被使用,要不然会被释放 /// 每个NSBundleResourceRequest 对象只能用于一个请求访问/结束访问周期。 @property (nonatomic, strong) NSBundleResourceRequest *request; @end @implementation IMYOdrManager @synthesize tagName; IMY_KYLIN_FUNC_LAUNCHED_ASYNC { NSSet *set = NSSet setWithObject:@"IMYLevel1"; \[IMYOdrManager sharedInstance reloadOdrWithTags:set]; } + (instancetype)sharedInstance { static id instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = self new; }); return instance; } - (instancetype)init { if (self = super init) { self addObserver; } return self; } #pragma mark - public - (void)reloadOdrWithTags:(NSSet *)set { self.tagName = set; self reloadOdr; } - (void)reloadOdr { if (self.tagName.count > 0) { self.request = \[IMYOdrDownloadManager new requestOdrWithTags:self.tagName]; // 设置优先级 between 0.0 and 1.0 self.request.loadingPriority = 1.0; } } #pragma mark - private - (void)addObserver { /// 低空位警告 @weakify(self); \[\[\[\[NSNotificationCenter defaultCenter rac_addObserverForName:NSBundleResourceRequestLowDiskSpaceNotification object:nil] deliverOnMainThread] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSNotification *notify) { @strongify(self); self.request endAccessingResources; }]; } @end |

3.4、一些额外方法

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| /// 暂停当前下载 - (void)pauseOdr { self.request.progress pause; } /// 恢复当前下载 - (void)resumeOdr { self.request.progress resume; } /// 取消当前下载 - (void)cancelOdr { self.request.progress cancel; } |

3.5、运行后的效果

3.6、通常的设计原则

  • 必要时可用
  • 下载期间影响最小
  • 对应用程序内存的影响最小

四、参考文献

相关推荐
末代iOS程序员华仔10 小时前
iOS 5.6 条例解决方法
flutter·ios·swift
末代iOS程序员华仔16 小时前
Guideline 5.6 - Developer Code of Conduct
flutter·ios·swift
2501_9159184118 小时前
Flutter项目配置iOS混淆的详细步骤与工具推荐
android·flutter·ios·小程序·uni-app·cocoa·iphone
凡泰AI18 小时前
如何通过小程序多端框架,让一个小程序同时运行在iOS、安卓、鸿蒙和微信客户端,实现开发层面的降本增效
android·ios·微信小程序·小程序·harmonyos
2501_915106321 天前
安卓抓包软件2026,免证书抓包 应用层抓包 代理抓包全解析
网络协议·计算机网络·网络安全·ios·adb·https·udp
kango1 天前
Xcode、模拟器Runtime、真机符号完整知识手册
ios·app
用户38034165882972 天前
50MB 红线下的 iOS 录屏引擎:ReplayKit Broadcast Extension 实战
ios
Privasa-隐私实验室2 天前
跨端技术选型|Flutter搭建隐私加密App,安卓与iOS双端差异适配实战
android·笔记·安全·flutter·ios·隐私安全·aes-256
sakiko_2 天前
OC基础语法(与Swift对比)-1
开发语言·ios·objective-c·swift
未来猫咪花2 天前
Everything is ViewModel:让状态管理回到对象世界
android·flutter·ios