Muhammad Umar
Muhammad Umar

Reputation: 11782

Calling a GCD Block else where in Main Thread

I am using following Code to get response from a string query. There are a lot of queries all around in my app and i want to copy and paste this code again and again

Is there any way I can just make an instance of it , pass the urlString and then return the response..

I have tried creating a function +(NSString*) myFunc{} in an NSObject Class but it seems that GCD Doesn't work except Main UI Threads. How can i fix this issue

__block__  NSString *response;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

    //your server url and request. data comes back in this background thread
    response; = [NSString stringWithContentsOfURL:[NSURL URLWithString:queryString] encoding:NSUTF8StringEncoding error:&err];

    dispatch_async(dispatch_get_main_queue(), ^{
        //update main thread here.
        NSLog(@"%@",response); // NEED TO RETURN THIS

        if (err != nil)
        {
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle: @"Error"
                                                           message: @"An error has occurred."
                                                          delegate: self
                                                 cancelButtonTitle:@"Ok"
                                                 otherButtonTitles:nil];
            [alert show];
            [indicator stopAnimating];
        }
    });
});

Upvotes: 1

Views: 365

Answers (1)

trojanfoe
trojanfoe

Reputation: 122391

I would separate out the request processing from the error reporting, using a completion block to provide the feedback to the caller.

First define the completion block semantics; we know we want the string response and an optional error descriptor:

typedef void (^COMPLETION_BLOCK)(NSString *response, NSString *error);

Second implement the method that will get the response in the background and then call the completion block in the main thread. This could be a class method in some global utility class if you wish:

- (void)responseFromURL:(NSURL *)url
        completionBlock:(COMPLETION_BLOCK)completionBlock
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSError *error = nil;
        NSString *response = [NSString stringWithContentsOfURL:url
                                                      encoding:NSUTF8StringEncoding
                                                         error:&error];

        dispatch_async(dispatch_get_main_queue(), ^{
            completionBlock(response, error);
        }
    }
}

And finally call the method:

[someClass responseFromURL:[NSURL URLWithString:queryString]
           completionBlock:^(NSString *response, NSError *error) {

    NSLog(@"response='%@'", response);

    if (error != nil)
    {
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error getting response"
                                                       message:[error localizedDescription]
                                                      delegate:self
                                             cancelButtonTitle:@"Ok"
                                             otherButtonTitles:nil];
        [alert show];
        [indicator stopAnimating];
    }
}];

(this code is untested and will therefore doubtless contain some bugs)

Upvotes: 1

Related Questions