Errors when update code to avoid deprecation warnings withUnsafeMutableBytes in swift 5Issue using outputStream.write in Swift 5How to hash NSString with SHA1 in Swift?Swift 5.0: 'withUnsafeBytes' is deprecated: use `withUnsafeBytes<R>(…)'withUnsafeMutableBytes' is deprecated: use `withUnsafeMutableBytes<R>How do I call Objective-C code from Swift?Swift: #warning equivalentXcode 6.0.1 segmentation fault at compile time with Swift projectDelete a Core Data stack without using -lock methodstatic protocol extensions generates Illegal Instruction compiler errorXcode 8 / Swift 3: “Expression of type UIViewController? is unused” warningCoreData NSFetchRequest error NSInvalidArgumentException in Swift 3Abort Trap: 6 error in the new Swift 3.1/Xcode 8.3The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to convert from [CUnsignedChar] or Array<Uint8> to UnsafeMutablePointer<UInt8>?

How to determine car loan length as a function of how long I plan to keep a car

Why in most German places is the church the tallest building?

Where was Carl Sagan working on a plan to detonate a nuke on the Moon? Where was he applying when he leaked it?

What is the best type of paint to paint a shipping container?

Why did Khan ask Admiral James T. Kirk about Project Genesis?

Network helper class with retry logic on failure

How to find out the average duration of the peer-review process for a given journal?

Transposing from C to Cm?

'Us students' - Does this apposition need a comma?

How to respectfully refuse to assist co-workers with IT issues?

Improving Performance of an XY Monte Carlo

Why do banks “park” their money at the European Central Bank?

Who was president of the USA?

Algorithms vs LP or MIP

Is there any way to keep a player from killing an NPC?

Rent contract say that pets are not allowed. Possible repercussions if bringing the pet anyway?

Why does Windows store Wi-Fi passwords in a reversable format?

How to prevent clipped screen edges on my TV, HDMI-connected?

Duplicate instruments in unison in an orchestra

What should come first—characters or plot?

Does an atom recoil when photon radiate?

How do I prevent other wifi networks from showing up on my computer?

Are there any elected officials in the U.S. who are not legislators, judges, or constitutional officers?

Prove your innocence



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


Issue using outputStream.write in Swift 5How to hash NSString with SHA1 in Swift?Swift 5.0: 'withUnsafeBytes' is deprecated: use `withUnsafeBytes<R>(…)'withUnsafeMutableBytes' is deprecated: use `withUnsafeMutableBytes<R>How do I call Objective-C code from Swift?Swift: #warning equivalentXcode 6.0.1 segmentation fault at compile time with Swift projectDelete a Core Data stack without using -lock methodstatic protocol extensions generates Illegal Instruction compiler errorXcode 8 / Swift 3: “Expression of type UIViewController? is unused” warningCoreData NSFetchRequest error NSInvalidArgumentException in Swift 3Abort Trap: 6 error in the new Swift 3.1/Xcode 8.3The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to convert from [CUnsignedChar] or Array<Uint8> to UnsafeMutablePointer<UInt8>?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








5















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're all similar to this:




withUnsafeMutableBytes is deprecated: use withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R instead




And this is a snipit of the code (it's basically just calling a c library's functions):



var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes kPtr in
flutter_sodium.crypto_generichash_keygen(kPtr)



For reference, in the above crypto_generichash_keybytes() just returns a size_t and crypto_generichash_keygen's signature is void crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]);.



I figured out (as this answer states) that the way to get around this should be to call kPtr.baseAddress:



var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes kPtr in
flutter_sodium.crypto_generichash_keygen(kPtr.baseAddress)



as that should use the withUnsafeMutableBytes<ResultType> variant rather than the deprecated withUnsafeMutableBytes<ResultType, ContentType>. However, this instead results in the error




value of type 'UnsafeMutablePointer<_>' has no member 'baseAddress'.




If I explicitly specify the resultType and kPtr:



var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes (kPtr: UnsafeMutableRawBufferPointer) -> Void in
flutter_sodium.crypto_generichash_keygen(kPtr.baseAddress)



I instead get




UnsafeMutableRawBufferPointer' is not convertible to 'UnsafeMutablePointer<_>'.




Are there any swift experts out there that can help me figure out the right way to do this? I know the warnings are just warnings, but I prefer to have code that compiles with no warnings.



