1

我正在使用 Siesta 进行 REST 调用,并且正在尝试创建一个简单的 ResourceObserver 来显示 SVProgressHUD。

open class SVProgressHUDResourceObserver: ResourceObserver {
    static let sharedInstance = SVProgressHUDResourceObserver()

    // Show/Hide SVProgressHUD
    public func resourceRequestProgress(for resource: Resource, progress: Double) {
        print("SVProgressHUDResourceObserver resourceRequestProgress - progress=\(progress)")
        if progress == 1 {
            print("SVProgressHUD.dismiss()")
            SVProgressHUD.dismiss()
        } else if !SVProgressHUD.isVisible() {
            print("show()")
            SVProgressHUD.show()
        }
    }

    public func resourceChanged(_ resource: Resource, event: ResourceEvent) {
        print("SVProgressHUDResourceObserver resourceChanged  event=\(event)")
    }
}

因为它是一个单例,所以我使用弱引用添加了观察者:

@discardableResult func login(_ username: String, _ password: String,
                                  onSuccess: @escaping (LoginResponse) -> Void,
                                  onFailure: @escaping (Int?, String) -> Void) -> Request {
        return service.resource("/app/v1/authentication/login")
            .addObserver(SVProgressHUDResourceObserver.sharedInstance)
            .request(.post, json: [
                "username": username,
                "password": password
                ])
            .onSuccess { entity in
                guard let loginResponse: LoginResponse = entity.typedContent() else {
                    onFailure(0, "JSON parsing error")
                    return
                }
                self.authToken = loginResponse.session.token
                SessionManager.beginNewSession(loginResponse)
                onSuccess(loginResponse)
            }
            .onFailure { (error) in
                onFailure(error.httpStatusCode, error.userMessage)
        }
    }

我故意为登录添加了 10 秒的延迟,但是 SVProgressHUD 从未显示,实际上从未调用 resourceRequestProgress 方法。身份验证过程效果很好。

日志输出为:

SVProgressHUDResourceObserver resourceChanged  event=observerAdded
SVProgressHUDResourceObserver resourceChanged  event=newData(wipe)

任何有关使其工作的帮助将不胜感激。

4

1 回答 1

2

午睡有以下区别:

  1. 整个资源本身的状态,Siesta 缓存并保留以供任何人观察,以及
  2. 与资源相关的单个请求的结果,Siesta 将其发送到请求挂钩,但最终在请求被解除分配后丢弃。

请注意,对于 #1,如果有人更新资源的状态,观察者会不断收到通知,而对于 #2,只有专门为该请求注册的钩子才能获得通知。

这两个携带不同类型的信息。#1 用于更新资源状态的持续共享真相(“当前用户的配置文件”),而 #2 用于更新资源上特定操作的状态(“更改用户密码”)。

花一些时间来消化用户指南中的“<a href="http://bustoutsolutions.github.io/siesta/guide/requests/#request-vs-load" rel="nofollow noreferrer">请求与加载” . 然后,一旦你理解了这一点,请继续阅读。


在此代码中,您SVProgressHUDResourceObserver.sharedInstance作为资源本身的观察者附加:

    return service.resource("/app/v1/authentication/login")
        .addObserver(SVProgressHUDResourceObserver.sharedInstance)

…这意味着它只会收到load()请求的通知。但你从来没有load;你只有request它:

        .request(.post, json: [
            "username": username,
            "password": password
            ])

…这意味着只有附加到该特定请求onSuccess的请求挂钩 ( , )才会被通知它已完成。onFailure


如果您只需要一个进度条,请放弃ResourceObserver并改用onProgress请求的钩子。

(如果您需要保存登录结果,那么用户指南会列出如何更新资源的状态以响应发布请求。但是,看起来您已经通过其他方式存储了身份验证凭据,这是典型而精细的方法。)

于 2018-04-03T03:09:38.377 回答