MMPReactiveCoreLocation 0.6.2

MMPReactiveCoreLocation 0.6.2

测试已测试
语言语言 Obj-CObjective C
许可 MIT
发布最新发布2015年2月

Mamad Purbo 维护。



MMPReactiveCoreLocation 是一个用于 CoreLocation 和 iBeacon 的响应式库,与 ReactiveCocoa 一起使用。

重要提示

  • 0.6 版本已经重新设计和从头开始重写,不与先前版本兼容。0.5.* 版本的文档仍然可用 在此处,0.4.* 在 此处

特性

  • 具有智能资源管理的全局可访问信号,自动启动和停止底层位置管理器的服务。
  • 不再需要代理,所有 CLLocationManager 的功能都可作为信号使用。
  • 用于位置相关更新的信号,包括一次性位置查询。
  • 用于区域监控更新的信号,包括 iBeacon 监控和测距。
  • 用于 iOS 8 访问监控的信号。
  • 用于位置管理器状态更新和错误的信号。
  • 支持 iOS 8 的“始终”和“使用时”授权。

尽管实现了大多数 CoreLocation 服务,但一些服务尚未测试,应被视为 alpha 质量。此处记录的功能已测试且应能正常工作

  1. 位置订阅
  2. 单个位置订阅
  3. 显著变化订阅
  4. 区域监控事件订阅
  5. 停止订阅
  6. 自定义位置管理器设置
  7. 处理错误和状态变化
  8. 手动授权请求

安装

使用

位置流订阅

要使用智能默认设置订阅位置流,最简单的方法是调用 locations 方法来获取信号

// import the header
#import <MMPReactiveCoreLocation/MMPReactiveCoreLocation.h>

// build service, subscribe to 'locations' signal
[[[MMPReactiveCoreLocation service] 
                           locations] 
                           subscribeNext:^(CLLocation *location) {
                               NSLog(@"[INFO] received location: %@", location);
                           }];

在应用程序的多个地方调用此确切的代码 不会 产生多个 CLLocationManager+CLLocationManagerDelegate 集合。库将根据定义服务时指定的设置管理、启动和停止共享的 CLLocationManager+CLLocationManagerDelegate 实例。例如,以下代码 创建一个新的 CLLocationManager+CLLocationManagerDelegate 集合,因为它需要一个自定义的 activityType

[[[[MMPReactiveCoreLocation service] 
                            activityType:CLActivityTypeFitness]
                            locations] 
                            subscribeNext:^(CLLocation *location) {
                                NSLog(@"[INFO] received location: %@", location);
                            }];

单个位置订阅

如果您不需要持续的位置更新流,可以使用 location(注意没有复数 s)获取最新位置一次,然后库将自动停止 CLLocationManager 并清理资源

// one-time location
[[[MMPReactiveCoreLocation service] 
                           location] 
                           subscribeNext:^(CLLocation *location) {
                               NSLog(@"[INFO] received single location: %@", location);
                           }];

有一种针对单个位置订阅的特定选项,称为 timeout。此选项可以用来指定在等待位置多长时间后信号应放弃(例如,在地下等情况下当前没有可用位置时)。这对于应用程序即使在没有位置信息的情况下也应该继续运行尤其有用。服务超时将在以下示例中产生信号错误:

// one-time location with 5 sec. timeout
[[[[MMPReactiveCoreLocation service]
                            timeout:5.0]
                            location]
                            subscribeNext:^(CLLocation *location) {
                                NSLog(@"[INFO] received single location: %@", location);
                            }
                            error:^(NSError *error) {
                                NSLog(@"[ERROR] error getting location: %@", error);
                            }
                            completed:^{
                                NSLog(@"[INFO] single location signal completed.");
                            }];

重要变更订阅

对于重要变更更新,请使用 significantLocationChanges 信号。

// build service, subscribe to 'significantLocationChanges' signal
[[[MMPReactiveCoreLocation service] 
                           significantLocationChanges] 
                           subscribeNext:^(CLLocation *location) {
                               NSLog(@"[INFO] received location: %@", location);
                           }];

就像使用 locations 进行持续更新和 location 进行单个更新一样,使用 significantLocationChanges 进行持续的重要位置变更更新,仅使用 significantLocationChange 进行单个重要位置变更。

区域监控事件订阅

对于区域监控,使用 region 添加要监控的区域,并使用 regionEvents 获取信号。

// build service, add 2 regions to monitor, subscribe to region events
[[[[[MMPReactiveCoreLocation service] 
                             region:region1] 
                             region:region2] 
                             regionEvents] 
                             subscribeNext:^(MMPRegionEvent *regionEvent) {
                                 NSLog(@"[INFO] received event: %ld for region: %@", regionEvent.type, regionEvent.region.identifier);
                             }];