I took a look at Swift 5.0: 'withUnsafeBytes' is deprecated: use `withUnsafeBytes<R>(...) before posting this question and it doesn't help my situation as I'm not loading the pointer but rather using the data. Also, I've done exactly what the documentation tells me to but that still isn't helping.



EDIT: To be a bit more clear, some of the 350+ warnings were related to code where the Data is allocated in the code, however some of them are where I receive Data from an external source. That looks something like this:



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 = Data(count: flutter_sodium.crypto_kx_sessionkeybytes())
var tx = Data(count: flutter_sodium.crypto_kx_sessionkeybytes())
let ret = rx.withUnsafeMutableBytes rxPtr in
tx.withUnsafeMutableBytes txPtr in
server_pk.withUnsafeBytes server_pkPtr in
server_sk.withUnsafeBytes server_skPtr in
client_pk.withUnsafeBytes client_pkPtr in
flutter_sodium.crypto_kx_server_session_keys(rxPtr, txPtr, server_pkPtr, server_skPtr, client_pkPtr)







with the corresponding method call



SODIUM_EXPORT
int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
unsigned char tx[crypto_kx_SESSIONKEYBYTES],
const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])
__attribute__ ((warn_unused_result));


(and I know that the code is not really optimal swift, but when dealing with interoperability between dart and swift this is what the flutter team came up with for how to do it).



When I asked the question I was trying to distill it down to the simplest case but that case had a specific answer which differs to the overall problem I'm having.










share|improve this question





















  • 1





    Great that you asked this question with Swift 5 just being released. Made the transition easier for me.

    – Wyetro
    Mar 27 at 22:11

















5















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're all similar to this:




withUnsafeMutableBytes is deprecated: use withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R instead




And this is a snipit of the code (it's basically just calling a c library's functions):



var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes kPtr in
flutter_sodium.crypto_generichash_keygen(kPtr)



For reference, in the above crypto_generichash_keybytes() just returns a size_t and crypto_generichash_keygen's signature is void crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]);.



I figured out (as this answer states) that the way to get around this should be to call kPtr.baseAddress:



var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes kPtr in
flutter_sodium.crypto_generichash_keygen(kPtr.baseAddress)



as that should use the withUnsafeMutableBytes<ResultType> variant rather than the deprecated withUnsafeMutableBytes<ResultType, ContentType>. However, this instead results in the error




value of type 'UnsafeMutablePointer<_>' has no member 'baseAddress'.




If I explicitly specify the resultType and kPtr:



var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes (kPtr: UnsafeMutableRawBufferPointer) -> Void in
flutter_sodium.crypto_generichash_keygen(kPtr.baseAddress)



I instead get




UnsafeMutableRawBufferPointer' is not convertible to 'UnsafeMutablePointer<_>'.




Are there any swift experts out there that can help me figure out the right way to do this? I know the warnings are just warnings, but I prefer to have code that compiles with no warnings.



I took a look at Swift 5.0: 'withUnsafeBytes' is deprecated: use `withUnsafeBytes<R>(...) before posting this question and it doesn't help my situation as I'm not loading the pointer but rather using the data. Also, I've done exactly what the documentation tells me to but that still isn't helping.



EDIT: To be a bit more clear, some of the 350+ warnings were related to code where the Data is allocated in the code, however some of them are where I receive Data from an external source. That looks something like this:



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 = Data(count: flutter_sodium.crypto_kx_sessionkeybytes())
var tx = Data(count: flutter_sodium.crypto_kx_sessionkeybytes())
let ret = rx.withUnsafeMutableBytes rxPtr in
tx.withUnsafeMutableBytes txPtr in
server_pk.withUnsafeBytes server_pkPtr in
server_sk.withUnsafeBytes server_skPtr in
client_pk.withUnsafeBytes client_pkPtr in
flutter_sodium.crypto_kx_server_session_keys(rxPtr, txPtr, server_pkPtr, server_skPtr, client_pkPtr)







with the corresponding method call



SODIUM_EXPORT
int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
unsigned char tx[crypto_kx_SESSIONKEYBYTES],
const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])
__attribute__ ((warn_unused_result));


(and I know that the code is not really optimal swift, but when dealing with interoperability between dart and swift this is what the flutter team came up with for how to do it).



When I asked the question I was trying to distill it down to the simplest case but that case had a specific answer which differs to the overall problem I'm having.










