简体   繁体   English

https上的NSURLConnection同步请求

[英]NSURLConnection synchronous request on https

Can anyone tell me the way how I can make a synchronous call to the https server? 谁能告诉我如何与https服务器进行同步调用? I am able to do asynchronous request on https server using following delegate methods. 我可以使用以下委托方法在https服务器上执行异步请求。

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

and

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

but I need to do synchronous. 但我需要做同步。

//Encoding the request //编码请求

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];
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error

in NSUrlConnection should work just fine with https. NSUrlConnection应该可以正常使用https。

If you'd like to provide credentials, they need to be part of the url: ( https://username:password@domain.tld/api/user.json ). 如果您想提供凭据,则需要成为URL的一部分:( https://username:password@domain.tld/api/user.json )。

There's no way to provide a NSURLConnection delegate, so if you need some nonstandard authentication handling you'll need to do it asynchronously. 无法提供NSURLConnection委托,因此如果您需要一些非标准的身份验证处理,则需要异步执行。

That's how i did it: instead of 这就是我做到的方式:而不是

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

I made the same method instance based, on the containing class, since we will need a delegate. 我在包含类上创建了相同的方法实例,因为我们需要一个委托。 And don't make it singleton, so every connection has its independent variables, because, if we don't, and two connections happen to be called before the other finishes, then the received data and the handling of the loops will be intertwined irrecoverably. 并且不要使它成为单例,因此每个连接都有自己的独立变量,因为如果我们不这样做,并且在另一个连接完成之前恰好调用了两个连接,那么接收到的数据和循环的处理将无法相继交织在一起。

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

This way i can create an NSUrl connection and handle it (in a synchronous way, we'll see how) so i don't have to change any of the previously written code. 这样我就可以创建一个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());
}

The trick was in the CFRunLoopRun() and CFRunLoopStop(CFRunLoopGetCurrent()) I hope it helps someone else in the futur. 诀窍在CFRunLoopRun()和CFRunLoopStop(CFRunLoopGetCurrent())我希望它可以帮助其他人在未来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM