Ios 将目标c中的4行代码翻译成swift(指针)

Ios 将目标c中的4行代码翻译成swift(指针),ios,objective-c,pointers,swift,Ios,Objective C,Pointers,Swift,两天以来,我一直在将一段代码从Objective-C翻译成Swift: CFArrayRef keyref = NULL; CFDictionaryRef identityDict = CFArrayGetValueAtIndex(keyref, 0); SecIdentityRef identityRef = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity); 是的,就这些!我就是不

两天以来,我一直在将一段代码从Objective-C翻译成Swift:

CFArrayRef keyref = NULL;
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(keyref, 0);
SecIdentityRef identityRef = (SecIdentityRef)CFDictionaryGetValue(identityDict,      kSecImportItemIdentity);
是的,就这些!我就是不能用这些指针来满足编译器。 请帮忙:-)

这是要翻译的全部目标c代码:

// Read .p12 file
NSString *path = [[NSBundle mainBundle] pathForResource:@"SSLKeyStoreClient" ofType:@"p12"];
NSData *pkcs12data = [[NSData alloc] initWithContentsOfFile:path];

// Import .p12 data
CFArrayRef keyref = NULL;
OSStatus sanityChesk = SecPKCS12Import((__bridge CFDataRef)pkcs12data,
                                       (__bridge CFDictionaryRef)[NSDictionary
                                                                  dictionaryWithObject:@"wed-zzz"
                                                                  forKey:(__bridge id)kSecImportExportPassphrase],
                                       &keyref);
if (sanityChesk != noErr) {
    NSLog(@"Error while importing pkcs12 [%d]", (int)sanityChesk);
} else
    NSLog(@"Success opening p12 certificate.");

// Identity
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(keyref, 0);
SecIdentityRef identityRef = (SecIdentityRef)CFDictionaryGetValue(identityDict,
                                                                  kSecImportItemIdentity);

// Cert
SecCertificateRef cert = NULL;
OSStatus status = SecIdentityCopyCertificate(identityRef, &cert);
if (status)
    NSLog(@"SecIdentityCopyCertificate failed.");

// the certificates array, containing the identity then the root certificate
NSArray *myCerts = [[NSArray alloc] initWithObjects:(__bridge id)identityRef, (__bridge id)cert, nil];

NSMutableDictionary *SSLOptions;
[SSLOptions setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsExpiredRoots];

NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
                          [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
                          [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
                          [NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
                          kCFNull,kCFStreamSSLPeerName,
                          myCerts,kCFStreamSSLCertificates,
                          nil];


CFReadStreamSetProperty((CFReadStreamRef)self.inputStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
CFWriteStreamSetProperty((CFWriteStreamRef)self.outputStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
到目前为止,我得到的是:

// Read .p12 file
var path = NSBundle.mainBundle().pathForResource("SSLKeyStoreClient", ofType: "p12")
var pkcs12data: NSData = NSData.dataWithContentsOfFile(path, options: nil, error: nil)

// Import .p12 data
var keyref: Unmanaged<CFArray>?


var optionDict: NSMutableDictionary = NSMutableDictionary()
optionDict.setValue("wed-zzz", forKey: kSecImportExportPassphrase!.takeRetainedValue())

var sanityChesk = SecPKCS12Import(pkcs12data,optionDict,&keyref)
if sanityChesk != 0{ //noErr
   println("Error while importing pkcs12 \(sanityChesk)")
} else {
   println("Success opening p12 certificate.")
}


// Identity
var key = keyref!
var identityDict: CFDictionary = CFArrayGetValueAtIndex(keyref, 0)
var identityRef:COpaquePointer = CFDictionaryGetValue(identityDict,nil)


// Cert
var cert: Unmanaged<SecCertificate>?
var status: OSStatus  = SecIdentityCopyCertificate(identityRef, &cert)
if status == 0{
    println("SecIdentityCopyCertificate failed.")
}

// the certificates array, containing the identity then the root certificate
var sslOptions = Dictionary<NSObject, NSObject>()

sslOptions[kCFStreamSSLAllowsExpiredRoots] = NSNumber.numberWithBool(true)

var settings = Dictionary<NSObject, NSObject>()
settings[kCFStreamSSLAllowsExpiredCertificates] = NSNumber.numberWithBool(true)
settings[kCFStreamSSLAllowsAnyRoot] = NSNumber.numberWithBool(true)
settings[kCFStreamSSLValidatesCertificateChain] = NSNumber.numberWithBool(false)
settings[kCFStreamSSLPeerName] = kCFNull
//settings[kCFStreamSSLCertificates] = myCerts



    CFReadStreamSetProperty(self.inputStream, kCFStreamPropertySSLSettings, settings)
    CFReadStreamSetProperty(self.inputStream, kCFStreamPropertySSLSettings, settings)
错误:“非托管CFArray无法转换为CFArray”


这是我迄今为止最好的尝试。

第一行大概是实际数组的占位符?如果您实际使用的是
NULL
数组指针,那么代码的其余部分什么也不做

假设您从一个真正的
CFArrayRef
开始,您可以利用桥接:CoreFoundation类型被自动视为Swift对象,因此您不需要使用
CFArrayRef
CFDictionaryRef
指针。这同样适用于使用CF类型系统的任何其他C API,因此它也应适用于
SecIdentity

CF集合的自动桥接似乎有些奇怪-您可以隐式地将
CFArray
桥接到
NSArray
,将
NSArray
桥接到Swift
数组
,您不能只为
CFArray
下标

因此,您的转换如下所示(封装在处理假定数组的函数中):

func getIdentity(keychainArray:NSArray)->SecIdentity?{
让dict=keychainArray[0]作为字典
let key=kSecImportItemIdentity.takeRetainedValue()
是否将dict[key]返回为SecIdentity?
}
如果你有一个
CFArray
,你可以将它传递给这个函数,它会自动桥接/转换到
NSArray
,然后自动转换到Swift数组进行订阅。将项0视为Swift字典,您可以为字典下标以获取标识。对于密钥,您需要将其从
非托管的
中拉出,因为安全框架没有为该常量声明的隐式桥接设置

我让这个函数返回一个可选的,因为我不知道你传递的数组+字典是否真的包含一个标识。如果你确定有,你可以去掉两个问号


(这是在操场上编译的,但我没有一个数组包含一个字典,其中包含一个便于测试的标识,所以请注意清空。)

No
[]
表示它不是Objective-C.;)请把你试过的代码贴出来。(或者至少是那两天你试过的一些东西)keyref的真正价值是什么?显然它不是空的。这是C代码,没有ObjCcode@user3211074有什么最新消息吗?你有一个工作代码示例要分享吗?我有一个相关的问题。我正在使用类似的代码片段进行SSL连接mit证书固定。不幸的是,.p12文件需要我的私钥才能在“keyref”数组中至少有一个元素。在.p12导入中没有私钥可以正常工作,但“keyref”中没有对象。由于密钥文件是应用程序的一部分并分发到商店,我不想包含私钥。我该如何处理这个问题?谢谢,我已经在打字时使用了你的提示。但现在我遇到了另一个问题(我昨天不知何故已经遇到了这个问题)编译器错误:架构i386的未定义符号:“OBJC_CLASS_$_SecIdentity”,引用自:uu tfc9Messenger 10Connection11GetIdentityfs0_FCSo7NSArrayGSqCSo11SecIdentity in Connection.o ld:symbol(s)未找到架构i386的clang:error:链接器命令失败,退出代码为1(使用-v查看调用),它似乎是在游乐场中编译的,但不是在空项目中编译的。你知道吗?我想这一定是测试版的问题,我自己也解释不了你的代码不是在正常的项目中编译的。仍然存在上述错误。有什么想法吗?我已经修改了你的代码,现在可以编译了,但是最后还是出现了运行时错误。也许你可以帮我:
let dict=keychainArray[0]作为字典let key:NSString=kSecImportItemIdentity.takeRetainedValue()返回dict[key]这以“致命错误:值未能从Objective-C类型桥接到Swift类型”结尾。似乎SecIdentity是Swift类型?!但客观的C型会在哪里呢?
var identityDict: CFDictionary = CFArrayGetValueAtIndex(keyref, 0)
func getIdentity(keychainArray: NSArray) -> SecIdentity? {
    let dict = keychainArray[0] as Dictionary<String,AnyObject>
    let key = kSecImportItemIdentity.takeRetainedValue()
    return dict[key] as SecIdentity?
}