gpt4 book ai didi

ios - 编写 CLLocationManagerDelegate 的最佳 Reactive-Cocoa 方法,它很少获取位置

转载 作者:可可西里 更新时间:2023-11-01 05:21:33 26 4
gpt4 key购买 nike

背景

我对 ReactiveCocoa 框架及其潜力感到非常兴奋,所以我决定硬着头皮使用它编写我的第一个应用程序。在我的应用程序中,我已经编写了各种服务和委托(delegate),但我现在需要对它们进行“Reactive-Cocoa-ise”,以便我可以继续处理实际的 GUI 方面的事情。

也就是说,为了更好地理解这一点,我正在编写一些简单的代码来尝试概念。在这种情况下,为 CLLocationManagerDelegate 编写一个包装器。

在实际应用中,用例是这样的:

  • 1) 应用程序加载后 (viewDidLoad) 然后 2) 尝试获取设备的位置
  • 2.1) 如果没有启用定位服务
  • 2.1.1) 检查授权状态,如果允许则startMonitoringSignificantLocationChanges,
  • 2.1.2) 否则返回错误
  • 2.2) else(启用定位服务)
  • 2.2.1) 如果位置管理器的最后位置是“最近的”(6 小时或更短)返回
  • 2.2.2) 否则 startMonitoringSignificantLocationChanges
  • 3) 返回位置时(立即或通过locationManager:(CLLocationManager *)manager
    didUpdateLocations:(NSArray *)locations
    ), 然后我们也 stopMonitoringSignificantLocationChanges
  • 4) 如果调用 LocationManagerDelegate 的代码接收到错误,则向代理询问固定的“默认”值
  • 5) 下一段代码然后使用该位置(获取的或默认的)启动并调用第三方服务(调用 WebServices 等)

您可以在 https://github.com/ippoippo/reactive-core-location-test 查看测试工具

关注点

安全带“起作用”是因为它会启动并获取位置。但是,我真的很担心我是否以正确的方式这样做。

考虑这段代码

RACSignal *fetchLocationSignal = [lmDelegate latestLocationSignal];

RACSignal *locationSignal = [fetchLocationSignal catch:^RACSignal *(NSError *error) {
NSLog(@"Unable to fetch location, going to grab default instead: %@", error);
CLLocation *defaultLocation = [lmDelegate defaultLocation];
NSLog(@"defaultLocation = [%@]", defaultLocation);
// TODO OK, so now what. I just want to handle the error and
// pass back this default location as if nothing went wrong???
return [RACSignal empty];
}];

NSLog(@"Created signal, about to bind on self.locationLabel text");

RAC(self.locationLabel, text) = [[locationSignal filter:^BOOL(CLLocation *newLocation) {
NSLog(@"Doing filter first, newLocation = [%@]", newLocation);
return newLocation != nil;
}] map:^(CLLocation *newLocation) {
NSLog(@"Going to return the coordinates in map function");
return [NSString stringWithFormat:@"%d, %d", newLocation.coordinate.longitude, newLocation.coordinate.latitude];
}];

问题

  • 1) 如何处理错误?我可以使用 catch,这让我有机会向委托(delegate)人询问默认位置。但是,然后我陷入了如何将默认位置作为信号传回的问题?或者我只是更改我的 defaultLocation 方法以返回 RACSignal 而不是 CLLocation??
  • 2) 当我返回位置时,应该以sendNext 还是sendCompleted 方式完成?目前它被编码为 sendNext,但它似乎可以作为 sendCompleted 完成。
  • 3) 实际上,答案是否取决于我如何创建委托(delegate)。每次加载 View 时,此测试应用程序都会创建一个新的委托(delegate)。那是我应该做的事吗,我应该让 Delegate 成为单例。如果是单例,那么 sendNext 似乎是正确的做法。但是,如果这意味着我将我在委托(delegate)中的 latestLocationSignal 中的代码移到 init 方法中呢?

对于这些杂乱无章的问题,我深表歉意,似乎只是在我脑海中打转。

最佳答案

将上面的答案更新为 ReactiveCocoa 4 和 Swift 2.1:

import Foundation
import ReactiveCocoa

class SignalCollector: NSObject, CLLocationManagerDelegate {

let (signal,sink) = Signal<CLLocation, NoError>.pipe()

let locationManager = CLLocationManager()

func start(){
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

for item in locations {

guard let location = item as CLLocation! else { return }
sink.sendNext(location)
}
}

并监听事件:

 var locationSignals : [CLLocation]  = []  
signal.observeNext({ newLocation in
locationSignals.append(newLocation)
})

关于ios - 编写 CLLocationManagerDelegate 的最佳 Reactive-Cocoa 方法,它很少获取位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22087276/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com