Get Data from UUID in Swift 3

The uuid property of UUID is a C array with is imported to Swift as a tuple. Using the fact that Swift preserves the memory layout of imported C structures, you can pass a pointer to the tuple to the Data(bytes:, count:) constructor:

if let vendorIdentifier = UIDevice.current.identifierForVendor {
    var uuid = vendorIdentifier.uuid
    let data = withUnsafePointer(to: &uuid) {
        Data(bytes: $0, count: MemoryLayout.size(ofValue: uuid))
    }

    // ...
}

As of Swift 4.2 (Xcode 10) your don't need to make a mutable copy first:

if let vendorIdentifier = UIDevice.current.identifierForVendor {
    let data = withUnsafePointer(to: vendorIdentifier.uuid) {
        Data(bytes: $0, count: MemoryLayout.size(ofValue: vendorIdentifier.uuid))
    }

    // ...
}

This extension I made seems to work great without using reflection, nor pointers. It depends on the fact that UUID in Swift is represented as a tuple of 16 UInt8s which can simply be unwrapped like so:

extension UUID{
    public func asUInt8Array() -> [UInt8]{
        let (u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15,u16) = self.uuid
        return [u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15,u16]
    }
    public func asData() -> Data{
        return Data(self.asUInt8Array())
    }
}

Here's one possible way. Note that identifierForVendor returns UUID in Swift 3. UUID has a uuid property which gives you a uuid_t. uuid_t is a tuple of 16 UInt8 values.

So the trick is converting the tuple of bytes into an array of bytes. Then it's trivial to create the Data from the array.

if let vendorIdentifier = UIDevice.current.identifierForVendor {
    let uuid = vendorIdentifier.uuid // gives a uuid_t
    let uuidBytes = Mirror(reflecting: uuid).children.map({$0.1 as! UInt8}) // converts the tuple into an array
    let vendorData = Data(bytes: uuidBytes)
}

If anyone knows a better way to convert a tuple of UInt8 into an array of UInt8, please speak up.