1

を使用してサーバーからデータを要求していますNSString#stringWithContentsOfURL:。サーバーは自己署名証明書を使用しているため、stringWithContentsOfURL:単純に nil を返し、証明書を受け入れるように変更しません。

これはすべて予期される動作です。私はこれを適切に行う方法を知ってNSURLConnectionおり、代わりにデリゲート メソッドを使用していますが、このコードを書き直すのではなく、短期間の修正を探しています。(イェーイ締め切り)

私の質問は、自己署名証明書をアプリケーションのキーチェーンにインポートすることは可能ですか?それによってstringWithContentsOfURL:自己署名証明書が受け入れられるようになりますか?

4

2 に答える 2

1

SSL証明書をインストールするためのAppleからのエンタープライズツールがあると私は信じています-交換メールを機能させるために必要でした。

.cer ファイルを自分宛てにメールで送信し、iPhone で開いてインストールすることもできます。

AppleのAdvancedURLConnections サンプル プロジェクトもあります。

このサンプルは、NSURLConnection を使用したさまざまな高度なネットワーク技術を示しています。具体的には、認証チャレンジに応答する方法、デフォルトのサーバー信頼評価を変更する方法 (たとえば、自己署名証明書を使用してサーバーをサポートするため)、およびクライアント ID を提供する方法を示します。

于 2010-09-21T11:03:43.590 に答える
1

その SSL 検証スキームを回避する方法はありません。しばらくの間、ソリューションをあちこち探し回った後、まさにそれを行うためのクラスを実装する必要がありました。

NSString の stringWithContentsOfURL の利点は同期であることなので、私も同期する必要がありました。すべての目的に対して少し大きいかもしれませんが、その要点は理解できます。

@interface NZStringLoader : NSObject
@property (assign, readonly, nonatomic) BOOL done;
@property (strong, readonly, nonatomic) NSString *result;
@property (strong, readonly, nonatomic) NSURLConnection *conn;

- (id) initWithURL:(NSURL*)u;
- (void) loadSynchronously;

@end

@implementation NZStringLoader

@synthesize done = _done, result = _result, conn = _connection;

- (id) initWithURL:(NSURL*)u {
    NSURLRequest *req = [[NSURLRequest alloc] initWithURL:u
                                              cachePolicy:NSURLRequestReloadIgnoringCacheData
                                          timeoutInterval:10.0];
    _connection = [NSURLConnection connectionWithRequest:req delegate:self];
    _done = NO;

    return self;
}

- (void) loadSynchronously {
    [_connection start];

    while(!_done)
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.15]];
}

#pragma mark -
#pragma mark NSURLConnectionDelegate

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    _done = YES;
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    RTLog(@"%@", [error localizedDescription]);
    _done = YES;
}

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    if(_result == nil)
        _result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    else
        _result = [_result stringByAppendingString:[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]];
}

@end

そして、次のように使用されます。

    NZStringLoader *sl = [[NSStringLoader alloc] initWithURL:u];
    [sl loadSynchronously];
    result = sl.result;

必要に応じて、1回の呼び出しで済むと思います。

于 2012-04-07T16:36:21.030 に答える