iOS应用安装及首次运行时如何检测是否需要更新文件
解决方案
1. 拷贝文件到App Bundle时保留原始时间戳的方法
你遇到的时间戳变更问题是拷贝操作没有保留元数据导致的,可通过以下方式解决:
- 如果你用脚本执行拷贝操作,替换默认的
cp命令为带参数的版本:- 用
cp -a或者cp -p命令,-p参数会保留文件的修改时间、创建时间、权限等元数据 - 更推荐使用Mac原生的
ditto命令,默认就会保留所有文件元数据、资源分支和扩展属性,语法为ditto 源文件路径 目标Bundle路径
- 用
- 如果你用Xcode打包:默认的「Copy Bundle Resources」构建阶段会自动保留文件元数据,如果你使用了自定义的拷贝脚本,按上面的脚本规则调整即可
- 如果你用pkgbuild生成安装包:增加
--preserve-metadata参数即可保留所有文件时间戳和属性
2. 现有实现的问题
你当前的逻辑存在两个明显缺陷:
- 不该用文件创建日期作为判断依据,创建日期仅代表文件第一次生成的时间,文件内容修改后创建日期不会更新,应该改为比较*修改日期(mtime)*才能准确反映文件内容的变更时间
- 单纯依赖时间戳判断容错性很低,除了安装时的时间戳丢失问题,用户手动修改文件、跨设备同步、系统时间修改都会导致判断错误
3. 仅更新变更文件的实现方案
方案1:时间戳方案(改造成本最低)
解决拷贝时保留元数据的问题后,将原有判断逻辑改为比较Bundle内文件和用户目录文件的修改日期,即可符合需求:
- 你昨晚8点更新的文件修改日期为8点,打包进Bundle时保留该时间戳,重装后Bundle内该文件的修改日期晚于用户目录下昨天中午的版本,会触发更新
- 其他未修改的文件修改日期早于或等于用户目录下的文件版本,不会被覆盖
方案2:哈希校验方案(更稳定可靠)
彻底规避时间戳带来的所有问题,完全不受安装过程影响:
- 打包阶段:给所有需要同步到用户目录的文件计算SHA256哈希值,生成一个哈希清单文件(比如
resource_manifest.plist)一并打包进Bundle - 应用启动阶段:先读取内置的哈希清单,逐一遍历目标文件,计算用户目录下对应文件的哈希值,和清单比对:
- 哈希不一致或用户目录文件不存在:删除旧文件,拷贝Bundle内的新文件
- 哈希一致:跳过不处理
内容的提问来源于stack exchange,提问作者Mozahler
相关产品推荐
相关产品推荐