您还可以多次调用 region 方法来定义多个要监控的区域。有关可获得哪些区域事件的更多详细信息,请参阅 MMPRegionEventType

停止订阅

要停止任何信号并自动清理底层位置管理器和服务请求,只需使用 stop 方法。

self.service = [MMPReactiveCoreLocation service];

// use 'stop' to tell the service that it should stop the subscription. Underlying location manager (CLLocationManager) 
// will automatically be stopped and cleaned up if there are no other subscriber.
[self.service stop];

请注意,如果有多个终端用户使用共享底层位置管理器(即以完全相同的设置构建和配置的服务)的信号,则停止一个终端用户不一定停止位置管理器。

设置位置管理器

位置信号默认设置如下:

如果您需要除默认设置之外的其他设置,则可以链式调用以下方法来设置您想要定制的值

  • distanceFilter 用于设置距离过滤。
  • desiredAccuracy 用于设置所需精度。
  • activityType 用于设置活动类型。
  • pauseLocationUpdatesAutomaticallypauseLocationUpdatesManually 以设置自动或手动更新位置暂停。

以下是示例代码,演示在订阅 SIGNAL 之前如何自定义位置管理器设置:

MMPReactiveCoreLocation *service = [MMPReactiveCoreLocation service];

RACSignal *locations = [[[[service distanceFilter:kCLDistanceFilterNone]
                                   desiredAccuracy:kCLLocationAccuracyBestForNavigation]
                                   activityType:CLActivityTypeFitness]
                                   locations];

请参阅头文件以获取更多设置选项。

处理错误和状态更改

// handling authorization status change
[[service authorizationStatus] subscribeNext:^(NSNumber *statusNumber) {
    CLAuthorizationStatus status = [statusNumber intValue];
    switch (status) {
        case kCLAuthorizationStatusNotDetermined:
            NSLog(@"[INFO] Status changed: kCLAuthorizationStatusNotDetermined");
            break;
        case kCLAuthorizationStatusRestricted:
            NSLog(@"[INFO] Status changed: kCLAuthorizationStatusRestricted");
            break;
        case kCLAuthorizationStatusDenied:
            NSLog(@"[INFO] Status changed: kCLAuthorizationStatusDenied");
            break;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
        case kCLAuthorizationStatusAuthorizedAlways:
            NSLog(@"[INFO] Status changed: kCLAuthorizationStatusAuthorizedAlways");
            break;
        case kCLAuthorizationStatusAuthorizedWhenInUse:
            NSLog(@"[INFO] Status changed: kCLAuthorizationStatusAuthorizedWhenInUse");
            break;
#else
        case kCLAuthorizationStatusAuthorized:
            NSLog(@"[INFO] Status changed: kCLAuthorizationStatusAuthorized");
            break;
#endif
        default:
            break;
    }
}];

// handling errors
[[service errors] subscribeNext:^(NSError *error) {
    NSLog(@"[ERROR] Location service error: %@", error);
}];

手动授权请求

当您需要手动发送授权请求时,例如在使用 MKMapView 并只需要在设置 showsUserLocation 之前发送请求时,可以使用返回状态事件生成信号(与 authorizationStatus 信号相同)的 requestAuthorization 方法。

[[[[MMPReactiveCoreLocation service]
                            authorizeAlways]
                            requestAuthorization]
                            subscribeNext:^(NSNumber *statusNumber) {      
                                CLAuthorizationStatus status = [statusNumber intValue];
                                switch (status) {
                                    case kCLAuthorizationStatusAuthorizedAlways:
                                    case kCLAuthorizationStatusAuthorizedWhenInUse:
                                        _mapView.showsUserLocation = YES;
                                        break;
                                    case kCLAuthorizationStatusAuthorized:
                                        _mapView.showsUserLocation = YES;
                                        break;
                                    default:
                                        break;
                                }
                            }];

路线图

大部分的CLLocationManager功能,包括iBeacon、访客监控、航向更新等,已实现,但尚未进行充分的测试,因此可能存在bug。我计划将其用于实际项目中,因此应积极维护。欢迎贡献力量。

随着我对bug的修复和测试的编写,我会编写更多的使用示例和文档。在此期间,如果您对该库如何实现某些CLLocationManager使用模式有任何疑问,请随时联系我或创建问题。

  • 0.7:iBeacon发布的CoreBluetooth集成。
  • 0.8:单元测试和文档。

联系

MMPReactiveCoreLocation由Mamad Purbo维护。

许可

MMPReactiveCoreLocation采用MIT许可证。有关更多信息,请参阅LICENSE文件。