SSL/TLSが有効になっCFStream
ているリモート サーバーにオブジェクトのペアを作成するコードがあります。このコードは OS X では問題なく動作しますが、iOS で実行すると失敗します。コンソールログは次のとおりです。
2011-04-26 22:39:35.820 RemoteSample[92127:40b] connecting to 192.168.1.187:8099
2011-04-26 22:39:35.825 RemoteSample[92127:40b] INPUT: NSStreamEventOpenCompleted
2011-04-26 22:39:35.825 RemoteSample[92127:40b] OUTPUT: NSStreamEventOpenCompleted
2011-04-26 22:39:35.827 RemoteSample[92127:40b] INPUT: NSStreamEventErrorOccurred
2011-04-26 22:39:35.828 RemoteSample[92127:40b] Error on input stream: The operation couldn’t be completed. (OSStatus error -108.)
2011-04-26 22:39:35.829 RemoteSample[92127:40b] OUTPUT: NSStreamEventErrorOccurred
2011-04-26 22:39:35.829 RemoteSample[92127:40b] Error on output stream: The operation couldn’t be completed. (OSStatus error -108.)
OSStatus エラー -108 は memFullErr のように見えますが、これは単純に奇妙で、どうすればよいかわかりません。これは、シミュレーターとデバイスの両方で発生します。Mac OS X アプリケーションでは、この問題なくコンパイルおよび実行されます。このエラーは、iOS 用にビルドされた場合にのみ発生します。
数時間かけてさまざまなアイデアを試し、多くの検索を行った結果、次のステップについてアドバイスを得ることができました。
コードは次のとおりです。
CFReadStreamRef inCfStream = NULL;
CFWriteStreamRef outCfStream = NULL;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)host, port, &inCfStream, &outCfStream);
if (inCfStream && outCfStream)
{
CFReadStreamSetProperty(inCfStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
inStream = NSMakeCollectable(inCfStream);
outStream = NSMakeCollectable(outCfStream);
[inStream setDelegate:self];
[outStream setDelegate:self];
[inStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey];
NSDictionary *properties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
kCFNull,kCFStreamSSLPeerName,
nil];
if (CFReadStreamSetProperty(inCfStream, kCFStreamPropertySSLSettings, (CFTypeRef)properties) == FALSE)
{
NSLog(@"Failed to set SSL properties on read stream.");
}
inputBuffer = [[NSMutableData alloc] init];
[inStream open];
[outStream open];
}