iOS Swift - 使用 NSTimer 为应用程序背景重新加载位置功能不起作用

2023-12-23

我的定位服务有问题。我无法设置一个通过 NSTimer 在后台更新我的位置坐标的函数。这是我来自 appDelegate 的代码:

var locationManager = CLLocationManager()

func applicationDidEnterBackground(application: UIApplication) {

    self.locationManager.delegate = self
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest

    self.theTimer = NSTimer(fireDate: NSDate(), interval: 40, target: self, selector: "handleTimer", userInfo: nil, repeats: true)
    NSRunLoop.currentRunLoop().addTimer(self.theTimer, forMode: NSDefaultRunLoopMode)

}

    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
    var locValue:CLLocationCoordinate2D = manager.location.coordinate
    println("dinBack = \(locValue.latitude) \(locValue.longitude)")
    self.locationManager.stopUpdatingLocation()
}

func handleTimer(){

    println("started")
    self.locationManager.startUpdatingLocation()

}

附言。 - 当然,我已经导入了核心定位。 - 当我回到应用程序时,控制台打印应该在后台打印的内容。


你不能做一个NSTimer当您的应用程序处于后台时,可以像这样工作。NSTimer不是“实时机制”。来自官方文档 https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/#//apple_ref/occ/clm/NSTimer/scheduledTimerWithTimeInterval:target:selector:userInfo:repeats::

定时器与运行循环结合使用。要有效地使用计时器,您应该了解运行循环的运行方式 - 请参阅NS运行循环 https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSRunLoop_Class/index.html#//apple_ref/occ/cl/NSRunLoop and 线程编程指南 https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html#//apple_ref/doc/uid/10000057i。请特别注意,运行循环维护对其计时器的强引用,因此在将计时器添加到运行循环后,您不必维护自己对计时器的强引用。

定时器不是实时机制;仅当已添加计时器的运行循环模式之一正在运行并且能够检查计时器的触发时间是否已过时,它才会触发。由于典型运行循环管理的输入源多种多样,因此定时器时间间隔的有效分辨率被限制在 50-100 毫秒的量级。如果计时器的触发时间发生在长标注期间或者当运行循环处于不监视计时器的模式时,计时器不会触发,直到运行循环下次检查计时器。因此,计时器触发的实际时间可能会比计划的触发时间晚很长一段时间。

Emphasis mine.

重要的是,当您的应用程序处于后台时,您的计时器本来安排的任何运行循环都不会主动运行。

一旦您的应用程序返回前台,此运行循环就会重新启动,发现您的计时器已过期,并将消息发送到选择器。


在 iOS 7 及更高版本中,如果您想在后台执行操作,您可以告诉操作系统您要执行“后台获取”。

要进行设置,我们必须首先告诉操作系统我们想要获取数据的频率,因此didFinishLaunching...,添加以下方法:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    application.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
    return true
}

我们可以在这里传递任何时间间隔(例如,如果我们只想每天检查一次)。但是,我们传入的值仅定义检查之间应经过的最短时间。无法告诉操作系统两次检查之间的最长时间。

现在,我们必须实现当操作系统为我们提供执行后台工作的机会时实际调用的方法:

func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    // do background work
}

我们可以做的whatever我们想要在这个方法中。然而,有两个问题。

  1. 当我们的应用程序在后台时调用此方法。操作系统将我们限制在(我相信)三十秒内。三十秒后,我们的时间到了。
  2. 我们必须调用completionHandler()(否则操作系统会认为我们用了所有的时间)。

The completionHandler传入的内容需要一个枚举,UIBackgroundFetchResult。我们应该通过它.Failed, .NewData, or .NoData,取决于我们的实际结果(这种方法是通常用于检查服务器是否有新数据)。

所以,我们的方法可能如下所示:

func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    // do stuff
    if let _ = error {
        completionHandler(.Failed)
    } else if results.count > 0 {
        completionHandler(.NewData)
    } else {
        completionHandler(.NoData)
    }
}

请记住,我们绝对有zero控制操作系统实际上让我们在后台运行此代码的频率。该操作系统使用多个指标来优化用户体验。

I think如果您的应用程序报告.Failed到完成处理程序,操作系统可能很快就会给你第二次机会,但是如果你滥用.Failed,操作系统可能会将您的应用程序列入黑名单,禁止使用后台获取(Applecould拒绝您的应用程序)。