share|improve this question





















  • 1





    Great that you asked this question with Swift 5 just being released. Made the transition easier for me.

    – Wyetro
    Mar 27 at 22:11













5












5








5








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're all similar to this:




withUnsafeMutableBytes is deprecated: use withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R instead




And this is a snipit of the code (it's basically just calling a c library's functions):



var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes kPtr in
flutter_sodium.crypto_generichash_keygen(kPtr)



For reference, in the above crypto_generichash_keybytes() just returns a size_t and crypto_generichash_keygen's signature is void crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]);.



I figured out (as this answer states) that the way to get around this should be to call kPtr.baseAddress:



var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes kPtr in
flutter_sodium.crypto_generichash_keygen(kPtr.baseAddress)



as that should use the withUnsafeMutableBytes<ResultType> variant rather than the deprecated withUnsafeMutableBytes<ResultType, ContentType>. However, this instead results in the error




value of type 'UnsafeMutablePointer<_>' has no member 'baseAddress'.




If I explicitly specify the resultType and kPtr:



var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes (kPtr: UnsafeMutableRawBufferPointer) -> Void in
flutter_sodium.crypto_generichash_keygen(kPtr.baseAddress)



I instead get




UnsafeMutableRawBufferPointer' is not convertible to 'UnsafeMutablePointer<_>'.




Are there any swift experts out there that can help me figure out the right way to do this? I know the warnings are just warnings, but I prefer to have code that compiles with no warnings.



I took a look at Swift 5.0: 'withUnsafeBytes' is deprecated: use `withUnsafeBytes<R>(...) before posting this question and it doesn't help my situation as I'm not loading the pointer but rather using the data. Also, I've done exactly what the documentation tells me to but that still isn't helping.



EDIT: To be a bit more clear, some of the 350+ warnings were related to code where the Data is allocated in the code, however some of them are where I receive Data from an external source. That looks something like this:



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 = Data(count: flutter_sodium.crypto_kx_sessionkeybytes())
var tx = Data(count: flutter_sodium.crypto_kx_sessionkeybytes())
let ret = rx.withUnsafeMutableBytes rxPtr in
tx.withUnsafeMutableBytes txPtr in
server_pk.withUnsafeBytes server_pkPtr in
server_sk.withUnsafeBytes server_skPtr in
client_pk.withUnsafeBytes client_pkPtr in
flutter_sodium.crypto_kx_server_session_keys(rxPtr, txPtr, server_pkPtr, server_skPtr, client_pkPtr)







with the corresponding method call



SODIUM_EXPORT
int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
unsigned char tx[crypto_kx_SESSIONKEYBYTES],
const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])
__attribute__ ((warn_unused_result));


(and I know that the code is not really optimal swift, but when dealing with interoperability between dart and swift this is what the flutter team came up with for how to do it).



When I asked the question I was trying to distill it down to the simplest case but that case had a specific answer which differs to the overall problem I'm having.










share|improve this question
















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're all similar to this:




withUnsafeMutableBytes is deprecated: use withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R instead




And this is a snipit of the code (it's basically just calling a c library's functions):



var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes kPtr in
flutter_sodium.crypto_generichash_keygen(kPtr)



For reference, in the above crypto_generichash_keybytes() just returns a size_t and crypto_generichash_keygen's signature is void crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]);.



I figured out (as this answer states) that the way to get around this should be to call kPtr.baseAddress:



var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes kPtr in
flutter_sodium.crypto_generichash_keygen(kPtr.baseAddress)



as that should use the withUnsafeMutableBytes<ResultType> variant rather than the deprecated withUnsafeMutableBytes<ResultType, ContentType>. However, this instead results in the error




value of type 'UnsafeMutablePointer<_>' has no member 'baseAddress'.




If I explicitly specify the resultType and kPtr:



var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes (kPtr: UnsafeMutableRawBufferPointer) -> Void in
flutter_sodium.crypto_generichash_keygen(kPtr.baseAddress)



I instead get




UnsafeMutableRawBufferPointer' is not convertible to 'UnsafeMutablePointer<_>'.




Are there any swift experts out there that can help me figure out the right way to do this? I know the warnings are just warnings, but I prefer to have code that compiles with no warnings.



I took a look at Swift 5.0: 'withUnsafeBytes' is deprecated: use `withUnsafeBytes<R>(...) before posting this question and it doesn't help my situation as I'm not loading the pointer but rather using the data. Also, I've done exactly what the documentation tells me to but that still isn't helping.



