【问题标题】:How can I make iOS background app notify based on location info如何根据位置信息使 iOS 后台应用程序通知
【发布时间】:2015-10-29 05:43:59
【问题描述】:

我正在尝试在 iOS 上实现基于位置的导航应用。我会在口袋里放一个设备,并希望它根据位置信息在满足条件时发出通知,例如当您在街道上转弯时,Google 地图导航会发出通知。

我认为我可以通过 CoreLocation 和本地通知来实现。

这是我所做的、期望的和实际得到的。

  • OS X El Capitan 10.11.1 上的 XCode 版本 7.1 (7B91b)
  • 在 Xcode 中,文件 -> 新建 -> 项目 -> iOS 应用程序 -> 单视图应用程序
  • 将 CoreLocation 框架添加到项目中
  • 启用“位置更新”后台模式
  • 将值为“hello”的 NSLocationAlwaysUsageDescription 键添加到 info.plist
  • 保持 ViewController.swift 不变
  • 如下编辑 AppDelegate.swift;

    import UIKit
    import CoreLocation
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {
        var window: UIWindow?
        lazy var locationManager: CLLocationManager! = {
            let manager = CLLocationManager()
            manager.desiredAccuracy = kCLLocationAccuracyBest
            manager.pausesLocationUpdatesAutomatically = false
            manager.delegate = self
            manager.requestAlwaysAuthorization()
            return manager
        }()
        var lastNotifictionDate = NSDate()
    
        func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
            let settings = UIUserNotificationSettings(forTypes: [.Alert], categories: nil)
            UIApplication.sharedApplication().registerUserNotificationSettings(settings)
            locationManager.startUpdatingLocation()
            return true
        }
    
        func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            // Do something interesting.
            // I make this function return immediately until 10sec passed after previous notification.
            let now = NSDate()
            if lastNotifictionDate.dateByAddingTimeInterval(10).compare(now) == .OrderedDescending {
                //NSLog("Not yet")
                return
            }
            //NSLog("It's time")
            lastNotifictionDate = now
    
            // Fire local notification, without sound configured for simplicity.
            let notification = UILocalNotification()
            notification.alertBody = "Hello"
            UIApplication.sharedApplication().presentLocalNotificationNow(notification)
        }
    
        // ... other methods are untouched ...
    }
    

该应用程序如我所料在模拟器上运行,即;

  • 在 iPhone 5 Simulator 中运行应用并允许定位和通知服务
  • 按主页按钮 (Shift-Command-H)。
  • 在模拟器菜单中,Debug -> Location -> Free drive
  • 应用每 10 秒显示一次本地通知提醒

该应用在我的设备上运行不同,iPhone 5 和 iOS 9.1;

  • 通过 Xcode 运行应用并允许定位和通知服务
  • 按下主页按钮
  • 设备不会在主屏幕或通知中心显示通知警报。
  • 然后,我点击设备上的应用图标,将应用带到前台,打开通知中心,发现两条通知。如果我等待 50 秒,我预计会新出现 5 条通知,但没有新出现通知。

我了解模拟器的行为与实际设备不同。例如,模拟器在后台显示 NSLog() 和 print() 输出在控制台上,而实际设备不会。

我想我没有为设备配置一些东西,或者我试图以不可行的方式做,但我找不到它是什么。您能告诉我哪里出了问题以及如何解决吗?

【问题讨论】:

  • 那么你确定你真的在设备上接收后台更新吗?
  • @MitchellCurrie 是的,我通过在 locationManager 函数中添加 dates.append(NSDate()) 验证我正在后台接收位置更新。
  • 所以问题是试图安排本地通知?
  • @MitchellCurrie 是的。我应该澄清一下。
  • 你能从主线程在前台成功调度吗?还要检查设备上的权限以确保它被允许

标签: ios swift


【解决方案1】:

将 CLLocationManager 的 allowBackgroundLocationUpdates 设置为 true 解决了我的问题。

manager.allowBackgroundLocationupdates = true

如果为 false(默认),则更新会在暂停时停止。更新发生在前台或后台时。

【讨论】:

    猜你喜欢
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    • 1970-01-01
    • 2017-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多