解包可选值时遇NIL致致命错误,视频元数据日期提取求助
问题排查与修复方案
核心错误原因
你的DateFormatter设置的dateFormat与实际获取到的日期字符串格式完全不匹配:
- 你设置的格式是
"yyyy:MM:dd HH:mm:ss" - 实际日期字符串是
"2024-02-13T13:22:30+0100"(ISO 8601带时区偏移格式)
这导致dF.date(from: dateCreate)返回nil,后续强制解包!触发致命错误。
修复步骤与优化代码
1. 匹配正确的日期格式
可以直接使用ISO8601DateFormatter来解析这种标准格式,或者手动设置对应的dateFormat:
- 手动格式:
"yyyy-MM-dd'T'HH:mm:ssZ" - 推荐用
ISO8601DateFormatter,它能自动处理不同变体的ISO格式
2. 消除强制解包风险
把所有!替换为安全的可选绑定,避免意外崩溃。
3. 安全拼接文件路径
使用URL.appendingPathComponent(_:)代替字符串拼接,避免路径分隔符错误。
修复后的完整代码:
func getVideoMetadataDate(srcPath: String, itemSrc: String) async -> Date { // 初始化默认日期 let defaultDateString = "1975-01-01T00:00:00Z" let isoFormatter = ISO8601DateFormatter() guard let defaultDate = isoFormatter.date(from: defaultDateString) else { return Date(timeIntervalSince1970: 0) } // 安全构建文件URL guard let baseURL = URL(fileURLWithPath: srcPath) else { return defaultDate } let itemURL = baseURL.appendingPathComponent(itemSrc) let asset = AVAsset(url: itemURL) do { for format in try await asset.load(.availableMetadataFormats) { let metadata = try await asset.loadMetadata(for: format) let dateItems = AVMetadataItem.metadataItems(from: metadata, filteredByIdentifier: .commonIdentifierCreationDate) guard let dateItem = dateItems.first, let dateString = dateItem.value as? String, let creationDate = isoFormatter.date(from: dateString) else { continue } return creationDate } } catch { print("读取元数据失败:\(error)") } return defaultDate }
代码说明
- 用
ISO8601DateFormatter直接解析标准格式,无需手动写复杂的dateFormat - 所有可选值都用
guard let做安全绑定,彻底消除强制解包崩溃风险 - 用
URL.appendingPathComponent构建文件路径,适配不同系统的路径规则 - 遍历所有元数据格式时,若当前格式找不到有效日期,会继续尝试下一个格式,而不是直接返回默认值
内容的提问来源于stack exchange,提问作者CasyJones
相关产品推荐
相关产品推荐

