适当的方式来获得用户的位置(也处于被杀死的状态)以获得"超本地化"应用

时间:2017-04-10 07:24:56

标签: ios objective-c swift cllocationmanager background-mode

要求 - 我正在构建一个超本地应用,它将根据用户的位置向用户提供优惠。在app中我可以获得他当前的位置并相应地显示优惠,但我现在需要的是根据他的位置向用户发送推送通知。所以我想找出用户的位置并根据他的位置发送优惠。

我已阅读Significant-Change Location Service的Apple文档,但后来this answer表示,一旦应用被杀,它就无法工作。

我也读过关于Tracking the User’s Location的内容,但这对我来说并不合适。我在后台没有获得超过5次更新。

我目前在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];

我的委托方法看起来像这样 -

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

我的应用功能和我的plist - enter image description here enter image description here

请建议一些适当的方式,我可以准确地生活在1公里左右。

另一种方法 -

  1. 我可以在"背景模式 - 后台获取"' fetchNewDataWithCompletionHandler:

  2. 中获取用户的位置
  3. 我可以使用静音推送通知application:didReceiveRemoteNotification:fetchCompletionHandler:来获取用户的位置吗? ):根据this answer

  4. ,这是不可能的

2 个答案:

答案 0 :(得分:2)

所以,你的问题基本上是"我如何解决Apple专门设计的用户互动,以便让我的应用程序闭嘴?" 答案是"如果你想要遵守AppStore规则,那就不是。

聆听,如果用户决定终止您的应用(即他们将其向上滑动并退出任务管理器),此设计的全部内容都是您的应用停止执行任何操作。 Apple设计了这个,以便人们可以快速关闭您似乎想要实现的行为。我不明白你为什么要绕开它。我同意这种互动可能有点模糊(毕竟,用户也可以允许/禁止应用程序在“设置”应用中在后台接收位置更新),但这是相互作用iOS定义。

如果我理解正确,您就成功设置了背景位置模式,因此即使不在前台,您的应用也可以接收位置更新(即在后台或暂停,在后一种情况下iOS会唤醒它简要介绍,以便您可以处理位置更新,例如发送本地通知以通知用户)。这很好。

哦,不要担心设备重启。是的,重新启动后你的应用程序在技术上没有运行,但由于用户最后没有明确地杀死它,iOS会像处于暂停模式IIRC那样对待它,所以你仍然会得到重要的位置更新,并且可以反应得当。 (以更一般的方式:人们通常认为实际的应用程序进程状态反映了应用程序状态,因为它在文档中定义和/或应用程序是否在任务管理器中显示是否与之相关联。两者都不是&#39 ; t完全正确。)

在您的评论之后

编辑,具体询问背景提取:

对不起,这可能并不完全清楚。我没有特别回答这个子问题,因为在用户有意退出你的应用之后,你不应该如所解释的那样"欺骗"他们的意图。由于这个原因,无声推送通知无法正常工作,是的。

我不知道背景提取是否会以类似方式被抑制(可能是,但我还没有尝试过),但我认为赢了&#39 ; t帮助你,即使它仍在工作(我怀疑,Apple可能会对此很难)。我也从未试图(重新)在这种方法中启动位置更新,所以我不能说这是否有效(一旦调用完成处理程序,系统可能会至少再次暂停你的应用程序,而我不是确保这"重置"用户杀死了应用程序标记"系统似乎用于决定唤醒哪个应用并提供位置更新。

操作系统将基于启发式调用

application:performFetchWithCompletionHandler:(因为它被完全调用),它会尝试“聪明地”#34;就此而言。由于该方法旨在从后端获取一些不提供推送通知的数据,因此它的调用时间可能会受到严重限制,如documentation中所述。决定操作系统调用的实际机制是一个黑盒子,并且当你需要时试图欺骗它进行调用是一种赌博。几小时后很可能发生这种情况。考虑以下情况:

  • 您的应用在后台位置模式下运行良好(我理解为您成功设置了该应用?请参阅herehere
  • 用户手动杀死您的应用。为了这个论点,让我们假设不会让系统在以后重新启动它以给它一个后台获取机会
  • 由于其他应用程序在系统上运行且用户此刻只有边缘连接,因此操作系统决定启动后台提取是一个糟糕的时间(我只是假设这些因素起作用,如上所述它是一个黑盒子,但那些对我来说是合理的)。您的用户可以绕过您感兴趣的几个位置,走动更多。
  • 两小时后,用户现在处于完全不同的区域,操作系统再次启动您的应用并获得application:performFetchWithCompletionHandler:电话。您再次开始位置更新(假设即使有效,系统也不会立即再次终止应用程序,即使在假冒背景提取后,它会在后台提供位置更新)。你错过了几个地方,但现在应用程序处理新的。您的所有逻辑基本上都搞砸了,因为您没有计划丢失那么多位置更新...
  • (可选:过了一段时间,您的用户意识到您的应用显然会做一些事情,即使他们终止它(例如他们注意到电池消耗)。他们会删除您的应用并留下一次开始审核......)< / LI>
  • (可选2,最糟糕的情况:一旦苹果意识到可以在用户以这种方式杀死应用程序后重新启动后台位置更新,他们只需关闭iOS更新中的循环漏洞,您的应用程序就会回到我们开始......)

为了记录:我不是在捍卫苹果公司做出的任何设计决定,哎呀我知道这让你感到困惑,就像人们可以在任何情况下保持电池和用户意图一样。 #34;一个人可以做一个更好的背景跟踪。我只是指出他们在这里控制并试图狡猾地围绕他们在平台上设置的任何特定交互范例可能不是一个好主意。

所有人都说,我担心用户终止了应用程序,现在我没有获得任何位置更新&#34;只是你必须忍受的东西。为什么这对你来说甚至会成为一个问题,因为你没有说出背景位置模式对你来说不够?我能想象的唯一(可疑)场景是一种跟踪器应用程序,可能是在发送给交付服务员工的设备上给出的。如果就是这样(并且抛开这些东西背后的道德规范,在某些甚至是非法的国家,请注意......),我不得不说iOS根本就不是正确的平台。

答案 1 :(得分:-2)

您好,只需创建一个Users.create({ uid: uuid(), login: 'login', password: 'password', role: { uid: uuid(), name: 'admin' } }, { include: [{ model: Types.UserRoles, as: 'role' }] }); 设置您的详细信息,最重要的是当您输入UILocalNotification添加Region属性时触发通知,请参阅docs

希望有所帮助