我在代码中有一行被弃用了,在XCode中有什么建议要替换它,但我无法理解差异,这些是我的三行有效:
let path = NSBundle.mainBundle().pathForResource("example", ofType: ".p12")
let pkcs12Data = NSData.dataWithContentsOfMappedFile(path!)
let cf: CFDataRef = pkcs12Data as! CFDataRef
现在根据警告和建议我将我的代码更改为:
let path = NSBundle.mainBundle().pathForResource("example", ofType: ".p12")
let pkcs12Data = NSData(contentsOfFile: path!)
let cf: CFDataRef = pkcs12Data as! CFDataRef
这给了我一个错误:
EXC_BAD_INSTRUCTION (CODE=EXC_I386_INVOP SUBCODE=0x0)
答案 0 :(得分:10)
更安全的版本:
guard
let url = NSBundle.mainBundle().URLForResource("example", withExtension: ".p12"),
let data = NSData(contentsOfURL: url)
else { // Do something because you couldn't get the file or convert it to NSData }
let dataPtr = CFDataCreate(kCFAllocatorDefault, UnsafePointer<UInt8>(data.bytes), data.length)
注意,使用基于文件的URL而不是字符串路径。
在决定调用哪些例程时,选择允许您使用NSURL对象指定路径的路径,而不是使用字符串指定路径的路径。大多数基于URL的例程都是在OS X v10.6及更高版本中引入的,并且从一开始就设计为利用Grand Central Dispatch等技术。这使您的代码在多核计算机上立即获得优势,同时不需要您做太多工作。
答案 1 :(得分:4)
@ Abizern的答案是有效的,但使用CFDataCreateWithBytesNoCopy
代替CFDataCreate
更有效。
答案 2 :(得分:3)
然而,在Swift 4中,你应该这样做:
当两个选项放在同一个NSData
子句中时,Xcode 9.2似乎会自动将Data
视为guard-let
。
我必须将两个选项放在单独的guard-let
子句中,如下所示:
// guard let url = Bundle.main.url(forResource: "example", withExtension: ".p12"),
// let data = NSData(contentsOf: url) else {
// return
// }
guard let url = Bundle.main.url(forResource: "example", withExtension: ".p12") else {
return
}
guard let data = NSData(contentsOf: url) else {
return
}
let bytes = data.bytes.assumingMemoryBound(to: UInt8.self)
let cfData = CFDataCreate(kCFAllocatorDefault, bytes, data.length) // CFData object you want