CLLocationManager protectedRegions (NSSet) 不正确,或者可能是其他什么?

2023-12-26

我想在每次用户从商店数组中传递一个商店时进行检查,我有超过 20 个商店,因此我编写了一个函数来查找离用户位置最近的 20 个商店并监视它们。名单更新中locationManager: didUpdateLocations,我还将旧的 20 个监控区域替换为新的 20 个最近的商店位置。

问题是locationManager: didEnterRegion当用户进入某个区域时不会定期调用。

我还注意到,当我检查locationManager.monitoredRegions NSSet由于某种原因,那里的区域是错误的(我用它检查过if句子,所以也许它们是正确的,只是更短?)。

如果有人可以检查我的代码并可能注意到我做错了什么,这真的会对我有帮助!

My code:

监视器LocationViewController.m(滚动查看完整代码):

-(void)getStoresArrays:(NSNotification*)notification
{
    //Fetching "allStoresArray"(NSArray of all the stores sent from another class using NSNotificationCenter) and adding it to "allStores"(NSMutableArray)
    NSDictionary *storesCategoriesArrays=[notification userInfo];
    self.allStores=[storesCategoriesArrays objectForKey:@"allStoresArray"];

    //Calling "locationChangeHandler" for monitoring
    [self locationChangeHandler];
}

#pragma mark - CLLocationDelegate methods
//Being called when user's location updated
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    //If "allStores"(NSMutableArray) isn't nil - calling "locationChangeHandler" to update monitoring
    if (self.allStores!=nil) {
        [self locationChangeHandler];
    }
}
//Being called when user enters a monitored region
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"Entered");
}

#pragma mark - Closest stores sorting methods
//Sorting closest stores to the user's location and adding the 20 closest store to "twentyClosestStores"(NSMutableArray)
-(void)sortClosestStores
{
    //Sorting "allStores"(NSMutableArray) from the closest "Store" to the furthest.
    [self.allStores sortUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        //Creating "location1"(CLLocation) and "location2"(CLLocation) and initializing each with "obj1"(id) and "obj2"(id) coordinates
        CLLocation *location1=[[CLLocation alloc] initWithLatitude:((Store*)obj1).geoPoint.latitude longitude:((Store*)obj1).geoPoint.longitude];
        CLLocation *location2=[[CLLocation alloc] initWithLatitude:((Store*)obj2).geoPoint.latitude longitude:((Store*)obj2).geoPoint.longitude];

        //Creating "dist1"(float) and setting its value to the distance between "location1"(CLLocation) and the user's location
        float dist1 =[location1 distanceFromLocation:self.locationManager.location];
        //Creating "dist2"(float) and setting its value to the distance between "location2"(CLLocation) and the user's location
        float dist2 = [location2 distanceFromLocation:self.locationManager.location];

        //If the distances are equal - the order will stay the same
        if (dist1 == dist2) {
            return NSOrderedSame;
        }
        else if (dist1 < dist2) { //If "dist1"(float) is smaller than "dist2"(float) - "dist2"(float) will be before "dist1" in the array
            return NSOrderedAscending;
        }
        else { //else - "dist2"(float) will be before "dist1" in the array
            return NSOrderedDescending;
        }
    }];

    //If "twentyClosestStores"(NSMutableArray) is nil
    if (self.twentyClosestStores==nil) {
        //Initializing "twentyClosestStores"(NSMutableArray)
        self.twentyClosestStores=[NSMutableArray array];
    }

    //If "previousTwentyStores"(NSMutableArray) is nil
    if (self.previousTwentyStores==nil) {
        //Initializing "previousTwentyStores"(NSMutableArray)
        self.previousTwentyStores=[NSMutableArray array];
    }
    //Setting "previousTwentyStores"(NSMutableArray) to "twentyClosestStores"(NSMutableArray)
    self.previousTwentyStores=self.twentyClosestStores;
    //Cleaning (reInitializing) "twentyClosestStores"(NSMutableArray)
    self.twentyClosestStores=[NSMutableArray array];

    //Adding indexes 0-19 of "allStores"(NSMutableArray) (20 closest stores to the user's current location) to "twentyClosestStores"(NSMutableArray)
    for (int i = 0; i < 20; i++) {
        [self.twentyClosestStores addObject:[self.allStores objectAtIndex:i]];
    }
}

