将 NSData 转换为! swift 2.0 中的 CFDataRef

Cast NSData as! CFDataRef in swift 2.0

我的代码中有一行已被弃用,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)

稍微安全一点的版本:

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 而不是字符串路径。

When deciding which routines to call, choose ones that let you specify paths using NSURL objects over those that specify paths using strings. Most of the URL-based routines were introduced in OS X v10.6 and later and were designed from the beginning to take advantage of technologies like Grand Central Dispatch. This gives your code an immediate advantage on multicore computers while not requiring you to do much work.

来自File System Programming Guide

@Abizern 的答案有效,但使用 CFDataCreateWithBytesNoCopy 而不是 CFDataCreate 更有效。

但是在Swift4中,你应该这样做:

Xcode 9.2 似乎将 NSData 自动视为 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