Working with init that takes a 32 element tuple?

I'm busy working with the Authorization Services APIs and came across an initializer for the type AuthorizationExternalForm that takes a 32 element tuple of UInt8s.


init(bytes: (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8))


Ref here: https://developer.apple.com/documentation/security/authorizationexternalform/1396798-init


Is there a shortcut to converting the contents of Data to that without explicitly referencing each element in a byte array?

Accepted Reply

I recommend that you wrap this up in a custom initialiser. Here’s the code I use:

extension AuthorizationExternalForm {

    init?(data: Data) {
        self.init()
        let bytesCount = MemoryLayout.size(ofValue: self.bytes)
        guard data.count == bytesCount else {
            return nil
        }
        data.withUnsafeBytes { src in
            withUnsafeMutablePointer(to: &self.bytes) { dst in
                _ = memcpy(dst, src.baseAddress!, bytesCount)
            }
        }
    }
}

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

The 32-element tuple is the result of importing fixed size C-array type `char[32]` into Swift.


You can write something like this:

typealias CChar32 = (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)

//Prepare a Data of 32-byte.
let data = Data([0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,
                 0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,
                 0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02,
                 0x01,0x02,0x01,0x02,0x01,0x02,0x01,0x02])
let dataAsCChar32 = data.withUnsafeBytes {rawBP in
    rawBP.bindMemory(to: CChar32.self)[0]
}
var extAuth = AuthorizationExternalForm(bytes: dataAsCChar32)

Thanks very much for explaining that to me. Now I know why it's like that, and thanks for the example code.

I recommend that you wrap this up in a custom initialiser. Here’s the code I use:

extension AuthorizationExternalForm {

    init?(data: Data) {
        self.init()
        let bytesCount = MemoryLayout.size(ofValue: self.bytes)
        guard data.count == bytesCount else {
            return nil
        }
        data.withUnsafeBytes { src in
            withUnsafeMutablePointer(to: &self.bytes) { dst in
                _ = memcpy(dst, src.baseAddress!, bytesCount)
            }
        }
    }
}

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"