#pragma mark - Start/stop monitoring methods
//For updating monitoring
-(void)locationChangeHandler
{
    //If "allStores"(NSMutableArray) isn't nil
    if (self.allStores!=nil) {
        //Finding the 20 closest stores to he user's location and adding it to "twentyClosestStores"(NSMutableArray)
        [self sortClosestStores];
        //Stop monitoring "previousTwentyStores"(NSMutableArray) (20 closest stores before user's location  updated)
        [self stopMonitoringStores];
        //Start monitoring "twentyClosestStores"(NSMutableArray)
        [self startMonitoringClosestStores];
    }
}
//Start monitoring "twentyClosestStores"(NSMutableArray)
-(void)startMonitoringClosestStores
{
    //If monitoring isn't availible for "CLCircularRegion"
    if (![CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]]) {
        NSLog(@"Monitoring is not available for CLCircularRegion class");
    }

    //Run on all "twentyClosestStores"(NSMutableArray)'s objects
    for (Store *currentStore in self.twentyClosestStores) {
        //Creating "region"(CLCircularRegion) and setting it to "currentStore"(Store)'s circular region
        CLCircularRegion *region=[currentStore createCircularRegion];

        //Start monitoring "region"(CLCircularRegion)
        [self.locationManager startMonitoringForRegion:region];
    }
}
//Stop monitoring "previousTwentyStores"(NSMutableArray) (20 closest stores before user's location  updated)
-(void)stopMonitoringStores
{
    //Run on all "previousTwentyStores"(NSMutableArray)'s objects
    for (Store *currentStore in self.previousTwentyStores) {
        //Creating "region"(CLCircularRegion) and setting it to "currentStore"(Store)'s circular region
         CLCircularRegion *region=[currentStore createCircularRegion];

        //Stop monitoring "region"(CLCircularRegion)
        [self.locationManager stopMonitoringForRegion:region];
    }
}

//Finding a store for region
-(Store*)storeForRegion:(CLCircularRegion*)region
{
    //Creating "latitude"(CGFloat) and "longtitude"(CGFloat) and setting it to "region"(CLCircularRegion)'s center.latitude/longtitude
    CGFloat latitude=region.center.latitude;
    CGFloat longtitude=region.center.longitude;

    //Run on all "allStores"(NSMutableArray)'s objects
    for (Store *currentStore in self.allStores) {

        //If "currentStore"(Store)'s latitude and longtitude is equal to "latitude"(CGFloat) and longtitude(CGFloat)
        if (currentStore.geoPoint.latitude==latitude&&currentStore.geoPoint.longitude==longtitude) {
            //Returning "currentStore"(Store)
            return currentStore;
        }
    }
    //Store not found - returning nil
    NSLog(@"No store found for this region: %@",[region description]);
    return nil;
}

Store.m:

    //Creating and returning a "CLCircularRegion" object of the store
-(CLCircularRegion*)createCircularRegion
{
    //Creating "region"(CLCircularRegion) and initializing it with current store information (self) and radios of 200m
    CLCircularRegion *region=[[CLCircularRegion alloc] initWithCenter:self.geoPoint radius:200 identifier:self.identifier];

    //Setting "region"(CLCircularRegion)'s notifyOnEntry to YES
    region.notifyOnEntry=YES;

    //Returning "region"(CLCircularRegion)
    return region;
}

注意:委托方法正在被调用,甚至didEnterRegion:但并不总是出于某种原因。

解决了问题:

(我决定不使用区域监控而是自己做)

 -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    [self checkIfNearStore]; //Not being called in background
}

