Ios 在反应式编程中创建静态流是个坏主意吗?
现在我正在使用RxSwift框架开发iOS。在我的应用程序中,我必须输入用户位置,但我不需要实时更新。只要用户每次打开应用程序或执行某些已定义的操作时位置都会更新就足够了。因此,在缓存最后一个结果的地方实现singleton类怎么样。每次更新操作都会更改缓存结果并将其接受到流中。流的默认值是缓存值。然后,需要用户位置的视图将订阅此流 示例实现使用和 <代码>导入基础 导入缓存 导入核心定位 导入RxSwift 进口RxCocoa 类UserLocationManager:NSObject{ 私有枚举密钥:字符串{ case diskConfig=“磁盘配置” case lastLocation=“用户上次位置” } //标记:-变量 私有函数缓存(型号:T.Type)->cache.Storage{ 让storage=try!Cache.storage(diskConfig:diskConfig(名称:Keys.diskConfig.rawValue)、memoryConfig:memoryConfig(过期:.never)、transformer:TransformerFactory.forCodable(类型:model)) 返回存储 } 私有let locationManager=CLLocationManager() private var lastPosition:MapLocation{ 得到{ 做{ 返回try-cache(model:MapLocation.self).object(forKey:Keys.lastLocation.rawValue) } 捕获{返回零} } 设置{ 做{ guard let location=newValue else{return} 尝试缓存(model:MapLocation.self).setObject(location,forKey:Keys.lastLocation.rawValue) } 捕获{} } } 私有出租dispebag=dispebag() 静态let shared=UserLocationManager() var locationStream=BehaviorRelay(值:零) //标记:-方法 func updateLocation(){ 如果CLLocationManager.locationServicesEnabled(){ locationManager.requestLocation() } } func subscribe(){ locationStream.accept(lastPosition?.clCoordinate2D) locationStream.subscribe(onNext:{[weak self]中的位置) guard let`self`=self-else{return} guard let location=位置else{return} self.lastPosition=MapLocation(纬度:location.lation,经度:location.longitude) }).处置(由:处置人) locationManager.delegate=self } //马克:生命周期 重写init(){ super.init() 推迟{ self.subscribe() } } } //标记:-CLLocationManagerDelegate 扩展UserLocationManager:CLLocationManagerDelegate{ func locationManager(manager:CLLocationManager,didUpdateLocations位置:[CLLocation]){ guard let location=locations.first-else{return} UserLocationManager.shared.locationStream.accept(location.coordinate) } func locationManager(manager:CLLocationManager,didFailWithError:error){ } }Ios 在反应式编程中创建静态流是个坏主意吗?,ios,swift,static,rx-swift,reactive,Ios,Swift,Static,Rx Swift,Reactive,现在我正在使用RxSwift框架开发iOS。在我的应用程序中,我必须输入用户位置,但我不需要实时更新。只要用户每次打开应用程序或执行某些已定义的操作时位置都会更新就足够了。因此,在缓存最后一个结果的地方实现singleton类怎么样。每次更新操作都会更改缓存结果并将其接受到流中。流的默认值是缓存值。然后,需要用户位置的视图将订阅此流 示例实现使用和 导入基础 导入缓存 导入核心定位 导入RxSwift 进口RxCocoa 类UserLocationManager:NSObject{ 私有枚举密钥
从概念上讲,拥有一个可以订阅的全局流是没有问题的。然而,你的具体实施令我担忧 关于可观察流的一个很酷的事情是,它们是懒惰的,除非需要,否则无法完成任何工作,但是您正在编写额外的代码来绕过该特性,我认为这是没有必要的。此外,当应用程序进入后台时,将当前位置存储在那里,并且当应用程序返回前台时(可能几周后)仅假设该位置是有效位置,这听起来不适合我
RxCocoa包已经有了CLLocationManager的Rx包装器。在我看来,仅仅使用它要简单得多。如果只需要一次位置更新,请使用
。取(1)
。我倾向于在拍摄前添加一个位置准确性过滤器(1)。谢谢您的回答!你能分享一些关于CLLocationManager的Rx包装器的链接吗?
import Foundation
import Cache
import CoreLocation
import RxSwift
import RxCocoa
class UserLocationManager: NSObject {
private enum Keys: String {
case diskConfig = "Disk Config"
case lastLocation = "User Last Location"
}
// MARK: - Variables
private func cache<T: Codable>(model: T.Type) -> Cache.Storage<T> {
let storage = try! Cache.Storage(diskConfig: DiskConfig(name: Keys.diskConfig.rawValue), memoryConfig: MemoryConfig(expiry: .never), transformer: TransformerFactory.forCodable(ofType: model))
return storage
}
private let locationManager = CLLocationManager()
private var lastPosition: MapLocation? {
get {
do {
return try cache(model: MapLocation.self).object(forKey: Keys.lastLocation.rawValue)
}
catch { return nil }
}
set {
do {
guard let location = newValue else { return }
try cache(model: MapLocation.self).setObject(location, forKey: Keys.lastLocation.rawValue)
}
catch { }
}
}
private let disposeBag = DisposeBag()
static let shared = UserLocationManager()
var locationStream = BehaviorRelay<CLLocationCoordinate2D?>(value: nil)
// MARK: - Methods
func updateLocation() {
if CLLocationManager.locationServicesEnabled() {
locationManager.requestLocation()
}
}
func subscribe() {
locationStream.accept(lastPosition?.clCoordinate2D)
locationStream.subscribe(onNext: { [weak self] location in
guard let `self` = self else { return }
guard let location = location else { return }
self.lastPosition = MapLocation(latitude: location.latitude, longitude: location.longitude)
}).disposed(by: disposeBag)
locationManager.delegate = self
}
// MARK: - Lifecycle
override init() {
super.init()
defer {
self.subscribe()
}
}
}
// MARK: - CLLocationManagerDelegate
extension UserLocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.first else { return }
UserLocationManager.shared.locationStream.accept(location.coordinate)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
}
}