Синхронный запрос NSURLConnection на https
Может ли кто-нибудь сказать мне, как я могу сделать синхронный вызов на https-сервере? Я могу выполнить асинхронный запрос на сервере https, используя следующие методы делегирования.
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
и
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
но мне нужно сделать синхронный.
Ответы
Ответ 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())
Надеюсь, это поможет кому-то еще в будущем.