-(void)checkIfNearStore
    {
        for (Store *currentStore in self.allStores) {
            if ([currentStore.circularRegion containsCoordinate:self.locationManager.location.coordinate]&&currentStore.alreadySendNotification==NO) {
                NSLog(@"Entered: %@",[[self storeForRegion:currentStore.circularRegion] address]);
                currentStore.alreadySendNotification=YES;
                [self.storesAlreadySentNotifications addObject:currentStore];
            }
        }

        for (Store *currentStore in self.storesAlreadySentNotifications) {
            if (![currentStore.circularRegion containsCoordinate:self.locationManager.location.coordinate]) {
                currentStore.alreadySendNotification=NO;
            }
        }
    }

非常感谢!


区域半径

请查看有关的讨论启动区域监控请注意,Apple 表示该区域的值最大为 400,在后续设备上效果最佳。他们还指出,平均可以在 3 到 5 分钟内得到回复。我不确定您如何测试该区域的进入/退出,但可能您没有留出足够的时间通过。

区域监控

此外,我建议您设置断点来检查监控区域代码中战略点处的 CLLocationManager 属性(当您期望区域更新时)。您可能会考虑清空区域数组(请参阅即:标题如下),然后使用您的自定义代码重新填充它们。我会非常仔细地检查该区域,以确保预期的行为正在发生。

Filters

有许多过滤器可以通知 CLLocationManager 位置何时发生重大变化。您应该设置这些值并检查它们是否对更新频率有影响。另请注意我展示的其他属性和方法,包括期望准确度以及启动重大更新的方法。阅读每个内容的讨论,看看它们是否适用于您的用例。尝试在需要时应用更改,以强制设备在适合您的情况时进行更新。

命中测试用户位置

您可能希望使用用户位置对特定 CLCircularRegion 实施定期命中测试。这应该允许您在代码中的预定时间/位置进一步细化位置更新。例如,您可能希望使用精度和距离过滤器来细化用户更新,然后在委托方法中调用针对数组中最近区域的查询。最终效果是,只要设备从最后一个已知位置显着移动,就会强制执行区域状态检查。

位置变更的后台更新

我建议您仔细阅读与此相关的讨论开始监控重大位置变化 https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/index.html#//apple_ref/occ/instm/CLLocationManager/startMonitoringSignificantLocationChanges方法(您必须使用此方法来解决问题)。 Apple 详细介绍了当应用程序在后台运行时获取更新所需的步骤。基本上,您必须拦截应用程序委托方法中的一个键。幸运的是这个所以问题 https://stackoverflow.com/questions/27742677/how-to-get-location-updates-for-ios-7-and-8-even-when-the-app-is-suspended有示例代码。但在跳转到代码之前,请按照建议查看讨论,因为它会让您更清楚地了解如何掌握此行为。

部分答案

就像很多问题一样。这个问题需要一些部分答案来解决您需要的功能。首先确保您已检查上面提供的注释,然后尝试其中一些链接以获得特定所需任务的部分答案。

如何禁用使用 -startMonitoringForRegion 注册的任何 CLRegion 对象? https://stackoverflow.com/questions/7061007/how-can-i-disable-any-clregion-objects-registered-with-startmonitoringforregion#dash-score-16

Namely: stop-monitoring

关于如何完善地理围栏的有用回复 https://stackoverflow.com/questions/23866097/ios-geofence-clcircularregion-monitoring-locationmanagerdidexitregion-does-not

地理围栏简化教程 http://shrikar.com/swift-tutorial-corelocation-and-region-monitoring-in-ios-8/

(你用过吗请求始终授权()在位置管理器上?)

诺塔·贝尼

我建议您阅读有关方法和属性的讨论,以了解 Apple 的提示。您还应该随意在代码编辑器中按住 cmd 键单击方法和属性,并查看头文件中的注释。这些将提供 Apple 提供的文档或快速帮助中未提供的更多见解。

作为一个简单的例子,以下标题注释似乎与您的目标相关。您可能想要实现并监视注释标题中提到的委托方法和 requestStateForRegion 方法:

/*
 *  locationManager:didDetermineState:forRegion:
 *
 *  Discussion:
 *    Invoked when there's a state transition for a monitored region or in response to a request for state via a
 *    a call to requestStateForRegion:.
 */
@available(iOS 7.0, *)
optional public func locationManager(manager: CLLocationManager, didDetermineState state: CLRegionState, forRegion region: CLRegion)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CLLocationManager protectedRegions (NSSet) 不正确,或者可能是其他什么? 的相关文章

  • 当应用程序处于后台时,替代 UserNotificationCenter Delegate 的 willPresent

    我正在尝试弄清楚是否可以通过本地通知来实现我的目标 或者是否需要切换到远程通知 我正在练习 iOS 10 Swift 3 方法是构建一个闹钟程序 该程序在一天中的设定时间播放 RSS 更新的广播节目的最新一集 当应用程序位于前台时 可以通过
  • 以编程方式访问 Apple Notes 内容

    是否可以以编程方式访问Apple Notes 即macos和ios中预装的应用程序 内容 macOS 上的 Notes 可使用 AppleScript 编写脚本 要注销所有笔记 请打开脚本编辑器并使用以下内容创建一个新脚本 然后单击播放按钮
  • SwiftUI 图像 ClipsToBounds

    尝试使用 SwiftUI Xcode 11 0 beta 2 我尝试用图像填充视图 Image large resizable aspectRatio contentMode fill frame width 80 height 80 al
  • 防止 Realm 在更新对象时覆盖属性

    我已经在 iOS 中设置了一个 REST API 来连接领域对象 然而 我发现在我的对象中创建最喜欢的标志存在问题 我创建了一个最喜欢的布尔值 但是每次从 API 更新该对象时 它都会再次将最喜欢的值设置为默认 false 在这里 我希望这
  • HTML 5 + iOS - 创建混合应用程序

    我正在尝试将我的本机 iOS 应用程序转换为使用 HTML 5 的混合应用程序 经过研究后我最终得到了jQuery 移动 phoneGap 我的问题是 是否可以将 html 5 和本机 iOS 功能混合在一个单一的版本中 看法 例如我可以使
  • 转发 UIAlertView 的可变参数

    我正在尝试设置一个非常简单的UIAlertView带有文本编辑 确定和取消按钮 我想根据文本编辑的内容禁用确定按钮 为了能够保留委托 以便他不会在警报视图之前消失 从而在用户对警报视图执行某些操作时立即导致崩溃 我对其进行了子类化 现在 我
  • Objective-C 相当于 Java 枚举或“静态最终”对象

    我试图找到一个与 Java 枚举类型或 public static final 对象等效的 Objective C 例如 public enum MyEnum private String str private int val FOO f
  • Dropbox iOS SDK 始终为 isLinked 返回“YES”:

    我正在使用 iOS Dropbox SDK 想要检查我的应用程序是否已与 Dropbox 帐户链接 所以我这样做 if self isLinked NSLog linked However self isLinked总是返回YES 即使在清
  • 如何开发iPhone MDM服务器?

    我刚刚阅读了有关适用于 iOS 设备的移动设备管理服务器的信息 但所有文档均指 第三方 MDM 服务器 我的问题是如何自己开发一个 第三方 MDM 服务器 我找不到任何关于此的文档 你有简单的方法和困难的方法 Easy way OSX Li
  • 终止应用程序后发送本地通知 swift 2

    当应用程序状态进入终止 不运行状态时 可以在特定时间后执行某些特定任务 func applicationDidEnterBackground application UIApplication print APP in background
  • 如果我在新证书上续订我的配置文件(企业分发方法),我的应用程序是否会停止?

    我有一个通过企业分发方法发布的应用程序 分发证书将在一个月后过期 因此我创建了一个新证书 此外 我还根据具有相同捆绑 ID 和应用 ID 的新证书更新了配置文件 旧的配置文件将像旧证书一样在 1 个月后过期 我的应用程序是通过此配置文件和证
  • 在 flutter 应用程序中添加启动屏幕的正确方法是什么?

    我正在开发一个基于 flutter 的应用程序 并研究了几种添加闪屏的方法 但我不确定哪一个是最好实现的 import dart async import package flutter material dart import packa
  • 如何在 UIView 中获取父导航控制器

    我创建了一个UITabBarController在我的应用程序委托中 其中每个选项卡栏项目都有不同的UINavigationController加载自定义的UIViewController带NIB 使用 pushViewController
  • 新的自动引用计数机制如何工作?

    有人可以简单地向我解释一下 ARC 的工作原理吗 我知道它与垃圾收集不同 但我只是想知道它到底是如何工作的 另外 如果 ARC 的作用与 GC 的作用相同且不影响性能 那么 Java 为什么要使用 GC 为什么它不使用 ARC 呢 每个接触
  • 处理具有不同缩放/分辨率的所有 iPhone 中的 UI [重复]

    这个问题在这里已经有答案了 在 iOS 中处理 iPhone 4 iPhone 5 iPhone 6 iPhone 6 UI 屏幕的最佳方法是什么 iPhone 6 的尺寸 3 倍缩放 坐标空间 414 x 736 像素 iPhone 6
  • exc_bad_access 于 [NSDate timeIntervalSinceReferenceDate]

    我的行为很奇怪 NSDate timeIntervalSinceReferenceDate 我有以下功能 void insertRow NSTimeInterval timeNow NSDate timeIntervalSinceRefer
  • 错误 ITMS-90596:“捆绑包无效。无法处理“Payload/ExpoKitApp.app/.bundle/Assets.car”处的资产目录。”

    问题摘要 我想向Apple App store TestFlight 提交一个应用程序 我正在使用 Transporter v1 1 提交应用程序 在提交过程中 我在 Transporter 中收到以下错误 请注意 我在此过程中没有使用 X
  • iPad 的自适应布局

    我正在关注这篇文章在 ios 中构建自适应布局为 iOS 8 构建自适应用户界面 http www sitepoint com building adaptive user interfaces ios 8 它在 iPhone 上运行良好
  • 查找 NSString 中子字符串的所有位置(不仅仅是第一个)

    有一个子串在字符串中出现多次 我用rangeOfString 不过好像只能找到第一个位置 如何找到子字符串的所有位置 NSString subString1 NSString subString2 n NSRange range1 newr
  • Swift - 带循环的多个链 http 请求

    两天以来 我感觉我正在搜索整个网络来解决多个 http 请求的问题 所以我的工作流程如下所示 将图像上传到服务器 响应 XML 格式和任务 ID 使用任务 ID 向服务器发出 GET 请求 以检查该任务的状态 响应 XML 格式 其中状态可

