如何在 iOS 应用程序的后台发出间歇性 HTTP POST 请求 - Swift

Posted

技术标签:

【中文标题】如何在 iOS 应用程序的后台发出间歇性 HTTP POST 请求 - Swift【英文标题】:How to make intermitent HTTP POST requests in the background of an iOS app - Swift 【发布时间】:2018-03-07 23:44:35 【问题描述】:

您好,我正在制作一个向 Web 应用程序发送 POST 位置更新请求的应用程序。我有一个名为 locationUpdate 的函数,一旦应用程序处于后台,我想间歇性地调用它,但是我还没有找到方法。

我已经设置了“始终允许位置”等所有基本功能。由于 AppDelegate 文件中的代码,该应用当前在进入后台时会立即发出一个 HTTP POST 请求:

 func applicationDidEnterBackground(_ application: UIApplication) 

    sendLocation.determineCurrentLocation()

我在 AppDelegate 中也有这个,因为我在一些堆栈溢出答案中看到了它:

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
    UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
    return true

因此,除了应用程序不会多次调用 sendLocation.determineCurrentLocation()(发出 POST 请求的函数)之外,这一切都是在应用程序关闭时。

谁能告诉我如何实现 sendLocation 函数的间歇调用?

已编辑以显示我的 locationManager:

 func determineCurrentLocation()

    locationManager.delegate = self
    locationManager.allowsBackgroundLocationUpdates=true
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()


    if CLLocationManager.locationServicesEnabled()
        DispatchQueue.main.async 

            self.locationManager.requestLocation()
        

    
    else if (!CLLocationManager.locationServicesEnabled())
    
        print("You need to enable location services to use this app")

    





func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
    locationManager.stopUpdatingLocation()
    userLocation = locations[0] as CLLocation
    locationStruct.latitude=userLocation?.coordinate.latitude
    locationStruct.longitude=userLocation?.coordinate.longitude



    print(userLocation?.coordinate.latitude)
    print(userLocation?.coordinate.longitude)

    sendLocationPost()



【问题讨论】:

你需要在didUpdateLocations发帖 @Paulw11 你能详细说明你的意思吗?当我调用 sendLocation.determineCurrentLocation() 时,该函数调用 didUpdateLocations() 您需要获得后台位置权限,开启重要的位置更新并致电startUpdatingLocation,并在您的位置管理器上启用后台更新。然后,您将在后台收到对 didUpdateLocations 的呼叫。您需要仔细考虑您要求的准确度,因为频繁的高精度位置更新会显着影响电池寿命。 @Paulw11 我编辑了我的答案以包括我的位置经理,因为我认为我已经完成了你提到的所有事情,但它仍然不起作用。你是说在我的 AppDelegates 当前状态下它应该定期更新吗?因为除非我向 AppDelegate 本身添加一些东西,否则我无法看到它会如何做到这一点。 您需要致电startUpdatingLocation 而不是requestLocation - requestLocation 只提供一次性更新。 startUpdatingLocation 会持续更新。您可能希望在 didUpdateLocations 中添加一些代码,以便每隔几分钟更新一次服务器,因为如果用户移动,您的设置将每秒提供一次位置更新 【参考方案1】:

除非您将您的应用设置为逐步导航应用并请求获得在后台获取位置更新的权限,否则您将无法执行您正在尝试执行的操作。

应用在被暂停之前只能在后台停留很短的时间。

您可以通过beginBackgroundTask(expirationHandler:) 呼叫请求更多后台时间,但这通常限制为最多 3 分钟的后台时间。 (搜索该方法以查找有关它的文档。)

仅允许某些类型的应用在后台无限期运行。 (Turn-by-turn 导航应用程序和流媒体音乐应用程序。)您必须设置 info.plist 以声明您的应用程序是这些类型的应用程序之一。这在 Xcode 附带的 ios 文档中有记录。

编辑:

正如 Paul 在他的评论中指出的那样,您可以请求“始终”位置更新许可,然后请求重要的位置更改更新,尽管这些都相当粗糙,并且您无法控制位置更新之间的时间间隔(并且赢得了'直到操作系统确定用户已经移动了很长的距离,才获得任何更新。)

【讨论】:

你不需要成为一个转弯导航应用;您只需要“始终”位置权限,并启用后台位置以及重要的位置更新。这会影响电池寿命,因此需要明智地选择精度设置。 重要的位置更新为您提供了相当粗略的位置更新粒度,除非您移动到足以触发更新的程度,否则您将不会获得任何更新。 你必须将两者结合起来;如果您只使用startUpdatingLocation,则后台更新会在几分钟后停止。如果您同时使用重要的位置更新 startUpdatingLocation,那么您将无限期地获得高精度的后台更新 真的吗?如果这是真的,那将是一个非常酷的技巧,而且我敢打赌,Apple 不会打算这样做。 Paul,听起来您应该将解决方案发布为您自己的答案,因为您似乎有一个完整的解决方案。

以上是关于如何在 iOS 应用程序的后台发出间歇性 HTTP POST 请求 - Swift的主要内容,如果未能解决你的问题,请参考以下文章

如何在后台应用程序时从 JavaScript 发出通知/警报 - PhoneGap iPhone/iOS

iPhone 音量间歇性/突然增加或减少

iOS - 在后台推送通知上刷新数据(发出 Api 请求)

如何在 React Native 应用程序的 iOS 后台运行 socket.io?

套接字 IO 日志记录:在 Swift/iOS 中得到消息 3

Laravel 间歇性注销