【问题标题】:Dynamic location based local notifications Swift iOS基于动态位置的本地通知 Swift iOS
【发布时间】:2016-12-29 15:02:45
【问题描述】:

我正在尝试在用户接近停靠点时获取一些公共汽车的到达时间,我已经测试以确保通过发送基本本地通知来正确触发这些区域,并且我还测试了我的 Web 服务调用以确保它工作正常。

但是我很难获取信息然后发送通知。

这是我的代码:

    var bgTask: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier()

    bgTask = UIApplication.shared().beginBackgroundTask {

        self.webService?.getStopEstimates(routeStopIds: stopRouteIdSet, routeNameDict: routeNameDict, completion: { (result) in

            if result == "error" {
                return
            }

            let notification = UILocalNotification()
            notification.fireDate = Date(timeIntervalSinceNow: 1)
            notification.alertTitle = region.identifier + " Stop Details"
            notification.alertBody = result
            notification.soundName = UILocalNotificationDefaultSoundName
            UIApplication.shared().scheduleLocalNotification(notification)
        })

        UIApplication.shared().endBackgroundTask(bgTask)
    }

有人知道为什么它可能没有发送吗?我启用了后台获取和定位服务。这是里面didEnterRegion

【问题讨论】:

  • 鉴于您使用的是 Swift 3,因此知道有一个新的 UserNotifications 框架。
  • 会不会是您忘记在基金申请中注册通知(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?)。注册码:let notificationSettings = UIUserNotificationSettings(types: .alert, categories: nil) application.registerUserNotificationSettings(notificationSettings)
  • 你是如何测试的?在 Xcode 中?添加一些日志记录以检查请求是否已发送/接收。有什么错误吗?

标签: ios swift core-location uilocalnotification


【解决方案1】:

我做了同样的事情(当用户接近有折扣的商店时,他/她会收到通知)。

首先,如果可以的话,我建议您下载所有数据并将它们保存在 Core Data 或 SQLite 上。

第二次查看重大位置变化here。如果您正在移动,它将在后台每 500 米更新一次您的位置,并且会节省大量电池而不是 didUpdateLocation。

第三次使用 SLC 后,在每次调用时,从您的 Core Data 或 SQLite 中获取您当前位置最近的 20 个位置并将它们添加以进行监控(使用Haversine 计算与您当前位置的所有点距离,然后获取最近的 20 个)。每次调用 SCL 时更新您监控的区域(如果无法离线保存数据,我建议您在此处的 Web 服务上发送请求。理想的情况是您将位置发送到您的 Web 服务,它会回复返回最近的点。然后添加它们进行监控)

当 didEnterRegion 被调用时,请确保您已下载数据,然后创建本地通知。

如果您需要更多详细信息,请告诉我

PS。请记住,如果您的应用消耗大量资源,系统可能会(在后台)终止您的应用。在这种情况下,您必须重新初始化提取和显示数据所需的一切(网络请求、位置管理器等)。您可以检测到应用程序由于 AppDelegate 的 didFinisingLaunchingWithOptions 中的位置事件而重新启动:

  if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {}

【讨论】:

    【解决方案2】:

    检查this example on GitHub,因为我认为您的问题是您如何处理后台任务。如果 Web 服务调用时间过长,后台任务将失效。我不知道您对 ObjC 了解多少,但在上面的示例中,您会发现一个 BackgroundTaskManager 类为您处理。

    你应该确保的事情是:

    1. 目标设置中的后台获取(后台模式部分)是 开。
    2. 您已请求并获得“始终”授权(在 plist 中)
    3. 目标设置(后台模式部分)中的位置更新已开启。
    4. 在应用程序委托的 appDidFinishLaunching 中注册用户通知。
    5. 如果服务时间过长,则更新过期的后台任务。

    如果您的应用在后台调用startUpdatingLocation,CoreLocation 仍会通过启动您的应用的位置更新来响应,但系统将不再为您保留断言,您的应用将暂停一次在后台花费了允许的时间。这个时间(目前)是10秒。但实际上您的应用程序现在已暂停,无法再接收更新。有一种方法可以通过使用 beginBackgroundTaskWithExpirationHandler: read more about it in Apple's CoreLocation Documentation 将此持续时间延长到(目前)最多 3 分钟

    这个延长的时间是否足够取决于你的应用。

    对于您的用例,重大位置更改服务非常有效。 您可以在您的应用程序处于前台时启动位置更新,并在您的应用程序处于后台时延迟位置更新。你可以also read Apple's documentation about Significant Location Change

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多