Swift Combine的CombineLatest不会响应其发布者之一的更新而触发

时间:2020-03-25 07:09:01

标签: swift combine combinelatest

我正在合并两个发布者,以确定地图视图的中心坐标应该是什么。两家出版商是:

  1. import cv2 url = "http://192.168.43.1:8080" # Your url might be different, check the app vs = cv2.VideoCapture(url+"/video") while True: ret, frame = vs.read() if not ret: continue # Processing of image and other stuff here cv2.imshow('Frame', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break 确定的用户的初始位置(CLLocationManager开始发送位置更新后报告的第一个位置)。
  2. 如果点击“当前位置的中心地图”按钮,则为用户的当前位置。

在代码中:

CLLocationManager

class LocationManager: NSObject, ObservableObject { // The first location reported by the CLLocationManager. @Published var initialUserCoordinate: CLLocationCoordinate2D? // The latest location reported by the CLLocationManager. @Published var currentUserCoordinate: CLLocationCoordinate2D? // What the current map view center should be. @Published var coordinate: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 42.35843, longitude: -71.05977) // Default coordinate. // A subject whose `send(_:)` method is being called elsewhere every time the user presses a button to center the map on the user's location. var centerButtonTappedPublisher: PassthroughSubject<Bool, Never> = PassthroughSubject<Bool, Never>() // The combined publisher that is where all my troubles lie. var coordinatePublisher: AnyPublisher<CLLocationCoordinate2D, Never> { Publishers.CombineLatest($initialUserCoordinate, centerButtonTappedPublisher) .map { initialCoord, centerButtonTapped in var latestCoord = initialCoord if centerButtonTapped { latestCoord = self.currentUserCoordinate } return latestCoord } .replaceNil(with: CLLocationCoordinate2D(latitude: 42.35843, longitude: -71.05977)) .eraseToAnyPublisher() } private var cancellableSet: Set<AnyCancellable> = [] //... Other irrelevant properties private override init() { super.init() coordinatePublisher .receive(on: RunLoop.main) .assign(to: \.coordinate, on: self) .store(in: &cancellableSet) //... CLLocationManager set-up } } extension LocationManager: CLLocationManagerDelegate { //... func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { // We are only interested in the user's most recent location. guard let location = locations.last else { return } let latestCoord = location.coordinate if initialUserCoordinate == nil { initialUserCoordinate = latestCoord } currentUserCoordinate = latestCoord } //... } $initialUserCoordinate这两个发布商都发布了更新-我已经确认了这一点。但是,只有在点击“当前位置的中心地图”按钮后,才会触发合并的发布者centerButtonTappedPublisher。首次设置coordinatePublisher属性时,它永远不会触发。

This question建议在initialUserCoordinate之后添加.receive(on: RunLoop.main),但这对我不起作用。

我在做什么错了?

1 个答案:

答案 0 :(得分:1)

您需要使用Publishers.Merge而不是CombineLatest,请参阅文档:

对于Publishers.CombineLatest

从两个发布者那里接收并合并最新元素的发布者。

对于Publishers.Merge

任一上游发布者发出事件时发出事件的发布者。