Swift中UUID与URL安全Base64互转时解码返回nil的解决办法
问题原因
- 你调用
String(data: data, encoding: .utf8)返回nil的核心原因是:解码得到的16字节是UUID的原始二进制数据,不属于有效的UTF8编码序列,解码失败属于正常情况。 - UUID的16字节是随机二进制值,本身无法安全转换为UTF8编码的字符串,你实际需要的是将二进制数据还原为UUID结构体,再按需输出为标准格式的UUID字符串。
修正后的完整UUID扩展
extension UUID { var base64UrlSafeString: String { var result = self.data.base64EncodedString() result = result.replacingOccurrences(of: "+", with: "-") result = result.replacingOccurrences(of: "/", with: "_") result = result.replacingOccurrences(of: "=", with: "") return result } var data: Data { // 简化写法,无需手动拼接16个字节 withUnsafeBytes(of: uuid) { Data($0) } } // 解码返回UUID实例 static func decodeBase64UrlSafeString(_ base64UrlSafe: String) -> UUID? { var base64 = base64UrlSafe .replacingOccurrences(of: "-", with: "+") .replacingOccurrences(of: "_", with: "/") // 补全Base64所需的padding let paddingLength = 4 - base64.count % 4 if paddingLength < 4 { base64.append(contentsOf: repeatElement("=", count: paddingLength)) } // 校验解码后数据长度必须为16字节,符合UUID长度要求 guard let data = Data(base64Encoded: base64), data.count == 16 else { return nil } let rawUuid = data.withUnsafeBytes { $0.load(as: uuid_t.self) } return UUID(uuid: rawUuid) } // 如果需要直接返回标准UUID字符串,可新增此方法 static func decodeBase64UrlSafeToUuidString(_ base64UrlSafe: String) -> String? { decodeBase64UrlSafeString(base64UrlSafe)?.uuidString } }
测试验证代码
let uuid = UUID(uuidString: "9823c260-4feb-11e9-990c-354fb53401ce")! print(uuid.base64UrlSafeString) // 输出:mCPCYE_rEemZDDVPtTQBzg print(UUID.decodeBase64UrlSafeToUuidString(uuid.base64UrlSafeString) ?? "解码失败") // 输出:9823C260-4FEB-11E9-990C-354FB53401CE,和原始UUID一致
内容的提问来源于stack exchange,提问作者Kacy
相关产品推荐
相关产品推荐

