Pregunta

I'm new to ios7 background fetch. Here is how I'm doing it.

This is what is going on in appDelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *url = [[NSURL alloc] initWithString:@"http://sample.com/api/home/lastnews"];
OldJson = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
}

Note that here I'm storing the whole JSON file in a string so i can use to check for new content.

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
//HomepageView is the view controller that is supposed to be updated
HomepageView *homepage = [[HomepageView alloc] init];

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];

NSURL *url = [[NSURL alloc] initWithString:@"http://sample.com/api/home/lastnews"];
NewJson = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];

NSURLSessionDataTask *task = [session dataTaskWithURL:url
        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

    if (error) {
        completionHandler(UIBackgroundFetchResultFailed);
        return;
    }

    if (![NewJson isEqualToString:OldJson])
    {
        completionHandler(UIBackgroundFetchResultNewData);
        NSLog(@"New Data : %@",NewJson);
    }
    else
    {
        completionHandler(UIBackgroundFetchResultNoData);
        NSLog(@"Old Json : %@",OldJson);
    }
}];

// Start the task
[task resume];
}

Now to test the whole process, i simply run the application. Then i send it to background and then when i have new content in the JSON file, i use the Simulate Background Fetch operation from the Debug menu. Then i open the application but nothing has changed.

¿Fue útil?

Solución

First store your newJson in NSUserDefaults as seen below

    if (![NewJson isEqualToString:OldJson])
                       {
                         completionHandler(UIBackgroundFetchResultNewData);
                         NSLog(@"New Data : %@",NewJson);
                         NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
                         [defaults setObject:NewJson forKey:@"newJson"];

                      }

Second in your View Controller add this in the ViewDidLoad

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refresh:) name: UIApplicationWillEnterForegroundNotification object:nil];

Add this to your viewWillAppear

-(void)viewWillAppear:(BOOL)animated{
[self loadData];

}

Create the loadData

- (void)loadData {
    // contains information the ViewController makes use of

    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    textView.text =  [defaults objectForKey:@"newJson"];
}

Finally add your action

-(IBAction)refresh:(id) sender {
    NSLog(@"I ran");
    [self loadData];
}

I tested this and it works.

Otros consejos

Three problems:

  1. There's no guarantee that JSON data comes in UTF-8 format. Use [NSData dataWithContensOfURL:...]

  2. Never, ever access a URL from the main thread. If the server doesn't respond, your app will be hanging.

  3. Really bad: In your background fetch handler, you actually load the URL synchronously. And then you create a task to load it again. So you load it actually twice.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top