How to load page content within a new UIWebView before exiting current method

457 views Asked by At

I have an application with implemented local server which handles request from web front-end. UIWebView presents some GUI, user do some interaction, I handle his requests and send responses back to webview.

Sometimes I'm receiving some request which require to open second webview (e.g for facebook login) and wait in current method for results to return from that second webview.

When I'm running such case on iDevice with dual core processor it works as expected. But when I'm running it on single core iPhone 4, webview processing is blocked until i leave the current method (white page with waiting indcator).

I solved this by putting sleep for current thread so the main thread will have time to process events in his run loop (if I properly understand this)

 - (void)requestProcessingMethod { // <-- on background thread
       someCalculations ...

       dispatch_sync(dispatch_get_main_queue(), ^{
       [self displayFacebookLoginWebView];
       });

       while(!facebookReturnCondition){
           [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];
           [NSThread sleepForTimeInterval:0.5]; // <-- on single core without this
                                                //     facebook webview will not load the login page
       }

       return response; //
   }

I'm not happy with that. Setting thread for sleep looks like very poor solution.

Is there any way to add working UIWebView from background thread without exiting current method (background thread)?

Or is it possible to manually switch/force run loop execution?

1

There are 1 answers

0
Naughty_Ottsel On

Now I am not sure if this will work, can't test at the moment. But:

You could try having the operations as separate operations in a queue, using Operation Dependencies.

in your case when you use this method:

-(void)methodThatCallsRequestProcessingMethod {

   NSOperationQueue *queue = [[NSOperationQueue alloc]init];

   NSInvocationOperation* theMainThreadOp = [[NSInvocationOperation alloc] initWithTarget:self
                    selector:@selector(displayFacebookLoginWebView) object:nil];

   NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self
                    selector:@selector(requestProcessingMethod) object:nil];
   [theOp addDependency: theMainThreadOp];

   [[NSOperationQueue mainQueue] addOperation: theMainThreadOp];
   [queue addOperation:theOp];

}

From reading the Concurrency Guide, it appears you can have operation dependencies over different queues. Which means that you can ensure the UI runs in the main thread, web later running in an async thread, keeping the Main Thread clear and responsive on all devices.

Apple Concurrency Guide