1

I have to do SSL pinning so need to verify server side SSL certificate. SO I have to use NSURL delegates. I have a helper class in which I have created method which returns me login response:

- (NSData *)sendSynchronousRequest:(NSString *)strNewLoginRequest
             returningResponse:(NSURLResponse **)response
                         error:(NSError **)error {
NSMutableURLRequest *finalRequest = nil;

NSURL *url= [NSURL URLWithString:const_url];

finalRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30.0];

NSData *requestData = [NSData dataWithBytes:[strLoginRequest UTF8String] length:[strLoginRequest length]];

    self.connection = [[NSURLConnection alloc] initWithRequest:finalRequest delegate:self startImmediately:NO];

    NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
    [self.connection unscheduleFromRunLoop:currentRunLoop forMode:NSDefaultRunLoopMode];
    [self.connection scheduleInRunLoop:currentRunLoop forMode:@"connectionRunLoopMode"];

    [self.connection start];

    while ([currentRunLoop runMode:@"connectionRunLoopMode" beforeDate:[NSDate distantFuture]]);

    return self.mutableResponse;
}

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

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    self.mutableResponse = [[NSMutableData alloc]init];
    [self.mutableResponse appendData:data];

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    dispatch_async(dispatch_get_main_queue(), ^{

    if (loadingView)
    {
        [loadingView removeView];
    }

    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Failure" message:@"Network Failure" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];

        [alert show];
    });
}

 - (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if (loadingView)
    {
        [loadingView removeView];
    }
    self.resultString = [[NSString alloc] initWithData:self.mutableResponse      encoding:NSASCIIStringEncoding];
}

and I am calling this method from another class called ViewController with code

-(void)doLogin
{
 self.service = [[SyncCommunicationService alloc]init];
 NSData *data = [self.service sendSynchronousRequest:strNewLoginRequest
                                  returningResponse:&response
                                              error:nil];
}

I have tried calling this method in background and on main thread but still delegate methods are not getting called, I have tried many other answers from same website but still couldn't able to solve this issue so please can anybody have a clue what am I doing wrong.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Vaibhav
  • 865
  • 2
  • 10
  • 19

1 Answers1

1

I'm wondering why would anyone use asynchronous request for performing task synchronously? Not to mention this strange way to wait with while statement instead of dispatch_semaphore or something similar.

However, why You even bother with delegate? Just use class method sendSynchronousRequest:returningResponse:error:. I think, it would suffice in your case

Sergii Martynenko Jr
  • 1,407
  • 1
  • 9
  • 18
  • i have to verify server certificates for SSL pinning so i have to use delegate method. – Vaibhav Jun 18 '15 at 08:30
  • In that case, try setting connection delegate queue `setDelegateQueue:` Let this queue be property of your SyncCommunicationService – Sergii Martynenko Jr Jun 18 '15 at 08:38
  • And, are You confident with that `while` statement for wait operation? Why won't You use dispatch_semaphore instead? Than your `sendSynchronousRequest:returningResponse:error:` method will return nothing, and response data can be retrieved from property of SyncCommunicationService (that is what I am doing each time, I need to retrieve data asynchronously) – Sergii Martynenko Jr Jun 18 '15 at 08:42
  • Yes !! while statement is for wait operation and its working, if I call all the methods from my ViewController class itself. The problem occurs when i try to communicate with my helper class to get the Data. – Vaibhav Jun 18 '15 at 09:17
  • also i tried setting delegate queue but still no success. – Vaibhav Jun 18 '15 at 09:25
  • Does your method return? Or it just waits continuously? – Sergii Martynenko Jr Jun 18 '15 at 10:02
  • And I would still suggest get rid of this `while` - looks like hack for me. Use delegation, dispatch_semaphore or notification instead - why reinvent the wheel while you're provided with ready to use and time-proved instruments? – Sergii Martynenko Jr Jun 18 '15 at 10:05
  • Well, shame on me, it's obvious - `self.connection` does not actually start anything. It just schedules start task to your current run loop - it won't be preformed while any other tasks scheduled before takes place on this loop. And, at least, you have your's helper method running - it's a deadlock!!! So just follow my advice from above - get rid of this `while`, make your helper method void-return and use notifications or delegation to get notified once you have connection finishes (successfully or not) – Sergii Martynenko Jr Jun 18 '15 at 10:08
  • Tell me, if you need more help - would be glad to provide you it – Sergii Martynenko Jr Jun 18 '15 at 10:31
  • sergii.. thank you so much for suggesting to make my method of type void, i created blocks to receive data. and its working now.thanks again. – Vaibhav Jun 18 '15 at 12:25
  • Would be grateful for marking my answer as helpful, if you really think it is – Sergii Martynenko Jr Jun 18 '15 at 12:38