Skip to content

Instantly share code, notes, and snippets.

@dagronf
Last active April 29, 2024 21:56
Show Gist options
  • Select an option

  • Save dagronf/bb1d42c5d28a25499c2e1aab9f60f6c6 to your computer and use it in GitHub Desktop.

Select an option

Save dagronf/bb1d42c5d28a25499c2e1aab9f60f6c6 to your computer and use it in GitHub Desktop.
Swift UUID -> Data code extension
extension UUID {
/// Errors thrown
public enum LoadError: Error {
case invalidUUIDData
}
/// Returns the raw bytes of the UUID as a Data object.
///
/// Note that this method assumes a specific memory layout (the layout on the device calling the method)
/// and as such may not be portable to other systems.
public var uuidData: Data {
var tempUUID = self.uuid
return withUnsafePointer(to: &tempUUID) { rawUuidPtr in
let bytes = UnsafeRawPointer(rawUuidPtr).assumingMemoryBound(to: UInt8.self)
let capacity = MemoryLayout<uuid_t>.size
return Data(bytes: bytes, count: capacity)
}
}
/// Create a UUID object initialized with the bytes stored in the Data object
///
/// - Parameter uuidData: The data object containing the binary form of the uuid
/// - Returns: a UUID object initialized with the bytes stored in the Data object
/// - Throws: Throws LoadError.invalidUUIDData if there aren't enough bytes, or if a UUID could not be created
///
/// Note that this method assumes a specific memory layout (the layout on the device calling the method)
/// and as such may not be portable to other systems.
init(uuidData data: Data) throws {
guard data.count >= MemoryLayout<uuid_t>.size else {
throw LoadError.invalidUUIDData
}
let uuid: NSUUID = try data.withUnsafeBytes { rawBuffer in
guard let bytes = rawBuffer.baseAddress?.assumingMemoryBound(to: UInt8.self) else {
throw LoadError.invalidUUIDData
}
return NSUUID(uuidBytes: bytes)
}
self = uuid as UUID
}
}
func testUUIDToFromData() {
let uuid = UUID()
let UIDS = uuid.uuidString
let bytes = uuid.uuidData
if let uuid2 = try? UUID(uuidData: bytes) {
let UIDS2 = uuid2.uuidString
XCTAssertEqual(UIDS, UIDS2)
}
else {
XCTAssert(false, "Unable to load UUID from bytes")
}
}
@dagronf
Copy link
Copy Markdown
Author

dagronf commented Mar 22, 2019

If transferring uuids between different systems, it might be better to use the string form of the uuid for storage and/or transmission

@lbwanghr
Copy link
Copy Markdown

Thanks for sharing, however I got a warning when I used your code snippet.

The code snippet:

      var nsUUID: NSUUID?
      data.withUnsafeBytes { rawBytes in
         nsUUID = NSUUID(uuidBytes: rawBytes)
      }

The warning:

'withUnsafeBytes' is deprecated: use withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R instead

After some tries, I found the modification below would work.

      var nsUUID: NSUUID?
      data.withUnsafeBytes { rawBytes in
         nsUUID = NSUUID(uuidBytes: rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self))
      }

Hope this comment will help others.

@dagronf
Copy link
Copy Markdown
Author

dagronf commented Apr 29, 2024

Thanks @lbwanghr, I've updated the sample with your changes and cleaned the interface a bit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment