iOS Plist文件如何体现与XML的相似性?
- 内容介绍
- 相关推荐
本文共计1031个文字,预计阅读时间需要5分钟。
iOS项目的Info.plist文件默认是二进制格式,而非纯文本的XML。很多人误以为修改XML后生效,这是错误的根源。Xcode中看到的可读内容,实际上是因为Xcode在编辑时自动将二进制格式转换为XML格式显示;保存时可能再次转换为二进制格式。如果使用Xcode外部工具(如VS Code)直接修改并保存,很容易出现问题。
- 用
plutil -s Info.plist可查看当前格式:输出xml1表示 XML,binary1表示二进制 - 强制转为 XML:
plutil -convert xml1 Info.plist;转回二进制:plutil -convert binary1 Info.plist - 二进制 plist 更紧凑、加载更快,系统运行时默认偏好二进制;XML 仅用于人工编辑和版本控制友好
XML 结构里 key 和 value 的类型必须显式声明
plist XML 不是自由格式的键值对,每个 <key> 后面必须紧跟一个带类型标签的 value,比如 <string>、<true/>、<integer>。漏掉类型或写错(比如把 <boolean>YES</boolean> 当作有效写法),会导致 CFPropertyListCreateFromXMLData 解析失败,App 启动直接 crash,错误日志里常出现 Could not parse property list data。
- 布尔值只能用
<true/>或<false/>,不能写<bool>1</bool>或<string>YES</string> - 数字优先用
<integer>(整数)或<real>(浮点),避免用<string>123</string>冒充数字 —— 某些 API(如CFBundleVersion校验)会严格检查类型 - 数组和字典必须用
<array>/<dict>包裹,不能靠缩进或换行暗示结构
Info.plist 中常见字段的类型陷阱
很多字段看似是字符串,实际有隐含类型约束。比如 UIBackgroundModes 是数组,但新手常写成字符串;NSLocationWhenInUseUsageDescription 看似普通字符串,但如果父级 <dict> 缺少对应 <key> 标签,整个 key 就会被忽略 —— 而且 Xcode 不报错,只静默失效。
-
CFBundleURLTypes必须是<array>,每个子项是<dict>,其中CFBundleTypeRole是<string>,CFBundleURLSchemes又得是嵌套<array>—— 少一层标签,URL Scheme 注册就失败 -
LSApplicationQueriesSchemes是字符串数组,但 iOS 9+ 要求必须声明,否则canOpenURL:返回NO,且控制台无提示 -
NSAppTransportSecurity是字典,但NSAllowsArbitraryLoads必须是<true/>或<false/>,写成<string>YES</string>会导致 ATS 配置不生效
在代码里读取 plist 时,别假设路径或编码永远可靠
用 NSDictionary(contentsOfFile:) 或 Bundle.main.path(forResource:ofType:) 加载自定义 plist 时,路径拼错、扩展名大小写不符(.PLIST ≠ .plist)、文件没加进 target 的 Copy Bundle Resources,都会让返回值为 nil —— 而且 Swift 里如果强制解包,直接 crash。
- 永远先检查路径是否存在:
Bundle.main.path(forResource: "Config", ofType: "plist") != nil - 用
NSDictionary(contentsOf:)替代contentsOfFile:,它会自动处理编码(XML plist 默认 UTF-8,但旧工具可能存为 UTF-16) - 自定义 plist 若含中文或特殊字符,确保文件保存为 UTF-8 without BOM;BOM 会导致解析失败,错误信息可能是
XML parser error: Invalid token
<true/> 标签,整个功能就哑火。本文共计1031个文字,预计阅读时间需要5分钟。
iOS项目的Info.plist文件默认是二进制格式,而非纯文本的XML。很多人误以为修改XML后生效,这是错误的根源。Xcode中看到的可读内容,实际上是因为Xcode在编辑时自动将二进制格式转换为XML格式显示;保存时可能再次转换为二进制格式。如果使用Xcode外部工具(如VS Code)直接修改并保存,很容易出现问题。
- 用
plutil -s Info.plist可查看当前格式:输出xml1表示 XML,binary1表示二进制 - 强制转为 XML:
plutil -convert xml1 Info.plist;转回二进制:plutil -convert binary1 Info.plist - 二进制 plist 更紧凑、加载更快,系统运行时默认偏好二进制;XML 仅用于人工编辑和版本控制友好
XML 结构里 key 和 value 的类型必须显式声明
plist XML 不是自由格式的键值对,每个 <key> 后面必须紧跟一个带类型标签的 value,比如 <string>、<true/>、<integer>。漏掉类型或写错(比如把 <boolean>YES</boolean> 当作有效写法),会导致 CFPropertyListCreateFromXMLData 解析失败,App 启动直接 crash,错误日志里常出现 Could not parse property list data。
- 布尔值只能用
<true/>或<false/>,不能写<bool>1</bool>或<string>YES</string> - 数字优先用
<integer>(整数)或<real>(浮点),避免用<string>123</string>冒充数字 —— 某些 API(如CFBundleVersion校验)会严格检查类型 - 数组和字典必须用
<array>/<dict>包裹,不能靠缩进或换行暗示结构
Info.plist 中常见字段的类型陷阱
很多字段看似是字符串,实际有隐含类型约束。比如 UIBackgroundModes 是数组,但新手常写成字符串;NSLocationWhenInUseUsageDescription 看似普通字符串,但如果父级 <dict> 缺少对应 <key> 标签,整个 key 就会被忽略 —— 而且 Xcode 不报错,只静默失效。
-
CFBundleURLTypes必须是<array>,每个子项是<dict>,其中CFBundleTypeRole是<string>,CFBundleURLSchemes又得是嵌套<array>—— 少一层标签,URL Scheme 注册就失败 -
LSApplicationQueriesSchemes是字符串数组,但 iOS 9+ 要求必须声明,否则canOpenURL:返回NO,且控制台无提示 -
NSAppTransportSecurity是字典,但NSAllowsArbitraryLoads必须是<true/>或<false/>,写成<string>YES</string>会导致 ATS 配置不生效
在代码里读取 plist 时,别假设路径或编码永远可靠
用 NSDictionary(contentsOfFile:) 或 Bundle.main.path(forResource:ofType:) 加载自定义 plist 时,路径拼错、扩展名大小写不符(.PLIST ≠ .plist)、文件没加进 target 的 Copy Bundle Resources,都会让返回值为 nil —— 而且 Swift 里如果强制解包,直接 crash。
- 永远先检查路径是否存在:
Bundle.main.path(forResource: "Config", ofType: "plist") != nil - 用
NSDictionary(contentsOf:)替代contentsOfFile:,它会自动处理编码(XML plist 默认 UTF-8,但旧工具可能存为 UTF-16) - 自定义 plist 若含中文或特殊字符,确保文件保存为 UTF-8 without BOM;BOM 会导致解析失败,错误信息可能是
XML parser error: Invalid token
<true/> 标签,整个功能就哑火。
