Подтвердить что ты не робот

Синхронный запрос NSURLConnection на https

Может ли кто-нибудь сказать мне, как я могу сделать синхронный вызов на https-сервере? Я могу выполнить асинхронный запрос на сервере https, используя следующие методы делегирования.

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace

и

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

но мне нужно сделать синхронный.

4b9b3361

Ответ 1

//Кодирование запроса

NSData *postData = [xmlText dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];

**//Calculating length of request**
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];

NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:requestUrlString]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
NSURLResponse* response;
NSError* error = nil;

//Capturing server response
NSData* result = [NSURLConnection sendSynchronousRequest:request  returningResponse:&response error:&error];

Ответ 2

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error

в NSUrlConnection должен работать только с https.

Если вы хотите предоставить учетные данные, они должны быть частью URL: (https://username:[email protected]/api/user.json).

Невозможно предоставить делегат NSUrlConnection, поэтому, если вам нужна некоторая нестандартная проверка подлинности, вам нужно сделать это асинхронно.

Ответ 3

Как я это сделал: вместо

[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]

Я сделал тот же экземпляр метода, основанный на содержащем классе, поскольку нам понадобится делегат. И не делайте это singleton, поэтому каждое соединение имеет свои независимые переменные, потому что, если мы этого не сделаем, и два соединения будут вызваны до того, как закончится другое, тогда полученные данные и обработка петель будут переплетены безвозвратно.

[[ClassNameHere new] sendSynchronousRequest:request returningResponse:&response error:&error]

Таким образом, я могу создать соединение NSUrl и обработать его (синхронно, как мы это увидим), поэтому мне не нужно менять какой-либо ранее написанный код.

- (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse *__strong*)response error:(NSError *__strong*)error
{
    _finishedLoading=NO;
    _receivedData=[NSMutableData new];
    _error=error;
    _response=response;

    NSURLConnection*con=[NSURLConnection connectionWithRequest:request delegate:self];
    [con start];
    CFRunLoopRun();

    return _receivedData;
}


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

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
{
    //handle the challenge
}

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

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [_receivedData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    *_error=error;
    CFRunLoopStop(CFRunLoopGetCurrent());
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    CFRunLoopStop(CFRunLoopGetCurrent());
}

Уловка была в CFRunLoopRun() и CFRunLoopStop (CFRunLoopGetCurrent()) Надеюсь, это поможет кому-то еще в будущем.