每隔几秒调用获取当前坐标而不使用 NSTimer

2023-12-11

我知道如何用 NSTimer 做到这一点,但我不想每隔几秒就在没有计时器的情况下获取当前的 iPhone 坐标。我无法使用计时器,因为我在应用程序处于后台时获取坐标。
我尝试过一些方法,但每秒都会调用一次,而不是每 10 秒调用一次,因为我不想这样做。
我在这里做错了什么?

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    CLLocation *loc = [locations objectAtIndex:0];

    NSDate* eventDate = loc.timestamp;
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
    if (howRecent < 10)
    {
        CLLocation* location = [locations lastObject];

        double lat = location.coordinate.latitude;
        double lng = location.coordinate.longitude;
        NSLog(@"lat:%f lng:%f", lat, lng);

首先尝试每 10 秒执行一次后台任务,但如果我在这里执行任何操作,则不知道在哪里设置时间:

- (void)applicationDidEnterBackground:(UIApplication *)application
{

    backgroundTask = [application beginBackgroundTaskWithExpirationHandler: ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            if (backgroundTask != UIBackgroundTaskInvalid)
            {
                [application endBackgroundTask:backgroundTask];
                backgroundTask = UIBackgroundTaskInvalid;
            }
        });
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        _pendingLocationsTimer = [NSTimer timerWithTimeInterval:_pendingLocationsTimerDuration
                                                         target:self
                                                       selector:@selector(_acceptBestAvailableLocation:)
                                                       userInfo:nil repeats:NO];


        NSRunLoop *loop = [NSRunLoop currentRunLoop];
        [loop addTimer:_pendingLocationsTimer forMode:NSRunLoopCommonModes];
        [loop run];

        dispatch_async(dispatch_get_main_queue(), ^{
            if (backgroundTask != UIBackgroundTaskInvalid)
            {
                // if you don't call endBackgroundTask, the OS will exit your app.
                [application endBackgroundTask:backgroundTask];
                backgroundTask = UIBackgroundTaskInvalid;
            }
        });
    });

}

我在后台状态下遇到了计时器问题。无法保证您将有一个活动的运行循环,因此计时器永远不会触发,直到您返回前台。我所做的是:

 NSRunLoop *loop = [NSRunLoop currentRunLoop];
 [loop addTimer:myTimer forMode:NSRunLoopCommonModes];
 [loop run];

我在BackgroundIdentifierTask开始和结束调用内的后台线程上执行此操作。我并不完全相信我的所有内容都是正确的,事实上,我查看了您的问题,看看答案是否可以帮助我确认或纠正我对要求的理解。

如果您想持续监控位置,还必须在默认 info.pList 中启用位置服务的后台模式。如果您只是使用 importantLocationUpdates 或地理围栏,则不需要这样做。

我的计时器确实工作并且按照预期的方式启动。在此之前它并不能可靠地工作。

除此之外,最好不要使用计时器。使用上面的代码,只需更改位置管理器的属性即可。所需的准确性和距离过滤器是可减少管理器发送新位置通知频率的属性。

请参阅我刚刚在 github 上发布的我自己的位置处理程序的示例,供任何感兴趣的人使用:

http://github.com/dsdavids/TTLocationHandler

我不认为计时器是关键。如果您将 TTLocationHandler 类删除到项目中,请查看 LMViewController 类如何响应处理程序。

NSNotificationCenter *defaultNotificatoinCenter = [NSNotificationCenter defaultCenter];
[defaultNotificatoinCenter addObserver:self selector:@selector(handleLocationUpdate) name:LocationHandlerDidUpdateLocation object:nil];

将控制器设置为观察者。每当处理程序确定已接收到新的或更准确的位置时,就会调用handleLocationUpdate。

当调用 startUpdating 时,locationManager 将发送新的位置,一开始每秒发送多个位置,并且在移动时发送新位置,直到设备静止并达到准确度。这TTL位置处理程序正在过滤这些事件并仅根据配置根据需要发送通知。

请注意,在 -(id)init 中,_recencyThreshold 设置为 60。因此,我们每 60 秒保存或显示一个 pin。如果您想要更小的间隔,请更改此值。

事实上,TTLocationHandler 在后台时总是会切换到显着的位置变化,除非设备已插入电源。如果使用电池供电,则更新之间的间隔不会那么小,但您会获得更新。

我添加了一个属性来配置连续后台更新而无需付费。

TTLocationHandler 的使用示例

我在存储库中添加了另一个类,以展示我将如何使用我的处理程序实现您的目标。我添加了 LMPinTracker 类,您可以在其中添加用于存储和上传位置的代码。

