首页 > 解决方案 > 中间件中的闭包为零

问题描述

我正在努力使用 SwiftUI 实现类似通量的实现。

我想跟踪用户的位置以及每当有新的位置更新时。因此我正在使用中间件。日志记录和 Firebase 身份验证中间件正在工作,但位置跟踪不起作用。因为 newLocation 是 nil,但是如果我将闭包 location.newLocation {} 放在 MiddlewareProvider 的 init 中,它会发布位置更改。为什么它在中间件中为零?

我包括了 firebase 和 logging 中间件来显示正在工作的中间件:

class VMiddlewareProvider: MiddlewareProvider {

    private var location: TrackLocation

    init() {
        self.location = TrackLocation()

    }

    func provideMiddleware() -> [Middleware<FluxState>] {
        return [
            loggingMiddleware(),
            locationTrackingMiddleware(),
            firebaseMiddleware()
        ]
    }

    private func loggingMiddleware() -> Middleware<FluxState> {
        let loggingMiddleware: Middleware<AppState> = { dispatch, getState in
            return { next in
                return { action in
                    #if DEBUG
                    let name = __dispatch_queue_get_label(nil)
                    let queueName = String(cString: name, encoding: .utf8)
                    print("#Action: \(String(reflecting: type(of: action))) on queue: \(queueName ?? "??")")
                    #endif
                    return next(action)
                }
            }
        }
        return loggingMiddleware
    }

    private func locationTrackingMiddleware() -> Middleware<FluxState> {
        let middleware: Middleware<AppState> = { dispatch, getState in
            return { next in
                return { action in
                    switch action as? LocationAction {
                    case .trackLocation:

                        self.location.newLocation = { result in
                            /// never gets called because newLocation is nil
                            print(result)
                        }
                        return next(action)

                    default:
                        return next(action)
                    }
                    return next(action)
                }
            }
        }
        return middleware
    }

    private func firebaseMiddleware() -> Middleware<FluxState> {
        let firebaseMiddleware: Middleware<AppState> = { dispatch, getState in
            return { next in
                return { action in
                    switch action {
                    case let action as AccountActions.Authenticate:
                        let handle = Auth.auth().addStateDidChangeListener {  (auth, user) in
                            if let user = user {
                                return next(AccountActions.AuthentificationAction(isLoggedIn: true, userUID: user.uid))
                            }  else {
                                return next(AccountActions.AuthentificationAction(isLoggedIn: false, userUID: nil))
                            }
                        }
                    default:
                        return next(action)
                    }
                }
            }
        }
        return firebaseMiddleware
    }
}

TrackLocation 类如下所示:

class TrackLocation: NSObject {
    let locationManager = CLLocationManager()
    var newLocation: ((CLLocation)->())?


    override init() {
        super.init()
        askForPermission()
        locationManager.delegate = self
        locationManager.startUpdatingLocation()
        locationManager.startMonitoringSignificantLocationChanges()
        locationManager.startMonitoringVisits()
    }

    func checkAuthorisation() {
        askForPermission()
    }

    func askForPermission() {
        locationManager.requestWhenInUseAuthorization()

    }

}

extension TrackLocation: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didVisit visit: CLVisit) {
        if let location = manager.location {

            newLocation?(location)

        }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        newLocation?(locations.last!)

    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        print(status)
    }
}

标签: swiftcore-locationmiddlewareswiftui

解决方案


有两个可能的错误: 1. 这个函数实际上并没有调用 self.location.newLocation. 请小心并调试它。

private func locationTrackingMiddleware() -> Middleware<FluxState> {
        let middleware: Middleware<AppState> = { dispatch, getState in
            return { next in
                return { action in
                    switch action as? LocationAction {
                    case .trackLocation:
//// this code isn't called! please,  check
                        self.location.newLocation = { result in
                            /// never gets called because newLocation is nil
                            print(result)
                        }
                        return next(action)

                    default:
                        return next(action)
                    }
                    return next(action)
                }
            }
        }
        return middleware
    }
  1. 在您的代码中的某处,您删除了这个变量:self.location.newLocation = nil

顺便说一句,你可以在某个地方删除变量location


推荐阅读