Making stringWithContentsOfURL asynchronous - Is it safe?
Asked Answered
M

3

6

I attempted to make -[NSString stringWithContentsOfURL:encoding:error:] asynchronous, by running it a-synchronically from a background thread:

__block NSString *result;
dispatch_queue_t currentQueue = dispatch_get_current_queue();

void (^doneBlock)(void) = ^{
    printf("done! %s",[result UTF8String]);
};

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
                                         (unsigned long)NULL), ^(void) {
    result = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com/"] encoding:NSUTF8StringEncoding error:nil];
    dispatch_sync(currentQueue, ^{
        doneBlock();
    });
});

Its working fine, and most importantly, its asynchronous.

My question is if it's safe to do this, or could there be any threading problems etc.?

Thanks in advance :)

Murrumbidgee answered 23/7, 2012 at 22:7 Comment(0)
D
27

That should be safe, but why reinvent the wheel?

NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];
[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    // etc
}];
Daffi answered 23/7, 2012 at 22:41 Comment(1)
First I though that this will work on main queue because of [NSOperationQueue mainQueue] , but than I saw sendAsynchronousRequest. So this should not stop UI from updating.Lianaliane
N
0

You can also use:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(queue, ^{
        NSError *error = nil;
        NSString *searchResultString = [NSString stringWithContentsOfURL:[NSURL URLWithString:searchURL]
                                                           encoding:NSUTF8StringEncoding
                                                              error:&error];
        if (error != nil) {
            completionBlock(term,nil,error);
        }
        else
        {
            // Parse the JSON Response
            NSData *jsonData = [searchResultString dataUsingEncoding:NSUTF8StringEncoding];
            NSDictionary *searchResultsDict = [NSJSONSerialization JSONObjectWithData:jsonData
                                                                              options:kNilOptions
                                                                                error:&error];
            if(error != nil)
            {
                completionBlock(term,nil,error);
            }
            else
            {

                //Other Work here
            }
        }
    });

But yes, it should be safe. I've been told though to use NSURLConnection instead due to error calls and such when communicating via the internet. I'm still doing research into this.

Nettie answered 21/4, 2013 at 15:35 Comment(0)
L
0
-(void)loadappdetails:(NSString*)appid {
    NSString* searchurl = [@"https://itunes.apple.com/lookup?id=" stringByAppendingString:appid];

    [self performSelectorInBackground:@selector(asyncload:) withObject:searchurl];

}
-(void)asyncload:(NSString*)searchurl {
    NSURL* url = [NSURL URLWithString:searchurl];
    NSError* error = nil;
    NSString* str = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
    if (error != nil) {
        NSLog(@"Error: %@", error);
    }
    NSLog(@"str: %@", str);
}
Lassitude answered 15/5, 2013 at 7:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.