实现iOS图片等资源文件的热更新化(五): 一个简单完整的资源热更新页面
简介
一个简单的关于页面,有一个图片,版本号,App名称等,着重演示各个系列的文章完整集成示例.
动机与意义
这是系列文章的最后一篇.今天抽空写下,收下尾.文章本身会在第四篇的基础上,简单扩充下代码,实现在线下载与重置更改的功能.
如果能较为仔细地阅读前四篇文章,第五篇给出的示例,应当是可以理解为无足轻重的.但是,大多数时候,我们更多的可能只是需要一个简易的解决方案,就是那种拿来就可以用的东西,那种我们需要先能看到一个简要的示例来看下效果再解决是否再继续阅读的方案.如此,对于很久以后,由于各种原因被搜索引擎或者其他文章的链接导向此系列文章的人来说,他们可能更想看到一个简要的示例,来决定系列的文章,在他们那个时间点,是否依然有意义.
截止目前而言,我对博客记录本身的定位,依然是属于一个辅助思考的工具.当你看到这篇文章的时候,可能你已经在用Xcode9 Xcode10了,可能代码示例都已经跑不起来了,但是我相信每篇文章所展示的那些参考链接和本身所透漏出的某些思考,或许对于你仍然是有某种启发的.
思路与实现
- App版本和名称,可以直接读取;
- 在线下载更新资源,可以借助前一篇的代码实现;
- 重置的话,可以选择清除补丁信息或者直接清除补丁,本文选择第一种;
核心代码:
我需要先扩展下更新资源的方法,使其在更新完整后,能返回更新的结果,以便于我进行进一步的操作,如重新显示某个图片:
+ (void)yf_updatePatchFrom:(NSString *) pathInfoUrlStr completionHandler:(void (^)(BOOL success, NSError * error))completionHandler
{
if ( ! completionHandler) {
completionHandler = ^(BOOL success, NSError * error){
// nothing to do...
};
} [self yf_fetchPatchInfo: pathInfoUrlStr
completionHandler:^(NSDictionary *patchInfo, NSError *error) {
if (error) {
NSLog(@"fetchPatchInfo error: %@", error);
completionHandler(NO, error);
return;
} NSString * urlStr = [patchInfo objectForKey: @"url"];
NSString * md5 = [patchInfo objectForKey:@"md5"]; NSString * oriMd5 = [[[NSUserDefaults standardUserDefaults] objectForKey: [self yf_sourcePatchKey]] objectForKey:@"md5"];
if ([oriMd5 isEqualToString:md5]) { // no update
completionHandler(YES,nil);
return;
} [self yf_downloadFileFrom:urlStr completionHandler:^(NSURL *location, NSError *error) {
if (error) {
NSLog(@"download file url:%@ error: %@", urlStr, error);
completionHandler(NO, error);
return;
} NSString * patchCachePath = [self yf_cachePathFor: md5];
[SSZipArchive unzipFileAtPath:location.path toDestination: patchCachePath overwrite:YES password:nil error:&error]; if (error) {
NSLog(@"unzip and move file error, with urlStr:%@ error:%@", urlStr, error);
completionHandler(NO, error);
return;
} /* update patch info. */
NSString * source_patch_key = [self yf_sourcePatchKey];
[[NSUserDefaults standardUserDefaults] setObject:patchInfo forKey: source_patch_key];
completionHandler(YES,nil);
}];
}]; }
然后是一个自定义的在线更新的点击方法:
- (IBAction)onlineUpdate:(id)sender {
__weak ViewController * weakSelf = self;
[UIImage yf_updatePatchFrom:@"https://raw.githubusercontent.com/ios122/ios_assets_hot_update/master/res/patch_04.json" completionHandler:^(BOOL success, NSError *error) {
UIImage * image = [UIImage yf_imageNamed:@"sub/sample"];
weakSelf.sampleImageView.image = image;
}];
}
还需要一个自定义的reset方法,考虑到以后的扩展性和目前的需要,使其支持block传出操作结果:
+ (void )yf_reset:(void (^)(BOOL success, NSError * error))completionHandler
{
if ( ! completionHandler) {
completionHandler = ^(BOOL success, NSError * error){
// nothing to do...
};
} [[NSUserDefaults standardUserDefaults] setObject:nil forKey: [self yf_sourcePatchKey]];
completionHandler(YES, nil);
}
具体使用起来,就很简单,重置后,更新下图片即可:
- (IBAction)reset:(id)sender {
__weak ViewController * weakSelf = self; [UIImage yf_reset:^(BOOL success, NSError *error) {
if (success) {
UIImage * image = [UIImage yf_imageNamed:@"sub/sample"];
weakSelf.sampleImageView.image = image;
}else
{
NSLog(@"reset error:%@", error);
}
}];
}
系列文章心得小结
这是第二个系列文章."我们应该相信大多数人们对于美好的东西是有鉴赏的能力" -- 如果能在这一点上达成共识,下面我说的,或许值得继续一读:
一些数据
- 开源中国 推荐了2篇博客: 已发布的四篇系列文章,有两篇在OSC上获得了小编的全站推荐.
- 简书 首页推荐两篇,获得打赏一次: 简书本身的技术属性,可能算不上很强,但近来搜索技术资料时,有好多都链接指向简书,而且信息大都很及时很新鲜,原因未知,所以最近自己也开始同步在简书更新文章,至于收到打赏,其实就只有2元的辣条钱,但是很明显这个童鞋是搜索某个信息时,被导向了我的文章,而且从其评论来看,确实对其有一定的帮助 -- 我觉得,能够被需要的人看到,这才是最让博主开心的事!
- 微博 相关博文有3位大V转发: 某种程度上,我觉得这算是一种认可.不过,我本身其实并不怎么玩微博;微博的信息太容易被淹没,但如果只考虑传播属性的话,微博的扩散效果其实是极好的.
- segmentfault 把文章添加到头条之后,被segmentfault的CEO 高阳Sunny点赞了两次,微博转发一次.有种受宠若惊的感觉,不过后来我想可能人家更多地只是想推一下新出的"头条"功能.
- csdn首页推荐一次: 通知原文是,"你的实现iOS图片等资源文件的热更新化(四): 一个最小化的补丁更新逻辑被推荐到首页喽!" 这个确实挺值得纪念的!刚开始的时候,我发篇文章,如果有外链,CSDN就必须要审查之后才能被公开看到!
几点心得
- 工作第一,博客分享第二: 我不指望能将来靠博客挣稿费,那也就意味着工作上的事务永远都必须是优先处理的.所以,博客的更新时间并不能真正固定.还有就是,不希望博客分享本身成为一种负担,如果实在没心情或者生活中有其他事的话,我也就真的搁在那,以后再写.
- 不要被以前的主题束缚,写自己真正需要或者真正感兴趣的:这个系列,从时间上来说,确实比预期的一周迟了一个月;但是从实际效果来看,要比上一个Spark系列好很多.但是当初决定这个系列的内容时,我也是很纠结,是要继续Spark大数据题材,还是分享下自己一直想深入研究,却一直抽不出时间的资源包优化问题.最终,还是选择了后者,因为目前对Spark需要的场景,在自己工作中确实不多.
- 记录思路和参考资源,可能比解决方案本身更重要:更多的,是阅读其他人博客的经验;遇到完全一致的问题的可能性很小,而且许多情况下,是从博主的相关引用中关于类似问题更细节的参考中,找到答案的;另外,各种引用资料,可能也给人一种很高大上的感觉.
- 你需要的时间比你预期的要更长: 你以为半个小时可以搞定的文章,可能会花费两个小时,才勉强收尾;你以为很简答的一个技术点,在某个细节上演绎之后,可能会比你想象中更经验.当你意识到,自己正在做的东西,是会被大家公开阅读和鉴赏时,你会不由自主地想多做一点,多查一些,多优化一点,不想显得太low.
小规划
- 题材,坚持系列文章: 我发现系列文章,真的有利于帮助自己进行和坚持深入地有序思考.
- 主题,确定为移动混合开发:最近一年都在用ReactNative开发App,但是单纯地使用,已经不能满足我了,我想深入研究下内部地某些实现机制.作为对比,会研究下勉强算是社区驱动的Weex;另外,还会关注下国内的商业驱动的APICloud平台.
- 内容会涉及iOS,Android,HTML5和自动化脚本: iOS算是本职工作,Android和HTML是自己迫切需要补上的技能,而自动化脚本的编写能力将在很大程度上决定自己自动处理复杂信息的能力和未来的发展 -- 都说Lisp是宇宙第一语言,但目前还是基础的shell脚本用的比较多.
- 文章和评论宜只谈技术: ReactNative 所代表的混合开发的方向,在一定程度上已经获得了国内以BAT为代表的一线技术公司的认可,大家可以去showcase示例具体看下;Weex,目前只是粗读了下文档,三端公用代码,确实有些脑洞,其内部实现应该具有相当程度的学习价值,但其理念不敢苟同,3端共用代码,意味着要取三端各自平台优势的交集,可能也就意味着要牺牲3个平台的各自的独特性和优势 -- 如果真的是这这样,那ReactNative,也是可以自称"一处编写,处处运行"的;APICloud,商业驱动,从产品角度来说,较为完善,混合开发只是服务的一部分,按照目前的发展路线,如果未来HTML发展再迅速一点,或许会有极大出线的可能.
参考资源
实现iOS图片等资源文件的热更新化(五): 一个简单完整的资源热更新页面的更多相关文章
- 实现iOS图片等资源文件的热更新化(四): 一个最小化的补丁更新逻辑
简介 以前写过一个补丁更新的文章,此处会做一个更精简的最小化实现,以便于集成.为了使逻辑具有通用性,将剥离对AFNetworking和ReativeCocoa的依赖.原来的文章,可以先看这里: htt ...
- 实现iOS图片等资源文件的热更新化(零): 序
必要的序 以后在写系列文章,准备把基本的规划和动机等,单独作为一个小的序言部分给独立出来.序言部分,可以较为完整地交待系列文章的写作动机,所展示的编码技术可能的应用场景等.个人,我还是比较看重文章或者 ...
- 实现iOS图片等资源文件的热更新化(三):动态的资源文件夹
简介 此文,将尝试动态从某个不确定的文件夹中加载资源文件.文章,会继续完善自定义的 imageNamed 函数,并为下一篇文章铺垫. 这么做的意义 正如我们经常所说的那样,大多数情景知道做事的意义往往 ...
- 实现iOS图片等资源文件的热更新化(一): 从Images.xcassets导出合适的图片
本文会基于一个已有的脚本工具自动导出所有的图片;最终给出的是一个从 Images.xcassets 到基于文件夹的精简 合适 的图片资源集的完整过程.难点在于从完整图片集到精简图片集,肯定是基于一个定 ...
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
本文转自 :http://www.cnblogs.com/wendingding/p/3761730.html ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布 ...
- iOS开发UI篇—使用picker View控件完成一个简单的选餐应用
iOS开发UI篇—使用picker View控件完成一个简单的选餐应用 一.实现效果 说明:点击随机按钮,能够自动选取,下方数据自动刷新. 二.实现思路 1.picker view的有默认高度为162 ...
- 实现iOS图片等资源文件的热更新化(二):自定义的动态 imageNamed
这篇文章,要解决的是,使用一个自定义的 imageNamed 函数来替代系统的 imageNamed 函数.内部逻辑,将贯穿对比论证 关于"合适"的图片的定义.对iOS加载图片的规 ...
- React Native超简单完整示例-tabs、页面导航、热更新、用户行为分析
初学React Native,如果没有人指引,会发现好多东西无从下手,但当有人指引后,会发现其实很简单.这也是本人写这篇博客的主要原因,希望能帮到初学者. 本文不会介绍如何搭建开发环境,如果你还没有搭 ...
- springmvc获取资源文件的两种方式(超简单)
1 比如我们在sc目录下新建一个db.properties文件内容如下 DriverClass=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306 ...
随机推荐
- dojo事件驱动编程之事件绑定
什么是事件驱动? 事件驱动编程是以事件为第一驱动的编程模型,模块被动等待通知(notification),行为取决于外来的突发事件,是事件驱动的,符合事件驱动式编程(Event-Driven Prog ...
- 【读书笔记】.Net并行编程高级教程(二)-- 任务并行
前面一篇提到例子都是数据并行,但这并不是并行化的唯一形式,在.Net4之前,必须要创建多个线程或者线程池来利用多核技术.现在只需要使用新的Task实例就可以通过更简单的代码解决命令式任务并行问题. 1 ...
- git版本管理策略及相关技巧(A)
公司几乎所有的项目都是使用 git 仓库来管理代码,以前对 git 只有些肤浅的了解,每次提交代码或者上线的时候总是会提心吊胆,生怕出现一些未知的问题.经过三个月的踩坑和填坑, git 操作颇显成熟. ...
- C# Lambda表达式详解,及Lambda表达式树的创建
最近由于项目需要,刚刚学完了Action委托和Func<T>委托,发现学完了委托就必须学习lambda表达式,委托和Lambda表达式联合起来,才能充分的体现委托的便利.才能使代码更加简介 ...
- alwaysOn为什么不支持分布式事务
Alwayson是微软从SQL2012开始引入的一种高可用和高性能架构,它既可以实现故障转移,同时又能实现查询分离,是当前SQL server的所有架构中最优秀的一种. 因此,一般我们都会推荐使用Al ...
- [专业名词·硬件] 1、等效串联电阻ESR概述及稳压电路中带有一定量ESR电容的好处
一.等效串联电阻ESR概述 ESR是Equivalent Series Resistance的缩写,即“等效串联电阻”.理想的电容自身不会有任何能量损失,但实际上,因为制造电容的材料有电阻,电 ...
- C#开源磁盘/内存缓存引擎
前言 昨天写了个 <基于STSdb和fastJson的磁盘/内存缓存>,大家可以先看看.下午用到业务系统时候,觉得可以改进一下,昨晚想了一个晚上,刚才重新实现一下. 更新 1. 增加了对批 ...
- 如何用django开发一个简易个人Blog
功能概要:(目前已实现功能) 公共展示部分: 1.网站首页展示已发布的博客记录,包括名称.摘要信息.发布日期.阅读量及评论数. 2.首页文章列表可按照分类筛选. 3.点击标题或阅读全文链接,进入博客阅 ...
- Redis快速入门详解
Redis入门详解 Redis简介 Redis安装 Redis配置 Redis数据类型 Redis功能 持久化 主从复制 事务支持 发布订阅 管道 虚拟内存 Redis性能 Redis部署 Redis ...
- Java中equals与==和comparaTo的区别
一.先说说Java中equals和==的区别: Java中的数据类型,可分为两类: 1.基本数据类型(也叫原始数据类型) 八大基本数据类型 char byte short int long doubl ...