随机推荐

  • 父进程如何通过调用_exit的子进程的wait来获取终止状态

    我已阅读以下声明 给 exit 的 status 参数定义了终止状态 该进程 当该进程的父进程可用时 该进程可用 调用 wait 进程总是由 exit 成功终止 即 出口 一去不复返 Question If exit不返回 父进程如何获取终
  • ASP.Net MVC jQuery AJAX 路由问题

    我的页面是domain com home details 1 在我的 jQuery AJAX 调用中 我有以下内容 但是当它进行该调用时 它会调用domain com home details home getdata 我该怎么做才能让它得
  • React Native:无法导入 csv 文件

    我有一个csv文件位于 src data文件夹 我希望导入它以便能够传递到帕帕帕斯库被解析为JSON图书馆 这是我用来执行此操作的脚本 import Papa from papaparse import file from src data
  • Micronaut-Core:如何创建动态端点

    简单的问题 是否可以创建端点而无需 Endpoint 我想通过文件并根据其上下文的内容创建相当动态的端点 Thanks 更新一下我的想法 我想创建类似插件系统的东西 以使我的应用程序对于维护和未来功能更具可扩展性 值得一提的是 我正在使用
  • 如何将pyspark数据帧写入HDFS,然后如何将其读回数据帧?

    我有一个非常大的 pyspark 数据框 所以我想对其子集进行预处理 然后将它们存储到hdfs 后来我想把它们全部读完并合并在一起 谢谢 将 DataFrame 写入 HDFS Spark 1 6 df write save target
  • 在新的 stdClass 中声明匿名函数

    只是想知道为什么这样的东西不起作用 public function address name if isset this gt addresses name address new stdClass address gt city func
  • 底层连接已关闭:发送时发生意外错误。--- NuGet

    在尝试恢复 nuget 包时 我得到以下信息 错误 1 基础连接已关闭 发送时发生意外错误 错误 2 底层连接已关闭 无法建立 SSL TLS 安全通道的信任关系 错误 3 命令 D root nuget NuGet exe install
  • 如何用猫鼬进行分页

    我想在我的收藏中添加分页功能 如何在单个查询中找到具有 开始 和 限制 位置的文档并获取文档总数 您无法在一次查询中获得两个结果 你能做的最好的事情就是用一只 Mongoose 让它们都得到Query http mongoosejs com
  • max_user_connections 或超出 ip 连接限制 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我收到以下 PHP 错误消息 Use
  • OpenCV背景减法学习率不能改变

    我希望训练一个 50 帧的背景区域 并使用这个预训练的模型进行背景减除 模型在训练后停止更新 这是我的代码 import cv2 print This program is for background subtraction with p
  • 每五个单词后分割字符串

    我想每五个单词后分割一个字符串 Example 这里有一些东西要输入 这是示例文本 Output There is something to type here This is an example text 如何使用preg split
  • Cordova android 仿真 - 错误:无法读取 null 的属性“semver”

    尝试使用 cordova 模拟 Android 应用程序 但收到此错误消息 构建了以下 apk Users jnj cordova hello platforms android build outputs apk android debu
  • MYSQL 5.7 中的原生 JSON 支持:MYSQL 中 JSON 数据类型的优点和缺点是什么?

    MySQL 5 7 中用于存储的新数据类型MySQL 中的 JSON 数据 http dev mysql com doc refman 5 7 en json html表已 添加 显然这对MySQL来说是一个巨大的改变 他们列出了一些好处
  • 为什么“ionic cordova build”只生成未签名的APK?

    我使用以下命令来生成签名的 APK 我很确定这在几个月前有效 ionic cordova build android prod release keystore my keystore file keystore storePassword
  • ITMS-90809:已弃用的 API 使用 - 不再接受使用 UIWebView 的现有应用程序

    ITMS 90809 已弃用的 API 使用 自 2020 年 4 月 30 日起 Apple 将不再接受提交使用 UIWebView 的新应用程序 以及自 2020 年 12 月起使用 UIWebView 的应用程序更新 相反 请使用 W
  • 旋转/平移和恢复后获取画布上的位置

    好吧 事情变得复杂了 给定情况 我有一个尺寸为 800x600 的画布 我的鼠标位于画布位置 100x200 例如 我保存我的画布状态 现在我旋转并平移画布 绘制一个正方形 我恢复画布状态 有什么方法可以确定我的鼠标是否位于方块上 我想我也
  • 使 GCC 和其他 C++ 编译器变得非常严格

    我正在开发一个大型协作 C 项目 该项目在各种版本的 Linux OS X 和 Windows 上开发和运行 我们使用 GCC Visual Studio C 和 Intel C 编译器跨这些平台进行编译 随着越来越多的人开始为该项目开发代
  • 覆盖 .ToString()

    我想重写 ToString 函数 以便每当我得到一个 double 它只输出小数点后 5 位数字 如何在覆盖函数内引用 ToString 正在处理的对象 换句话说 我用什么 shell 来代替下面代码中的 XXX public overri
  • 父类中的功能需要检测子类属性的更改

    我试图找到一种方法让这个父 持久 类添加功能 以便每当子对象的任何属性发生更改时 更改 属性都会变为 true class Persistent bool changed false Persistent print Something s
  • CLLocationManager protectedRegions (NSSet) 不正确,或者可能是其他什么?

    我想在每次用户从商店数组中传递一个商店时进行检查 我有超过 20 个商店 因此我编写了一个函数来查找离用户位置最近的 20 个商店并监视它们 名单更新中locationManager didUpdateLocations 我还将旧的 20