我正致力于使用 SwiftUI 实现类似 flux 的实现。
我想跟踪用户的位置以及何时有新的位置更新。因此我正在使用中间件。日志记录和 firebase 身份验证中间件正在运行,但位置跟踪不起作用。因为 newLocation 是 nil,但是如果我将闭包 location.newLocation {} 放在 MiddlewareProvider 的 init 中,它会发布位置更改。中间件为什么是nil?
我包含了 firebase 和日志记录中间件以显示工作中间件:
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)
}
}
最佳答案
有两个可能的错误:
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
}
- 在代码的某处,您删除了这个变量:
self.location.newLocation = nil
顺便说一句,你可以在某个地方删除变量 location
关于swift - 中间件中的闭包为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58746436/