В ролях NSData как! CFDataRef в 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)
3 ответа
Немного безопаснее версия:
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. Это дает вашему коду непосредственное преимущество на многоядерных компьютерах, не требуя от вас много работы.
В Swift 4, однако, вы должны сделать это следующим образом:
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
@Abizern ответ работает, но используйте CFDataCreateWithBytesNoCopy
вместо CFDataCreate
более эффективно.