EDIT: To be a bit more clear, some of the 350+ warnings were related to code where the Data is allocated in the code, however some of them are where I receive Data from an external source. That looks something like this:



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 = Data(count: flutter_sodium.crypto_kx_sessionkeybytes())
var tx = Data(count: flutter_sodium.crypto_kx_sessionkeybytes())
let ret = rx.withUnsafeMutableBytes rxPtr in
tx.withUnsafeMutableBytes txPtr in
server_pk.withUnsafeBytes server_pkPtr in
server_sk.withUnsafeBytes server_skPtr in
client_pk.withUnsafeBytes client_pkPtr in
flutter_sodium.crypto_kx_server_session_keys(rxPtr, txPtr, server_pkPtr, server_skPtr, client_pkPtr)







with the corresponding method call



SODIUM_EXPORT
int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
unsigned char tx[crypto_kx_SESSIONKEYBYTES],
const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])
__attribute__ ((warn_unused_result));


(and I know that the code is not really optimal swift, but when dealing with interoperability between dart and swift this is what the flutter team came up with for how to do it).



When I asked the question I was trying to distill it down to the simplest case but that case had a specific answer which differs to the overall problem I'm having.







swift






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 27 at 19:20







rmtmckenzie

















asked Mar 27 at 18:30









rmtmckenziermtmckenzie

10.9k30 silver badges46 bronze badges




10.9k30 silver badges46 bronze badges










  • 1





    Great that you asked this question with Swift 5 just being released. Made the transition easier for me.

    – Wyetro
    Mar 27 at 22:11












  • 1





    Great that you asked this question with Swift 5 just being released. Made the transition easier for me.

    – Wyetro
    Mar 27 at 22:11







1




1





Great that you asked this question with Swift 5 just being released. Made the transition easier for me.

– Wyetro
Mar 27 at 22:11





Great that you asked this question with Swift 5 just being released. Made the transition easier for me.

– Wyetro
Mar 27 at 22:11












1 Answer
1






active

oldest

votes


















6















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.






share|improve this answer



























  • Ah, that's interesting. I can see how using an array would be a more sensible option in this particular case. And since Data currently zeros the buffer anyways I don't think that's a performance concern for Array either - and I like the Array way of doing it better than fiddling around with UnsafeMutableBufferPointers. I always figure that if it has 'Unsafe' in the name it should be avoided.

    – rmtmckenzie
    Mar 27 at 19:10











  • However, I'm also dealing with the case where I have Data objects passed directly to me (from Flutter's abstraction layer which receives the raw data from Dart code) - I should have been more clear about that in the question. In that case I don't really have the option to start with an array and am back to trying to use withUnsafeMutableBytes or withUnsafeBytes.

    – rmtmckenzie
    Mar 27 at 19:11











  • I've updated my question with a bit more detail; as I said in the update I was trying to distill the problem down to the simplest case but and while I think your answer is 100% correct for the cases where I'm allocating Data myself, it doesn't help for the cases where I'm using a Data that I get from elsewhere.

    – rmtmckenzie
    Mar 27 at 19:21











  • @rmtmckenzie Honestly the easiest way to deal with that would probably be to just convert the Data values you get into arrays before passing them off to the API, e.g flutter_sodium.crypto_kx_server_session_keys(rxPtr, Array(tx), Array(server_pk), Array(server_sk), Array(client_pk)). That also nicely eliminates the pyramid of doom.

    – Hamish
    Mar 27 at 21:26











  • 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 other code sharing that memory by switching out the type from under it.

    – Hamish
    Mar 27 at 21:26










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55384250%2ferrors-when-update-code-to-avoid-deprecation-warnings-withunsafemutablebytes-in%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









6















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.






