将NSData转换为!swift 2.0中的CFDataRef

Jak*_*Zak 4 casting nsdata cfdata ios swift2

我在代码中有一行被弃用了,在XCode中有什么建议要替换它,但我无法理解差异,这些是我的三行有效:

let path = NSBundle.mainBundle().pathForResource("example", ofType: ".p12")
let pkcs12Data = NSData.dataWithContentsOfMappedFile(path!)
let cf: CFDataRef = pkcs12Data as! CFDataRef
Run Code Online (Sandbox Code Playgroud)

现在根据警告和建议,我将我的代码更改为:

let path = NSBundle.mainBundle().pathForResource("example", ofType: ".p12")
let pkcs12Data = NSData(contentsOfFile: path!)
let cf: CFDataRef = pkcs12Data as! CFDataRef
Run Code Online (Sandbox Code Playgroud)

这给了我一个错误:

EXC_BAD_INSTRUCTION (CODE=EXC_I386_INVOP SUBCODE=0x0)
Run Code Online (Sandbox Code Playgroud)

Abi*_*ern 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)
Run Code Online (Sandbox Code Playgroud)

请注意,使用基于文件的URL而不是字符串路径.

在决定调用哪些例程时,选择允许您使用NSURL对象指定路径的路径,而不是使用字符串指定路径的路径.大多数基于URL的例程都是在OS X v10.6及更高版本中引入的,并且从一开始就设计为利用Grand Central Dispatch等技术.这使您的代码在多核计算机上立即获得优势,同时不需要您做太多工作.

文件系统编程指南


Min*_*int 5

但是,在 Swift 4 中,您应该这样做:

当两个选项放在同一个子句中时,Xcode 9.2 似乎自动将NSData视为。我必须将这两个选项放在单独的子句中,如下所示:Dataguard-letguard-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
Run Code Online (Sandbox Code Playgroud)