看看LMAppDelegate.m

    self.pinTracker.uploadInterval = 30.00;

将其更改为您想要的上传到服务器之间的任何间隔。

    self.sharedLocationHandler.recencyThreshold = 5.0;

将 5.0 更改为您想要的存储位置之间的最短时间。它并不准确,会因行进速率和信号强度而异,但基本上,在 x 秒间隔后,它会认为存储的位置已过时,并尝试获取另一个准确的位置。

现在查看 LMPinTracker.m 文件
将数据存储代码放在这两行之后:

    // Store the location into your sqlite database here
    NSLog(@"Received location info: %@ \n Ready for store to database",lastKnowLocationInfo);

将您的网络上传代码放在此评论之后:

    // Do your upload to web operations here

Comments

这应该可以完成您想要做的事情,同时仍然尊重用户电池和后台操作。

基本上,当用户旅行时,更新将按照您设置的时间间隔持续进行。
当用户静止时,不会有更新,也不会发生重大活动。
当没有新的活动时,您也不会上传到网络。
当用户再次开始移动时,日志记录和更新将恢复。

如果我是你,想要进一步完善它,我会考虑设置一个区域和时间来检查。如果用户长时间保持静止,则仅切换到 importantLocationUpdates。然后,您将关闭定位服务,但当用户再次开始使用时,您将重新启动定位服务。

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

每隔几秒调用获取当前坐标而不使用 NSTimer 的相关文章

  • 在 iOS Safari 上滚动后锚点失去点击能力

    使用它来获取点击次数 nav li a click function event event preventDefault target this attr href replace goToByScroll target 这是滚动功能 f
  • 如何计算CLLocationDistance的中心坐标

    我想计算我的位置和一些注释之间的中心点 到目前为止我已经这样做了 CLLocation myLoc self locMgr location MKPointAnnotation middleAnnotation locationV anno
  • WKWebView在后台,几个奇怪的断言

    我想找出iOS中当前浏览器的userAgent 所以在 Xcode 创建的默认项目中我添加了 import ViewController h import
  • 未找到符号,预计出现在平面命名空间 ObjC++ 中

    我可能遇到了一个简单的问题 但是在编译过程中没有任何信息错误或警告来提醒我出了什么问题 我有一个 Objective C 应用程序 其中包含 C 主文件和 ObjC 头文件 它构建得很好 但是当运行时 它会给出以下错误消息 Dyld Err
  • 为什么我无法更改 UIBarButtonItem 的标题?

    我想改变UIBarButtonItem s title 但这段代码不起作用 void viewDidLoad self smay void smay AppDelegate apd AppDelegate UIApplication sha
  • iOS5 和 Facebook API

    我想将我的应用程序与 Facebook 集成并从 github 下载 Facebook ios sdk 但是 该 sdk 适用于 Xcode 4 0 代码库 我正在使用 Xcode 4 2 for iOS 5 beta 5 应用程序 是否有
  • 在两个可移动 uiview 之间画线

    我有一个带有节点的 滚动视图 UIViews 可以拖动 我正在尝试在选定的之间绘制边缘UIViews使用 calayer 但我不知道当视图位置发生变化时如何重新绘制线条 In my viewControllerI 类在节点数组中添加第一个和
  • 如何在 iPad 应用程序上禁用横向方向?

    我创建了一个全新的单视图 iOS 通用 Swift 应用程序 然后 我在应用程序设置中取消选中 横向左 和 横向右 我在 iPhone 上运行了它 万岁 无论我如何旋转手机 它都会保持纵向模式 然后我在 iPad 上运行它 它会旋转到任何内
  • 使用什么来移动 UIView self.frame 或 self.transform 属性?

    这个问题我有点困惑 我知道我可以改变观点self frame origin 但我发现有一个名为 变换 的属性 我认为这是用于在屏幕上移动我的视图等 也许我有点不明白 所以我想知道 我必须使用哪个房产来搬家UIView 或者它的子类 另一个类
  • 如何将 SCNPlane 颜色更改为透明颜色

    我正在开发一个 ARKit 项目 在水平面上点击时需要波纹动画效果 为此 我采用了 UIView 对象并将其作为 SCNPlane 对象材料的内容传递 我已将波纹动画添加到 UIView 对象 一切正常 但我无法将 SCNPlane 颜色更
  • UIView 周围的虚线边框

    如何在周围添加虚线边框UIView 像这样的东西 如果您喜欢子层 还有另一种方法 在您的自定义视图的 init 中 输入以下内容 border 是 ivar border CAShapeLayer layer border strokeCo
  • 双击并滑动/拖动手指以放大/缩小

    如果有人使用过 iOS 版谷歌地图应用程序 那么它有一个很棒的功能 可以用一根手指放大 缩小 双击 uiscrollview 然后立即向上或向下滑动手指以放大 缩小 有谁知道这是如何实现的 谷歌发布了任何片段吗 我将此功能添加到我的 UIS
  • 旋转 GPUImageTiltShiftFilter - GPUImage

    我想要一个非水平 GPUImageTiltShiftFilter 旋转 我想将其旋转到任意旋转角度 我还希望过滤器速度快 可以通过带有 UIRotationGestureRecongizer 的 UI 进行旋转 我该怎么做呢 啊 想通了 不
  • 应用程序仅启用纵向,但 UIImagePickerController 在 iOS6 中旋转

    请注意 下面的答案 不适用于 iOS6 所以我仍然需要答案 我的应用程序仅启用纵向模式 但是 如果我将 UIImagePickerController 作为子视图嵌入其中 并旋转设备 则顶部和底部栏将保持在同一位置 但 UIImagePic
  • 播放循环声音的最简单方法是什么?

    在 iPhone 应用程序中播放循环声音的最简单方法是什么 可能最简单的解决方案是使用AVA音频播放器 http developer apple com library ios DOCUMENTATION AVFoundation Refe
  • ObjectiveC 和 JavaScriptCore:使用这种调用回调的方法会导致内存问题吗?

    免责声明 这是一篇很长的文章 但对于那些努力使用新的 ObjectiveC JavascriptCore 框架并在 ObjC 和 JS 之间进行异步编码的人来说可能非常有价值 您好 我对 Objective C 非常陌生 正在将 javas
  • 使用 MPMoviePlayerViewController 时的 iPad 旋转错误

    问题摘要 使用 MPMoviePlayerViewController 播放视频时更改 iPad 设备或模拟器的方向会导致视频播放器关闭时旋转状态不一致 这是 iPad SDK 3 2 中的一个已知错误 记录于http www openra
  • 游戏中心玩家显示名称在沙盒中始终为“我”

    我使用用户的游戏中心显示名称和玩家 ID 来维护他们在我的服务器上的个人资料 当我进行测试时 一切似乎都正确执行 但我的沙箱帐户的用户显示名称显示为 Me 而不是附加到我的帐户的显示名称 Billybobbo 这应该在沙盒模式下发生吗 Co
  • 使用自定义格式将字符串转换为 NSDate [重复]

    这个问题在这里已经有答案了 可能的重复 NSString 到 NSDate https stackoverflow com questions 1353081 nsstring to nsdate iPhone 如何将 yyyyMMddTh
  • 如何从地址簿中获取一个人的电话号码?

    我想做的就是让用户从地址簿中选择一个号码 我在这个问题中找到了代码 如何从地址簿联系人获取电话号码 iphone sdk https stackoverflow com questions 286207 how to get a phone