share|improve this answer



























  • Ah, that's interesting. I can see how using an array would be a more sensible option in this particular case. And since Data currently zeros the buffer anyways I don't think that's a performance concern for Array either - and I like the Array way of doing it better than fiddling around with UnsafeMutableBufferPointers. I always figure that if it has 'Unsafe' in the name it should be avoided.

    – rmtmckenzie
    Mar 27 at 19:10











  • However, I'm also dealing with the case where I have Data objects passed directly to me (from Flutter's abstraction layer which receives the raw data from Dart code) - I should have been more clear about that in the question. In that case I don't really have the option to start with an array and am back to trying to use withUnsafeMutableBytes or withUnsafeBytes.

    – rmtmckenzie
    Mar 27 at 19:11











  • I've updated my question with a bit more detail; as I said in the update I was trying to distill the problem down to the simplest case but and while I think your answer is 100% correct for the cases where I'm allocating Data myself, it doesn't help for the cases where I'm using a Data that I get from elsewhere.

    – rmtmckenzie
    Mar 27 at 19:21











  • @rmtmckenzie Honestly the easiest way to deal with that would probably be to just convert the Data values you get into arrays before passing them off to the API, e.g flutter_sodium.crypto_kx_server_session_keys(rxPtr, Array(tx), Array(server_pk), Array(server_sk), Array(client_pk)). That also nicely eliminates the pyramid of doom.

    – Hamish
    Mar 27 at 21:26











  • 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 other code sharing that memory by switching out the type from under it.

    – Hamish
    Mar 27 at 21:26















6















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.






share|improve this answer



























  • Ah, that's interesting. I can see how using an array would be a more sensible option in this particular case. And since Data currently zeros the buffer anyways I don't think that's a performance concern for Array either - and I like the Array way of doing it better than fiddling around with UnsafeMutableBufferPointers. I always figure that if it has 'Unsafe' in the name it should be avoided.

    – rmtmckenzie
    Mar 27 at 19:10











  • However, I'm also dealing with the case where I have Data objects passed directly to me (from Flutter's abstraction layer which receives the raw data from Dart code) - I should have been more clear about that in the question. In that case I don't really have the option to start with an array and am back to trying to use withUnsafeMutableBytes or withUnsafeBytes.

    – rmtmckenzie
    Mar 27 at 19:11











  • I've updated my question with a bit more detail; as I said in the update I was trying to distill the problem down to the simplest case but and while I think your answer is 100% correct for the cases where I'm allocating Data myself, it doesn't help for the cases where I'm using a Data that I get from elsewhere.

    – rmtmckenzie
    Mar 27 at 19:21











  • @rmtmckenzie Honestly the easiest way to deal with that would probably be to just convert the Data values you get into arrays before passing them off to the API, e.g flutter_sodium.crypto_kx_server_session_keys(rxPtr, Array(tx), Array(server_pk), Array(server_sk), Array(client_pk)). That also nicely eliminates the pyramid of doom.

    – Hamish
    Mar 27 at 21:26











  • 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 other code sharing that memory by switching out the type from under it.

    – Hamish
    Mar 27 at 21:26













6














6










6









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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 27 at 22:35

























answered Mar 27 at 18:56









HamishHamish

53.8k9 gold badges126 silver badges191 bronze badges




53.8k9 gold badges126 silver badges191 bronze badges















  • Ah, that's interesting. I can see how using an array would be a more sensible option in this particular case. And since Data currently zeros the buffer anyways I don't think that's a performance concern for Array either - and I like the Array way of doing it better than fiddling around with UnsafeMutableBufferPointers. I always figure that if it has 'Unsafe' in the name it should be avoided.

    – rmtmckenzie
    Mar 27 at 19:10











  • However, I'm also dealing with the case where I have Data objects passed directly to me (from Flutter's abstraction layer which receives the raw data from Dart code) - I should have been more clear about that in the question. In that case I don't really have the option to start with an array and am back to trying to use withUnsafeMutableBytes or withUnsafeBytes.

    – rmtmckenzie
    Mar 27 at 19:11











  • I've updated my question with a bit more detail; as I said in the update I was trying to distill the problem down to the simplest case but and while I think your answer is 100% correct for the cases where I'm allocating Data myself, it doesn't help for the cases where I'm using a Data that I get from elsewhere.

    – rmtmckenzie
    Mar 27 at 19:21











  • @rmtmckenzie Honestly the easiest way to deal with that would probably be to just convert the Data values you get into arrays before passing them off to the API, e.g flutter_sodium.crypto_kx_server_session_keys(rxPtr, Array(tx), Array(server_pk), Array(server_sk), Array(client_pk)). That also nicely eliminates the pyramid of doom.

    – Hamish
    Mar 27 at 21:26











  • 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 other code sharing that memory by switching out the type from under it.

    – Hamish
    Mar 27 at 21:26

















  • Ah, that's interesting. I can see how using an array would be a more sensible option in this particular case. And since Data currently zeros the buffer anyways I don't think that's a performance concern for Array either - and I like the Array way of doing it better than fiddling around with UnsafeMutableBufferPointers. I always figure that if it has 'Unsafe' in the name it should be avoided.

    – rmtmckenzie
    Mar 27 at 19:10











  • However, I'm also dealing with the case where I have Data objects passed directly to me (from Flutter's abstraction layer which receives the raw data from Dart code) - I should have been more clear about that in the question. In that case I don't really have the option to start with an array and am back to trying to use withUnsafeMutableBytes or withUnsafeBytes.

    – rmtmckenzie
    Mar 27 at 19:11











  • I've updated my question with a bit more detail; as I said in the update I was trying to distill the problem down to the simplest case but and while I think your answer is 100% correct for the cases where I'm allocating Data myself, it doesn't help for the cases where I'm using a Data that I get from elsewhere.

    – rmtmckenzie
    Mar 27 at 19:21











  • @rmtmckenzie Honestly the easiest way to deal with that would probably be to just convert the Data values you get into arrays before passing them off to the API, e.g flutter_sodium.crypto_kx_server_session_keys(rxPtr, Array(tx), Array(server_pk), Array(server_sk), Array(client_pk)). That also nicely eliminates the pyramid of doom.

    – Hamish
    Mar 27 at 21:26











  • 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 other code sharing that memory by switching out the type from under it.

    – Hamish
    Mar 27 at 21:26
















