I have the following extension to convert UUIDs to base64 url safe strings and vise versa. I'm struggling with my base64UrlSafeString
not returning a utf8 string because the underlying data is an array of UInt8. At least I think that's the problem because the last line of decodeBase64UrlSafeString()
returns nil. Is there a safe way to convert the 16 bytes from the UUID into a Data
object with utf8 encoding?
let uuid = UUID(uuidString: "9823c260-4feb-11e9-990c-354fb53401ce")!
print(uuid.base64UrlSafeString) //mCPCYE_rEemZDDVPtTQBzg
print(UUID.decodeBase64UrlSafeString(uuid.base64UrlSafeString)) //nil
The UUID extension:
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 {
var result = Data()
result.append(uuid.0)
result.append(uuid.1)
result.append(uuid.2)
result.append(uuid.3)
result.append(uuid.4)
result.append(uuid.5)
result.append(uuid.6)
result.append(uuid.7)
result.append(uuid.8)
result.append(uuid.9)
result.append(uuid.10)
result.append(uuid.11)
result.append(uuid.12)
result.append(uuid.13)
result.append(uuid.14)
result.append(uuid.15)
return result
}
static func decodeBase64UrlSafeString(_ base_64_uuid: String ) -> String? {
var base_64_uuid = base_64_uuid
base_64_uuid = base_64_uuid.replacingOccurrences(of: "-", with: " ")
base_64_uuid = base_64_uuid.replacingOccurrences(of: "_", with: "/")
while base_64_uuid.count % 4 != 0 {
base_64_uuid = base_64_uuid.appending("=")
}
guard let data = Data(base64Encoded: base_64_uuid) else { return nil }
print("Got here") //code makes it here
return String(data: data, encoding: .utf8) //returns nil!
}
}
CodePudding user response:
The UUID data is not a valid utf8 encoded string. What you need is to convert the data to UUID and then return the uuidString:
static func decodeBase64UrlSafeString(_ base_64_uuid: String) -> String? {
var base_64_uuid = base_64_uuid
.replacingOccurrences(of: "-", with: " ")
.replacingOccurrences(of: "_", with: "/")
while base_64_uuid.count % 4 != 0 { base_64_uuid = "=" }
guard let data = Data(base64Encoded: base_64_uuid), data.count == 16 else { return nil }
let uuid = data.withUnsafeBytes { $0.load(as: UUID.self) }
return uuid.uuidString
}