实现iOS图片等资源文件的热更新化(五): 一个简单完整的资源热更新页面

简介

一个简单的关于页面,有一个图片,版本号,App名称等,着重演示各个系列的文章完整集成示例.

动机与意义

这是系列文章的最后一篇.今天抽空写下,收下尾.文章本身会在第四篇的基础上,简单扩充下代码,实现在线下载与重置更改的功能.

如果能较为仔细地阅读前四篇文章,第五篇给出的示例,应当是可以理解为无足轻重的.但是,大多数时候,我们更多的可能只是需要一个简易的解决方案,就是那种拿来就可以用的东西,那种我们需要先能看到一个简要的示例来看下效果再解决是否再继续阅读的方案.如此,对于很久以后,由于各种原因被搜索引擎或者其他文章的链接导向此系列文章的人来说,他们可能更想看到一个简要的示例,来决定系列的文章,在他们那个时间点,是否依然有意义.

截止目前而言,我对博客记录本身的定位,依然是属于一个辅助思考的工具.当你看到这篇文章的时候,可能你已经在用Xcode9 Xcode10了,可能代码示例都已经跑不起来了,但是我相信每篇文章所展示的那些参考链接和本身所透漏出的某些思考,或许对于你仍然是有某种启发的.

思路与实现

  1. App版本和名称,可以直接读取;
  2. 在线下载更新资源,可以借助前一篇的代码实现;
  3. 重置的话,可以选择清除补丁信息或者直接清除补丁,本文选择第一种;

核心代码:

我需要先扩展下更新资源的方法,使其在更新完整后,能返回更新的结果,以便于我进行进一步的操作,如重新显示某个图片:

+ (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);
        }
    }];
}

系列文章心得小结

这是第二个系列文章."我们应该相信大多数人们对于美好的东西是有鉴赏的能力" -- 如果能在这一点上达成共识,下面我说的,或许值得继续一读:

几点心得

  • 工作第一,博客分享第二: 我不指望能将来靠博客挣稿费,那也就意味着工作上的事务永远都必须是优先处理的.所以,博客的更新时间并不能真正固定.还有就是,不希望博客分享本身成为一种负担,如果实在没心情或者生活中有其他事的话,我也就真的搁在那,以后再写.
  • 不要被以前的主题束缚,写自己真正需要或者真正感兴趣的:这个系列,从时间上来说,确实比预期的一周迟了一个月;但是从实际效果来看,要比上一个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发展再迅速一点,或许会有极大出线的可能.

参考资源

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏区块链

每天有数百人搜索App破解,开发者该怎么保护自己的手机应用呢?

百度上搜索“App破解”,会出现1210万条结果。从App破解的入门知识到逆向工具下载,从破解技术视频到全图文教程。 随着黑客技术的普及化平民化,App——智能...

2145
来自专栏安恒信息

网络莫名异常?都是“肉机”惹的祸

当前的信息安全建设方案中,安全防护都是针对外部的,而对于内部的威胁却少有关注,尤其是内部主机可能存在通过其他途径被黑的情况,一旦被黑客控制成为“肉机”,可能会感...

2537
来自专栏区块链

第三方组件安全剖析

Apache Struts2再曝高危漏洞 前段时间,Apache Struts2又接连曝出了两个高危远程代码执行(Remoce Code Execution,下...

2319
来自专栏C语言及其他语言

【程序源码】女神节特供

今天3月8号喽,女神节,咱们还是程序猿,最容易孤生的一个人种,得看别人各种虐,小编这就不乐意了,所以奉上祖传源码助大家一臂之力告别单身,各位,瞧好了。 效果...

1925
来自专栏FreeBuf

热榜 | 2015年度渗透测试神器TOP 10

现在,安全研究者对网站或者应用程序进行渗透测试而不用任何自动化工具似乎已越来越难。因此选择一个正确的工具则变得尤为重要,正确的选择甚至占去了渗透测试成功半壁江山...

1858
来自专栏ThoughtWorks

第三方组件安全剖析 | 洞见

Apache Struts2再曝高危漏洞 前段时间,Apache Struts2又接连曝出了两个高危远程代码执行(Remoce Code Execution,下...

2556
来自专栏SDNLAB

虚拟CPE和SD-WAN功能逐步走向融合

对服务提供商而言,虚拟客户端设备(vCPE)以及软件定义广域网(SD-WAN)是能够实现业务目标的不同选择,最终目的都是要向用户提供托管服务。因此,服务提供商面...

2957
来自专栏FreeBuf

新式攻击使用W3C环境光线传感器来窃取浏览器的敏感信息

概述 在这篇文章中,我们将会给大家介绍一种从浏览器中提取敏感信息的方法,而我们所要用到的工具就是你的智能手机或笔记本电脑中的环境光传感器。文章结构如下: 1.首...

1715
来自专栏智能计算时代

工控系统 SCADA(监控和数据采集)系统简介

监控和数据采集- SCADA是指用于控制基础设施流程(水处理,污水处理,天然气管道,风电场等)的ICS(工业控制系统),基于设施的过程(机场,空间站,船舶等) ...

3606
来自专栏黑白安全

渗透测试

渗透测试,也称为笔测试,是针对您的计算机系统的一个模拟网络攻击,用于检查可利用的漏洞。在Web应用程序安全性方面,渗透测试通常用于增强Web应用程序防火墙(WA...

791

扫码关注云+社区