Search code examples
swiftgrand-central-dispatchswift4

Convert Data to DispatchData in Swift 4


I am migrating a project to Swift 4 and I cannot figure out how I am supposed to use the new API:s to do this in Swift 4. The following code is the old Swift 3 way (from the middle of a function hence the guard):

let formattedString = "A string"
guard let stringData: Data = formattedString.data(using: .utf8) else { return }
let data: DispatchData = [UInt8](stringData).withUnsafeBufferPointer { (bufferPointer) in
    return DispatchData(bytes: bufferPointer)
}

Now it gives the following warning: init(bytes:)' is deprecated: Use init(bytes: UnsafeRawBufferPointer) instead

In order to do that you need to get access to a variable with the type UnsafeRawBufferPointer instead of UnsafeBufferPointer<UInt8>


Solution

  • Use withUnsafeBytes to get an UnsafeRawPointer to the data bytes, create an UnsafeRawBufferPointer from that pointer and the count, and pass it to the DispatchData constructor:

    let formattedString = "A string"
    let stringData = formattedString.data(using: .utf8)! // Cannot fail!
    
    let data = stringData.withUnsafeBytes {
        DispatchData(bytes: UnsafeRawBufferPointer(start: $0, count: stringData.count))
    }
    

    Alternatively, create an array from the Strings UTF-8 view and use withUnsafeBytes to get an UnsafeRawBufferPointer representing the arrays contiguous element storage:

    let formattedString = "A string"
    let data = Array(formattedString.utf8).withUnsafeBytes {
        DispatchData(bytes: $0)
    }