Errors when update code to avoid deprecation warnings withUnsafeMutableBytes in swift 5

前端 未结 1 939
走了就别回头了
走了就别回头了 2020-12-20 20:11

I\'ve updated to swift 5 and one of the dependencies I use won\'t compile in swift 5. I\'ve fixed it, but now I\'m getting 350+ deprecation warnings all over the file. They\

相关标签:
1条回答
  • 2020-12-20 20:45

    I wouldn't use Data here – Data represents an untyped collection of "raw" bytes, however crypto_generichash_keygen wants a mutable pointer to typed memory. The reason why the UnsafeMutablePointer<T> variant of withUnsafeMutableBytes was deprecated is that it's fundamentally the wrong abstraction to be providing on untyped memory.

    The simplest way to get a buffer of typed memory in Swift is with an Array:

    var k = [UInt8](repeating: 0, count: crypto_generichash_keybytes())
    flutter_sodium.crypto_generichash_keygen(&k)
    

    You can always turn the resulting buffer into a Data value afterwards by saying Data(k).

    Another option is to use an UnsafeMutableBufferPointer:

    let k = UnsafeMutableBufferPointer<UInt8>.allocate(capacity: crypto_generichash_keybytes())
    defer {
      k.deallocate()
    }
    flutter_sodium.crypto_generichash_keygen(k.baseAddress!)
    // Now use the buffer `k` – just make sure you finish using it before the end of
    // the scope when `deallocate()` gets called!
    

    Unlike Array, this avoids having to pre-fill the resulting buffer with zeros before being passed off to the C API, however this likely isn't of concern. But just like Array, you can turn such a buffer into a Data by just saying Data(k).


    For cases where you get handed a Data value from some external source and need to pass it off to an API as a typed pointer, the simplest and safest option is to just turn it into an array before passing it by saying Array(someData).

    For example:

    let args = call.arguments as! NSDictionary
    let server_pk = (args["server_pk"] as! FlutterStandardTypedData).data
    let server_sk = (args["server_sk"] as! FlutterStandardTypedData).data
    let client_pk = (args["client_pk"] as! FlutterStandardTypedData).data
    
    var rx = [UInt8](repeating: 0, count: flutter_sodium.crypto_kx_sessionkeybytes())
    var tx = [UInt8](repeating: 0, count: flutter_sodium.crypto_kx_sessionkeybytes())
    
    flutter_sodium.crypto_kx_server_session_keys(
      &rx, &tx, Array(server_pk), Array(server_sk), Array(client_pk)
    )
    

    You probably could use withUnsafeBytes and call bindMemory on the underlying pointer, but I would discourage it, as it changes the type of the underlying memory which could subtly impact the soundness of any other Swift code sharing that memory due to the fact that you're switching out the type from under it.

    0 讨论(0)
提交回复
热议问题