如果您的应用没有报告.NewData,操作系统将使您的应用程序更少地进行后台工作。我这么说并不是因为我建议你总是报告.NewData。你绝对应该准确地报告。操作系统在安排工作方面非常智能。如果你路过.NewData当没有新数据时,操作系统会让您的应用程序比实际需要更频繁地运行,这会更快地耗尽用户的电池(并可能导致他们完全卸载您的应用程序)。

然而,当您的应用程序开始执行后台工作时,还涉及其他指标。当用户正在积极使用其设备时,操作系统不太可能让任何应用程序执行后台工作,并且更有可能在用户不使用其设备时让应用程序执行后台工作。此外,操作系统更有可能在连接 WiFi 和插入某种充电器时执行后台工作。

操作系统还会查看用户使用您的应用程序的频率,或者他们经常使用它的时间。如果用户每天下午 6 点使用您的应用程序,并且从不在任何其他时间使用您的应用程序,则您的应用程序很可能始终有机会在下午 5:30 到下午 6 点之间(就在用户使用该应用程序之前)执行后台工作,并且never在一天中的任何其他时间。如果用户非常稀有使用您的应用程序时,在后台工作的机会可能需要几天、几周或几个月。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS Swift - 使用 NSTimer 为应用程序背景重新加载位置功能不起作用 的相关文章

  • 记录使用 OpenAL 播放的样本

    我在 iOS 上使用 OpenAL 同时播放 9 个循环 为了使循环 100 同步 它们开始在不同的线程上运行 有关使用 OpenAL 记录正在播放的内容的任何指示 教程 如果我使用不同的线程 我会遇到录制问题吗 iOS 上的 OpenAL
  • iOS 应用程序中的谷歌地图实时交通状况?

    如何使用 google 地图 sdk 或 api 在 ios 应用程序中添加当前交通状况 如下图所示 有 javascript api 但我没有找到任何适用于 iOS 应用程序的解决方案 只需在 iOS SDK 中添加一行代码即可启用或禁用
  • 如何在 WPF 中更改按钮 MouseOver 的背景?

    我的页面上有一个带有以下 XAML 的按钮
  • 如何在文本末尾添加按钮,如 Facebook 的“继续阅读”?

    当状态帖子太长时 Facebook 应用程序会剪切文本并在末尾添加 继续阅读 它如何知道在哪里剪切文本并添加 继续阅读 不仅仅是向 textView 或标签添加按钮 而是如何剪切字符串 例如 在下图中 我将行数限制为 7 我可以在 text
  • 快速将数据从 tableviewcontroller 传递到另一个 tableviewcontroller

    我有一个正在创建的表单 该表单填充有用户输入的文本字段 回答完所有问题后 会弹出一个保存按钮 我在使此表视图控制器将数据传递到新的表视图控制器时遇到问题 我被困住了 不知道该怎么做 import UIKit class TableViewC
  • 即席分发失败

    我在一家大公司工作 正在开发一个适用于 iOS 5 的 iOS 应用程序 分发应用程序的唯一方式是通过临时部署 我拥有自己的服务器已经有一段时间了 由 o2switch 法国托管商 托管 当我开始开发时 我们使用它来部署应用程序以进行 Be
  • just_audio 无法在 ios flutter 上工作未处理的异常:(-11800)操作无法完成

    我正在尝试从它自己的存储库运行 just audio 示例项目https github com ryanheise just audio tree master just audio example https github com rya
  • 使用捏合手势;如何放大用户手指实际“捏”的位置?

    我已经在我的应用程序中的 UIImageView 上实现了 UIPinchGestureRecognizer 但是无论我在图像的哪个位置捏合 它似乎都会放大到同一个位置 有谁知道我如何让它放大到用户实际 捏 的地方 请参阅下面的代码 视图控
  • 将 HTML 字符串加载到 UIWebView 中的延迟

    我在导航控制器中有两个视图控制器 第一个视图控制器有一个带有按钮的菜单 按下此按钮将移动到第二个视图控制器并将 html 字符串加载到 UIWebView 中 没有其他东西被加载到 webview 中 只是一个简单的 NSString 其中
  • Xcode 6.3 Parse SDK 1.7.1 PFTableViewCell 错误“具有不兼容的类型”

    My code override func tableView tableView UITableView cellForRowAtIndexPath indexPath NSIndexPath object PFObject gt PFT
  • iOS 复合谓词

    我正在编写一个具有照片数据库的应用程序 每张照片都有多个与之关联的标签 并且该应用程序有一个带有大量切换的搜索页面 允许用户仅根据他们感兴趣的标签搜索照片 每个标签都存储了integerID 是因为它们对应于外部数据库的 ID 所以我尝试简
  • 如何将 #ifdef DEBUG 添加到 Xcode?

    我的项目中有一些代码永远不应该在发布版本中使用 但在测试时很有用 我想做这样的事情 ifdef DEBUG Run my debugging only code endif 在 Xcode 4 中哪里添加 DEBUG 设置 我尝试将其放入
  • 将多个数组合并为一个数组

    如何将多个数组合并为一个二维数组 鉴于我有以下输入 var arr1 1 2 3 var arr2 a b c var arr3 aa bb cc 我需要这样的输出 1 a aa 2 b bb 1 c cc 我认为你想要的是将三个数组组合成
  • 获取 Swift 子目录中资源的所有 URL

    我正在尝试为 iOS 应用程序的子目录中的所有资源创建 URL 数组 我似乎无法到达正确的路径 即使我不知道名称 我也希望能够检索 URL 即我不想将文件名硬编码到代码中 Below is a screen shot of the hier
  • 子视图控制器旋转方法未被调用

    Summary 我试图将子视图控制器添加到父视图控制器 并让父视图控制器通知子视图控制器旋转事件 但是 旋转消息不会转发到子视图控制器 这是默认行为 为什么这种默认行为没有发生 环境 iOS 7 XCode 5 OSX 10 9 Detai
  • 如何在 XCode5 中将部署目标更改为 5.1.1 [重复]

    这个问题在这里已经有答案了 我正在一个项目中工作 我需要支持 iOS 5 1 1 但在 部署目标 的下拉菜单中我没有 5 1 1 作为选项 我的问题是如何将 iOS 5 1 1 添加为部署目标 我将非常感谢你的帮助 如果您愿意 您可以在框中
  • 更新查询时 ios 中出现“数据库锁定”错误

    我正在使用下面的代码更新查询 using sqlite 但我越来越 database is locked error 我尝试搜索一些 SO 链接 建议关闭数据库 但我再次执行此操作时遇到相同的错误 我已经提到过代码中出现错误的地方 cons
  • 您可以严格泛型类型或为一个参数指定多个类型吗?

    例如我想指定一个类型可能是Integer or String并将其用作特殊类型func我试过typealias但它不会解决这个问题 因为类型别名不能有or参数作为其唯一用途 因此请考虑下面的情况 typealias alis StringP
  • NSURLConnection 是否自动保留从服务器发送的 cookie?

    我从 ios 登录到我的龙卷风后端并发回 secure cookie 我注意到只要验证我设置的 secure cookie 我还可以请求其他信息 NSURLConnection 会保留 cookie 多久 或者关闭应用程序后 cookie
  • Swift 3 和 Xcode8 - init 的使用不明确

    在我安装 Xcode 8 并将项目转换为 Swift 3 之前 以下行没问题 现在转换后看起来像这样 let valueData Data Data bytes UnsafePointer

