gpt4 book ai didi

ios - 在响应式(Reactive)编程中创建静态流是个坏主意吗?

转载 作者:行者123 更新时间:2023-11-28 05:38:51 24 4
gpt4 key购买 nike

现在我正在使用 RxSwift 框架开发 iOS。在我的应用程序中,我必须使用用户位置,但我不需要实时更新它。如果每次用户打开应用程序或执行某些定义的操作时更新位置就足够了。因此,如何实现缓存最后结果的单例类。每次更新都会更改缓存的结果并将其接受到流中。 Stream 的默认值是缓存值。然后,需要用户位置的 View 将订阅此流。

示例实现 使用 CacheRxSwift

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) {

}
}

最佳答案

拥有一个可以订阅的全局流在概念上没有问题。但是,您的具体实现令我担心。

关于 Observable 流的一个很酷的事情是它们是惰性的,除非需要,否则不做任何工作,但是您正在编写额外的代码来绕过该功能,我认为没有必要。此外,当应用程序进入后台时将当前位置存储在那里,并在应用程序返回前台(可能几周后)时假设这是一个有效位置,这对我来说听起来不合适。

RxCocoa 包已经有一个用于 CLLocationManager 的 Rx 包装器。在我看来,使用它会简单得多。如果您只需要一个位置更新,则使用 .take(1)。我倾向于在拍摄 (1) 之前添加一个关于位置准确性的过滤器。

关于ios - 在响应式(Reactive)编程中创建静态流是个坏主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57668983/

24 4 0
文章推荐: javascript - 如何检测在 android webview 中单击