随机推荐

  • web2py 网址验证器

    在 web2by 构建的缩短器中 我想首先验证 url 如果无效 则返回到第一页并显示错误消息 这是我在控制器 mvc arch 中的代码 但我不明白出了什么问题 import urllib def index return dict de
  • Woocommerce 变体产品价格显示默认值

    我的商店设置了产品变体 目前在产品缩略图页面 即类别和过滤页面 上显示 从 xx 到 xx 当进入单个产品页面时 变体被选择为变体价格显示 我将某些属性设置为默认值 这是我希望在类别页面上显示的价格 标准尺寸和成本 但我不知道是否可能或将其
  • Python 错误:“ValueError:需要超过 1 个值才能解压”

    在 Python 中 当我运行这段代码时 from sys import argv script user name argv prompt gt print Hi s I m the s script user name script 我
  • 将单选按钮值插入 mysql

    我创建了一个测试表单只是为了尝试将我的单选按钮值发送到 mysql 我现在遇到了问题 下面的代码只是一个测试 我希望单选按钮提交该值 但事实并非如此 table width 300 border 0 align center cellpad
  • Flutter/Dart 中的 SOAP 请求

    我需要使用 Flutter 向 NET Webservice WSDL 发出 SOAP 请求 该网络服务有一个基本的身份验证 用户 密码 和一些带有预定义信封的服务 所以我尝试创建一个 SOAP 信封 String requestBody
  • 多次购买时会发生什么 - 非续订订阅应用内购买

    我正在实现一个包含应用内购买功能的示例 订阅是非续订类型 自动续费订阅时 如果用户已经购买过 且在有效期内再次尝试购买 iTunes会提示 您已经订阅了购买 并且不会进一步进行 用户可以使用应用程序恢复功能恢复其订阅 但对于非续订订阅类型
  • 是否可以在 FullCalendar 中交替行背景颜色?

    我对 fc agenda slot tr 应用了奇数 偶数类 但问题是左 右 单元格 边框位于下面的 fc agenda days 表上 因此当我设置背景时它不会显示在 fc agenda slot tr 上 FullCalendar 本身
  • CakePHP 使用 saveAll:如何使用 HABTM 链接记录保存额外数据?

    我已经能够使用 CakePHP 的 saveAll 方法同时创建 成员 并将它们注册到 事件 中 创建 HABTM 链接记录 这非常棒 例如 此代码创建两个新的 Members 并将每个人的记录添加到 EventsMember 表中 将它们
  • Android 数字选择器对话框 [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 有没有人有任何对话框允许用户选择一定范围内的数字 这似乎是一个相当普遍的需求 但我找不到它的通用对话框 而且我不想花时间创建自己的对话框 有什么帮助吗 我知道两年多过去了 但答案仍然
  • ruby 如何允许方法和类同名?

    我碰巧正在用 ruby 开发 Singleton 类 只记得它的工作方式工厂女工 他们解决了这个问题 所以你可以同时使用漫长的路 Factory create and 捷径 Factory 我想了想 很好奇他们是如何上课的Factory也表
  • Cygwin编码困难

    不确定这是否是一个编程问题 我开始怀疑是这样 但后来我在 Windows 控制台而不是 Cygwin 控制台中运行了有问题的 Java 程序 可执行 jar 并且它运行良好 输出重音良好 重音输入接受良好 因此以下内容仅适用于 Cygwin
  • kernel.h中min宏中的“(void)(&_min1 == &_min2)”的作用是什么?

    In kernel h分钟定义为 define min x y typeof x min1 x typeof y min2 y void min1 min2 min1 lt min2 min1 min2 我不明白那条线是什么 void mi
  • 在 SimpleInjector 中使用 IAuthorizationFilter 进行依赖注入

    我有课PermissionFilter实现IAuthorizationFilter from System Web Mvc 由于它具有已映射的依赖项 因此我想使用 SimpleInjector 来提供它 我正在这样做 与 Ninject 合
  • 嵌套 ES6 类?

    似乎可以将类嵌套在构造函数中 然后可以从类中的任何位置实例化 这是官方的吗 编辑 例如 class C constructor class D constructor method var a new D works fine var a
  • 跨域AJAX withCredentials,PHP返回标头内容长度,但没有内容

    我正在尝试从一个域上的页面向另一个域上的 PHP 服务器发送跨域请求 没有凭据 一切都可以正常工作 我需要一个会话 但一旦添加凭据 它就不起作用 这是JS代码 var xhr new XMLHttpRequest xhr open GET
  • 使用 $_GET 字符串传递换行符

    我必须将字符串传递给表单 我想按以下方式混合使用 GET 和 POST
  • ViewBox 内的 WPF TextBox 在调整大小时丢失光标

    我在视图框中有一个文本框 当我尝试调整窗口大小时 文本框大小和字体大小会缩放 但如果我尝试聚焦文本框并尝试使用键盘在文本框中移动光标 有时光标会消失 有没有办法始终显示光标 请参考下面的代码 其中 ViewBox 内有一个 TextBox
  • boost/archive/binary_woarchive.hpp 和/或 boost/archive/binary_wiarchive.hpp 的序列化示例?

    我试图找到一个很好的例子来说明如何使用 boost 序列化内容的这些二进制宽字符版本 我拼凑了一些代码来尝试让它工作 但不幸的是 在尝试编译它时 我遇到了链接器错误 这是我的代码 以防我做任何明显错误的事情 include
  • 处理子例程中重复出现的 VBA 错误

    我被困在我有解决方法的事情上 但这让我烦恼我没有关于如何解决使用问题的直接答案On Error Goto对于重复出现的错误 我的问题本质上是一样的正如这个 但是提供的答案是OP整体方法的替代方案 而不是如何处理具体问题 我在下面简化了一个例
  • 每隔几秒调用获取当前坐标而不使用 NSTimer

    我知道如何用 NSTimer 做到这一点 但我不想每隔几秒就在没有计时器的情况下获取当前的 iPhone 坐标 我无法使用计时器 因为我在应用程序处于后台时获取坐标 我尝试过一些方法 但每秒都会调用一次 而不是每 10 秒调用一次 因为我不