我已经更新到 swift 5,我使用的依赖项之一无法在 swift 5 中编译。我已经修复了它,但现在我在整个文件中收到了 350 多个弃用警告。它们都类似于:
withUnsafeMutableBytes
已弃用:使用withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R
instead
这是代码片段(它基本上只是调用 C 库函数):
var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes { kPtr in
flutter_sodium.crypto_generichash_keygen(kPtr)
}
作为参考,上面的 crypto_generichash_keybytes() 仅返回 size_t 和crypto_generichash_keygen
的签名是void crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]);
.
我想通了(如这个答案 https://stackoverflow.com/questions/25761344/how-to-hash-nsstring-with-sha1-in-swift/25762128#25762128指出)解决这个问题的方法应该是调用 kPtr.baseAddress:
var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes { kPtr in
flutter_sodium.crypto_generichash_keygen(kPtr.baseAddress)
}
因为应该使用withUnsafeMutableBytes<ResultType>
变体而不是已弃用的withUnsafeMutableBytes<ResultType, ContentType>
。但是,这会导致错误
类型“UnsafeMutablePointer<_>”的值没有成员“baseAddress”。
如果我明确指定 resultType 和 kPtr:
var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes { (kPtr: UnsafeMutableRawBufferPointer) -> Void in
flutter_sodium.crypto_generichash_keygen(kPtr.baseAddress)
}
我反而得到
UnsafeMutableRawBufferPointer' 不能转换为 'UnsafeMutablePointer<_>'。
有没有快速的专家可以帮助我找出正确的方法来做到这一点?我知道警告只是警告,但我更喜欢编译时没有警告的代码。
我看了一下Swift 5.0:'withUnsafeBytes' 已弃用:使用 `withUnsafeBytes(...) https://stackoverflow.com/questions/55378409/swift-5-0-withunsafebytes-is-deprecated-use-withunsafebytesr在发布这个问题之前,它对我的情况没有帮助,因为我没有加载指针而是使用数据。另外,我已经完全按照文档的要求进行操作,但这仍然没有帮助。
编辑:更清楚一点,350 多个警告中的一些与以下代码相关:Data
是在代码中分配的,但是其中一些是我收到的Data
来自外部来源。看起来像这样:
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)
}
}
}
}
}
并调用相应的方法
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));
(我知道代码并不是真正最佳的 swift,但是在处理 dart 和 swift 之间的互操作性时,这就是 flutter 团队提出的解决方法)。
当我问这个问题时,我试图将其简化为最简单的情况,但该情况有一个特定的答案,与我遇到的总体问题不同。