随机推荐

  • 是什么导致外键不匹配错误?

    我有一个 sqlite 数据库 结构如下 CREATE TABLE IF NOT EXISTS Patient PatientId INTEGER PRIMARY KEY AUTOINCREMENT CREATE TABLE IF NOT
  • 组合关系和关联关系有什么区别?

    在OOP中 类之间的组合 在UML中用实心菱形表示 和关联 在UML中用空心菱形表示 关系有什么区别 我有点困惑 什么是聚合 我可以举一个令人信服的现实例子吗 作品 想象一下 一家软件公司由不同的业务单元 或部门 组成 例如存储BU 网络B
  • AWS CloudFormation:如何在 cloudformation 模板中引用默认/主路由表(在创建 VPC 时创建)?

    我有一个用于创建自定义 VPC 的 CloudFormation 模板 该模板创建以下资源 VPC Internet 网关 将 IGW 连接到 VPC 并创建公共子网 我想将路由 目标 0 0 0 0 0 目标 IGW 添加到作为 VPC
  • 嵌套数组(6 维)的替代方案,内存间隙保留 O(1) 访问

    我正在读取运行具有不同配置的程序的统计数据 假设有 6 种配置 a b f 配置可能不会线性变化 因此如果您将测量值视为表格 则表格中可能存在间隙 问题在于如何在内存中构建这些统计数据 首先想到的是将这些配置读取到动态分配的一个或多个 6
  • 自定义模板加载器 Django

    我正在尝试在 django 中编写一个自定义模板加载器 它为 s3 存储桶中存在的 index html 提供服务 以下是我的加载程序文件 from django conf import settings from django templ
  • 通过包名查找正在运行的进程ID

    我正在编写一个脚本 需要在其中提供应用程序的 PID 我可以通过以下命令列出所有进程及其 PID 并且可以看到我的应用程序的条目 adb shell ps 这给了我一个巨大的进程列表 我需要一个条目 我可以进一步将其提供给另一个命令 因此我
  • 在 iOS 上创建相当于 Android 同步适配器的内容

    我在网络服务器上获取了数据 我想将其下载到 iOS 联系人列表中 是否可以在 iOS 上以编程方式创建一个类似于 Android 同步适配器 的帐户 并且不是默认帐户或 LDAP CardDAV 帐户之一 或者我可以让我的应用程序定期检查网
  • PHP:使用 PEAR 写入 Excel 文件

    我已经安装了PEAR Spreadsheet Excel Writer和 OLE 示例程序已成功执行 但当我尝试读取文件时 它显示垃圾值 我也尝试过 workbook gt setVersion 8 and worksheet gt set
  • Android:使用 KSOAP 解析 XML

    我与我的 Web 服务 SOAP 连接 这是我从 Web 服务收到的 xml 结果 如何在没有 SAX 解析器的情况下解析此结果
  • 如何删除 Chrome 中选择选项的黑色边框?

    如下图所示 当选择选项悬停在镶边上时 会显示黑色边框 我怎样才能去掉边框 下面的代码不起作用 select hover focus outline 0 important 如果您能帮我解决问题 我将不胜感激 Go 镀铬旗帜 https i
  • 无法找到自动发现服务

    我有使用 Exchange Web 服务 EWS 1 1 API 发送电子邮件的代码 如果我使用硬编码参数值也不例外 例如 service AutodiscoverUrl email protected cdn cgi l email pr
  • 可以通过cfldap将缩略图照片注入AD吗?

    有谁有办法将用户的缩略图注入 AD 中吗 当我通过 cfldap 获取数据时 我可以看到缩略图的条目 但 我的记录 的条目 手动附加了照片 在该字段中有一个空字符串 有什么建议么 谢谢 克里斯 我不相信有什么办法可以做到这一点 我一直无法弄
  • 枚举设计决策的恒定特定方法

    这更多是一个设计问题 首先 我有一个枚举 enum WageType MONTHLY public int getWageRatePerUnit return 60000 public boolean isPaymentTime DateT
  • 没有 HTML 标签的 XSS

    如果我的输入不允许 字符 是否有可能进行 XSS 攻击 Example I enter text 但如果我删除 脚本就不是文本 I enter script alert this script text 是的 这仍然是可能的 例如假设您的网
  • 如何使用调试器处理任务中的异常?

    我学MSDN 上的这篇文章 http msdn microsoft com en us library dd537614 aspx 以及有关此主题的一些问题 答案 但无法弄清楚为什么下面的代码不起作用 在示例控制台应用程序中 根据 MSDN
  • Android 应用程序上下文是否会被破坏?

    我使用 Android 应用程序的应用程序上下文作为应用程序 当前状态 信息的存储区域 我发现在现场 有些情况下此信息在某些人的设备上消失 导致各种 NullPointerExceptions 因为我希望当应用程序恢复并开始重建必要的活动时
  • 如何将子进程的输出重定向到文件

    我有以下 python 脚本 import shlex import subprocess from datetime import datetime timedelta import os import sys import xml et
  • Python 预提交单元测试失败

    I wish pre commit https pre commit com在提交我的代码之前运行测试 命令python m unittest discover正在命令行中工作 D project dir gt python m unitt
  • 从连接字符串获取用户名和密码的正确方法? [复制]

    这个问题在这里已经有答案了 我有一个像这样的连接字符串 SERVER localhost DATABASE tree UID root PASSWORD branch Min Pool Size 0 Max Pool Size 200 如何
  • iOS Swift - 使用 NSTimer 为应用程序背景重新加载位置功能不起作用

    我的定位服务有问题 我无法设置一个通过 NSTimer 在后台更新我的位置坐标的函数 这是我来自 appDelegate 的代码 var locationManager CLLocationManager func applicationD