After looking through a lot of code and a dizzying array of ways to do this, I really couldn't find a "simple" example. Many examples on the net are pre-ARC, or too complex for my level of understanding. Still other examples hinged on 3rd party libraries which are no longer in development. Still other examples, more up to date, have timeouts of 30 seconds in which everything must be completed (ios7 fetch) which doesn't seem like enough time for a quick download on a busy wi-fi network. Eventually, I did manage to piece together a working sample which does run a background download every 20 seconds. Not sure how to update the UI yet.
AppDelegate.m
#import "bgtask.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
bgtask *b = [[bgtask alloc] initTaskWithURL:@"http://www.google.com" app:application];
return YES;
}
bgtask.h
#import <Foundation/Foundation.h>
@interface bgtask : NSOperation
@property (strong, atomic) NSMutableData *webData;
@property (strong, atomic) UIApplication *myApplication;
- (id) initTaskWithURL:(NSString *)url app:(UIApplication *)application;
@end
bgtask.m
#import "bgtask.h"
@implementation bgtask
UIBackgroundTaskIdentifier backgroundTask;
@synthesize webData = _webData;
@synthesize myApplication = _myApplication;
NSString *mURL;
// connect to webserver and send values. return response data
- (void) webConnect
{
NSURL *myURL = [NSURL URLWithString:mURL];
_webData = [NSData dataWithContentsOfURL:myURL];
if (_webData)
{
// save response data if connected ok
NSLog(@"connetion ok got %ul bytes", [_webData length]);
}
else
{
NSLog(@"connection failed");
//TODO: some error handling
}
}
- (void) timerTask:(NSTimer *) timer
{
backgroundTask = [_myApplication beginBackgroundTaskWithExpirationHandler:
^{
dispatch_async(dispatch_get_main_queue(),
^{
if (backgroundTask != UIBackgroundTaskInvalid)
{
[_myApplication endBackgroundTask:backgroundTask];
backgroundTask = UIBackgroundTaskInvalid;
}
});
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
NSLog (@"Running refresh...");
[self webConnect];
dispatch_async(dispatch_get_main_queue(),
^{
if (backgroundTask != UIBackgroundTaskInvalid)
{
[_myApplication endBackgroundTask:backgroundTask];
backgroundTask = UIBackgroundTaskInvalid;
}
});
});
}
- (id) initTaskWithURL:(NSString *)url app:(UIApplication *)application
{
self = [super init];
if (self)
{
// setup repeating refresh task.
// Save url, application for later use
mURL = [[NSString alloc] initWithString:url];
_myApplication = application;
[NSTimer scheduledTimerWithTimeInterval:20.0
target:self
selector:@selector(timerTask:)
userInfo:nil
repeats:YES];
NSLog (@"task init");
}// if self
return (self);
}