Are there any way to upload locations from background frequently using 3G/4G/LTE?

459 views Asked by At

I want to make an iOS7 devise to upload its locations to server from background using 3G/4G/LTE(NOT WiFi) frequently like less than every 5 to 10 mins or when it's location changed.

What I already have tried is like these:

1.Background Fetch

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler is called so irregularly and not controllable.

2.Remote Notification(NOT silent push)

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler is called only in WiFi connection.

3.CLLocationManager

I put uploader in - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation but it is called when on WiFi only.

I want to realize an application like "Find Your Friends" which is the Apple native application in iOS8. Are there any ideas?

Thank you for your help.

UPDATE

I tried NSURLSession upload triggered by CLLocationManager didUpdateToLocation like below, but still it uploads only on WiFi.

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{

[[NSUserDefaults standardUserDefaults] setFloat:newLocation.coordinate.latitude forKey:@"lat"];
[[NSUserDefaults standardUserDefaults] setFloat:newLocation.coordinate.longitude forKey:@"lon"];
[[NSUserDefaults standardUserDefaults] synchronize];

[self update];

}

- (void)update
{

NSURL *url = [NSURL URLWithString:@"http://.../updater.php"];
NSString *identifier = [NSDate date].description;
NSURLSessionConfiguration *configration = [NSURLSessionConfiguration backgroundSessionConfiguration:identifier];
configuration.networkServiceType = NSURLNetworkServiceTypeBackground;
configuration.discretionary = NO;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"PUT";
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration
                                                      delegate:self
                                                 delegateQueue:[NSOperationQueue mainQueue]];

float lat = [[NSUserDefaults standardUserDefaults] floatForKey:@"lat"];
float lon = [[NSUserDefaults standardUserDefaults] floatForKey:@"lon"];

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                            [NSNumber numberWithFloat:lat], @"lat",
                            [NSNumber numberWithFloat:lon], @"lon", nil];

NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:nil];

NSString *path = [[self applicationDocumentsDirectory].path stringByAppendingPathComponent:@"json.data"];
[data writeToFile:path atomically:YES];

NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromFile:[NSURL fileURLWithPath:path]];

[task resume];

}

- (NSURL *)applicationDocumentsDirectory
{

// The directory the application uses to store the Core Data store file. This code uses a directory named "jp.skyElements.NNZ" in the application's documents directory.
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];

}
1

There are 1 answers

5
pronebird On BEST ANSWER

You have background location updates mode which allows your app to get notified about location changes. Read more on this in Background Modes section in Xcode documentation for iOS.

Now I never tried to do any network requests during background location updates but what I would try is the following:

NSURLSession with background configuration. POST to server and delegate all burden of this to iOS itself. QoS, network throttling, power efficiency and other benefits come out of this.