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;
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: usewithUnsafeMutableBytes<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
add a comment |
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: usewithUnsafeMutableBytes<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
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
add a comment |
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: usewithUnsafeMutableBytes<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
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: usewithUnsafeMutableBytes<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
swift
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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.
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 haveData
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 usewithUnsafeMutableBytes
orwithUnsafeBytes
.
– 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 allocatingData
myself, it doesn't help for the cases where I'm using aData
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 theData
values you get into arrays before passing them off to the API, e.gflutter_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 usewithUnsafeBytes
and callbindMemory
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
|
show 1 more comment
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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 haveData
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 usewithUnsafeMutableBytes
orwithUnsafeBytes
.
– 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 allocatingData
myself, it doesn't help for the cases where I'm using aData
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 theData
values you get into arrays before passing them off to the API, e.gflutter_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 usewithUnsafeBytes
and callbindMemory
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
|
show 1 more comment
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.
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 haveData
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 usewithUnsafeMutableBytes
orwithUnsafeBytes
.
– 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 allocatingData
myself, it doesn't help for the cases where I'm using aData
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 theData
values you get into arrays before passing them off to the API, e.gflutter_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 usewithUnsafeBytes
and callbindMemory
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
|
show 1 more comment
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.
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.
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 haveData
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 usewithUnsafeMutableBytes
orwithUnsafeBytes
.
– 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 allocatingData
myself, it doesn't help for the cases where I'm using aData
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 theData
values you get into arrays before passing them off to the API, e.gflutter_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 usewithUnsafeBytes
and callbindMemory
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
|
show 1 more comment
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 haveData
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 usewithUnsafeMutableBytes
orwithUnsafeBytes
.
– 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 allocatingData
myself, it doesn't help for the cases where I'm using aData
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 theData
values you get into arrays before passing them off to the API, e.gflutter_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 usewithUnsafeBytes
and callbindMemory
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
|
show 1 more comment
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.
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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