Appropriate way to get user's location(also in killed state) for an “hyperlocal” app

ぐ巨炮叔叔 提交于 2019-12-10 13:22:57

问题


Requirement - I am building a hyperlocal app which will provide offers to user based on his location. When in app I can get his current location and show offers accordingly but what I need now is to send push notification to user based on his location. So I want to find out user's location and send offers based on his location.

I have read Apple doc for Significant-Change Location Service but then this answer is saying that it won't work once app is killed.

I have also read about Tracking the User’s Location but that didn't work for me properly. I was not getting more than 5 updates in background.

My current code in viewDidLoad -

if (self.locationManager == nil)
{
     self.locationManager = [[CLLocationManager alloc] init];
     self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
     self.locationManager.delegate = self;
     self.locationManager.allowsBackgroundLocationUpdates = true;
     self.locationManager.pausesLocationUpdatesAutomatically = false;
     if ([CLLocationManager authorizationStatus] != AVAuthorizationStatusAuthorized) {
         [self.locationManager requestAlwaysAuthorization];
     }
}
[self.locationManager startUpdatingLocation];

And my delegate method looks like this -

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {   
   if (UIApplication.sharedApplication.applicationState == UIApplicationStateActive) {
       // Get updated data according to location
   } else {
       // Send location to server
   }
}

My apps capabilities And my plist -

Please suggest some appropriate way, I can live with accuracy of around 1km.

Another approaches -

  1. Can I get user's location in "Background Mode- Background Fetch"'s fetchNewDataWithCompletionHandler: ?

  2. Can I get user's location using Silent Push notification's application:didReceiveRemoteNotification:fetchCompletionHandler:? ): Not possible according to this answer


回答1:


So, your question is basically "How can I get around Apple's specifically designed user interaction for people wanting to make my app shut up?" The answer to that is "Not if you want to stay within the rules for the AppStore".

Listen, if the user decides to terminate your app (i.e. they swipe it up and out of the task manager), the entire point of this design is for your app to stop do anything. Apple designed this so that people can quickly turn off exactly the kind of behavior you seem to want to implement. I don't quite get why you would want to circumvent that. I agree that this interaction is a bit obscure perhaps (after all, users can also allow/disallow an app's right to receive location updates in the background in the Settings app as well), but that's the interaction iOS defines.

If I understand you correctly, you succeeded in properly setting up the background location modes, so your app can receive the location updates even if it is not in the foreground (i.e. in background or suspended, in the latter situation iOS wakes it up briefly so you can process location updates and e.g. send a local notification to inform the user). That's as good as it gets.

Oh, and don't fear a device reboot. Yes, after the reboot your app is technically not running, but since the user didn't explicitly kill it the last time, iOS treats it like it was in suspended mode, IIRC, so you will still get significant location updates and can react properly. (In a more general way: people often seem to think the actual app process state reflects the app state as it is defined in the documentation and/or that whether the app is shown in the task manager is linked to that. Both isn't entirely true.)


Edit after your comment asking me specifically about background fetch:

Sorry, that was perhaps not entirely clear. I didn't answer on this sub-question specifically, because after the user quits your app intentionally, you should not, as explained, "cheat" on their intention. Silent push notifications won't work because of this, yes.

I don't know whether the background fetch will be suppressed in a similar way (could be, but I haven't tried it), but I think that won't help you either, even if it were still working (which I doubt, Apple's probably going to be hard on this). I have also never tried to (re)start location updates in this method, so I can't say whether that even works (once the completion handler is called the system will likely suspend your app again at least, and I am not sure that this "resets" the "user killed the app flag" that the system seems to use for deciding which app to wake up and deliver location updates to).

application:performFetchWithCompletionHandler: (as it is fully called) will be called by the OS based on heuristics, it tries to be "clever" on this. Since the method is meant to fetch some data from a backend that doesn't provide push notifications, the times it is called at all can be severely limited, as is explained in the documentation. The actual mechanism that decides when the OS calls is a black box and it is a gamble to try to trick it into getting called when you need it. Could be very likely that this happens hours later. Think of the following scenario:

  • Your app runs fine in the background location modes (I understood you correctly in that you successfully set that up? see here and here)
  • The user manually kills your app. For the sake of this argument let's assume that doesn't keep the system from later restarting it to give it a background fetch opportunity
  • Since other apps are running on the system and the user only has an edge connection at the moment, the OS decides it is a bad time to initiate a background fetch (I just assume here that those factors play a role, as said it's a blackbox, but those appear reasonable to me). Your user walks around some more, bypassing several locations you would be interested in.
  • Two hours later, the user is by now in a completely different area, your app is started again by the OS and gets a application:performFetchWithCompletionHandler: call. You start location updates again (lets assume that even works and the system doesn't immediately terminate the app again, i.e. even after the fake background fetch it delivers location updates in background). You missed several locations, but nevertheless the app now handles new ones. All your logic is basically messed up, because you didn't plan for so many location updates being missing...
  • (Optional: After a while your user realizes that your app apparently does something, even although they terminated it (for example they notice battery drain). They will delete your app and leave a one-start review...)
  • (Optional 2, worst-case: Once apple realizes it is possible to re-init background location updates after a user killed an app this way, they simply close the loop-hole in an iOS update and your app is back where we started...)

For the record: I am not defending any design decisions made by apple, heck I know this is confusing to wrap your head around and just as one can make a stand for "preserve battery and user intent under all circumstances" one can make one for better background tracking. I am merely pointing out that they're in control here and trying to weasel around any specific interaction paradigms they set on the platform is likely not a good idea.

That all being said, I am afraid the "user terminated the app, now I won't get any location updates" is simply something you have to live with. Why would that even be a problem for you, considering you didn't say anything about background location modes not being enough for you? The only (questionable) scenario I could imagine is a kind of tracker application, maybe given on devices handed out to employees of a delivery service or something. If that is it (and putting aside the ethics behind such stuff, in some countries that is even illegal to do, mind you...), I have to say that iOS is simply not the correct platform for this.




回答2:


Hi just create a UILocalNotification set it with your details and most important for notification to be triggered when you enter a Region add the region property see docs

Hope it helps



来源:https://stackoverflow.com/questions/43317108/appropriate-way-to-get-users-locationalso-in-killed-state-for-an-hyperlocal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!