Ah, that's interesting. I can see how using an array would be a more sensible option in this particular case. And since Data currently zeros the buffer anyways I don't think that's a performance concern for Array either - and I like the Array way of doing it better than fiddling around with UnsafeMutableBufferPointers. I always figure that if it has 'Unsafe' in the name it should be avoided.

– rmtmckenzie
Mar 27 at 19:10





Ah, that's interesting. I can see how using an array would be a more sensible option in this particular case. And since Data currently zeros the buffer anyways I don't think that's a performance concern for Array either - and I like the Array way of doing it better than fiddling around with UnsafeMutableBufferPointers. I always figure that if it has 'Unsafe' in the name it should be avoided.

– rmtmckenzie
Mar 27 at 19:10













However, I'm also dealing with the case where I have Data objects passed directly to me (from Flutter's abstraction layer which receives the raw data from Dart code) - I should have been more clear about that in the question. In that case I don't really have the option to start with an array and am back to trying to use withUnsafeMutableBytes or withUnsafeBytes.

– rmtmckenzie
Mar 27 at 19:11





However, I'm also dealing with the case where I have Data objects passed directly to me (from Flutter's abstraction layer which receives the raw data from Dart code) - I should have been more clear about that in the question. In that case I don't really have the option to start with an array and am back to trying to use withUnsafeMutableBytes or withUnsafeBytes.

– rmtmckenzie
Mar 27 at 19:11













I've updated my question with a bit more detail; as I said in the update I was trying to distill the problem down to the simplest case but and while I think your answer is 100% correct for the cases where I'm allocating Data myself, it doesn't help for the cases where I'm using a Data that I get from elsewhere.

– rmtmckenzie
Mar 27 at 19:21





I've updated my question with a bit more detail; as I said in the update I was trying to distill the problem down to the simplest case but and while I think your answer is 100% correct for the cases where I'm allocating Data myself, it doesn't help for the cases where I'm using a Data that I get from elsewhere.

– rmtmckenzie
Mar 27 at 19:21













@rmtmckenzie Honestly the easiest way to deal with that would probably be to just convert the Data values you get into arrays before passing them off to the API, e.g flutter_sodium.crypto_kx_server_session_keys(rxPtr, Array(tx), Array(server_pk), Array(server_sk), Array(client_pk)). That also nicely eliminates the pyramid of doom.

– Hamish
Mar 27 at 21:26





@rmtmckenzie Honestly the easiest way to deal with that would probably be to just convert the Data values you get into arrays before passing them off to the API, e.g flutter_sodium.crypto_kx_server_session_keys(rxPtr, Array(tx), Array(server_pk), Array(server_sk), Array(client_pk)). That also nicely eliminates the pyramid of doom.

– Hamish
Mar 27 at 21:26













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 other code sharing that memory by switching out the type from under it.

– Hamish
Mar 27 at 21:26





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 other code sharing that memory by switching out the type from under it.

– Hamish
Mar 27 at 21:26








Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.







Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55384250%2ferrors-when-update-code-to-avoid-deprecation-warnings-withunsafemutablebytes-in%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript