如何解析并导出NSKeyedArchiver编码的大型plist格式数据
解决方案
核心原理
你遇到的是苹果NSKeyedArchiver序列化生成的plist文件,你疑惑的整数值引用逻辑非常明确:
- 文件根节点下的
$objects是有序数组,所有序列化产生的对象、字符串、数值等内容全部提前存在这个数组中 CF$UID对应的整数值就是$objects数组的下标(从0开始计数),直接取下标位置的元素就是引用指向的实际内容
比如你标注的<integer>24</integer>,对应的实际值就是$objects数组的第24个元素。
可落地操作方案
无需手动逆向分析结构,用Python内置的plistlib库即可快速完成10万条数据的批量导出,操作步骤如下:
- 执行以下脚本读取plist文件并自动解引用所有CF$UID:
import plistlib import csv # 替换为你的plist文件路径 with open("target.plist", "rb") as f: plist_content = plistlib.load(f) obj_array = plist_content["$objects"] # 递归解引用工具,自动处理嵌套的UID引用 def resolve_ref(value): if isinstance(value, dict) and "CF$UID" in value: return resolve_ref(obj_array[value["CF$UID"]]) if isinstance(value, list): return [resolve_ref(item) for item in value] if isinstance(value, dict): return {k: resolve_ref(v) for k, v in value.items()} return value # 示例:获取你标注的UID为24的实际内容 print(resolve_ref({"CF$UID": 24})) # 批量导出CSV示例,你需要先定位到待导出的数据集对应的节点 # with open("export_result.csv", "w", encoding="utf-8", newline="") as csv_file: # writer = csv.writer(csv_file) # # 按需修改表头 # writer.writerow(["字段1", "字段2", "目标字符串值"]) # for data_node in 待导出的数据集列表: # resolved_node = resolve_ref(data_node) # writer.writerow([ # resolved_node["字段1"], # resolved_node["字段2"], # resolved_node["stringValue"] # ])
- 你之前通过修改数值定位到的改动位置,就是你需要批量导出的数据集的结构模板,拿到该结构的父节点路径后,替换示例中的
待导出的数据集列表即可自动导出所有数据到CSV。
注意事项
- 该方法同时支持XML格式和二进制格式的plist文件,无需提前做格式转换
- 如果遇到自定义类的归档内容,解引用后会保留类结构的字典,按需提取你需要的字段即可
内容的提问来源于stack exchange,提问作者MonkeyBolts
相关产品推荐
相关产品推荐

