ios swift siesta ResourceObserver resourceRequestP

2019-06-07 22:18发布

I am using Siesta for REST calls and I am trying to create a simple ResourceObserver to display a 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)")
    }
}

Since it's a singleton I add the observer using a weak reference:

@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)
        }
    }

I purposely added a 10 second delay to the login however the SVProgressHUD never displays, in-fact the resourceRequestProgress method is never called. The authentication process work great.

The log output is:

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

Any assistance on getting this to work would be greatly appreciated.

1条回答
姐就是有狂的资本
2楼-- · 2019-06-07 22:54

There is a difference in Siesta between:

  1. the state of the whole resource itself, which Siesta caches and keeps around for anyone to observe, and
  2. the results of individual requests relating to the resource, which Siesta sends to request hooks but ultimately discards once the request is deallocated.

Note that with #1, observers keep getting notifications if anyone updates the state of the resource, whereas with #2 only the hook specifically registered for that request get notifications.

These two carry different kinds of information. #1 is for updates to the ongoing shared truth of the state of a resource (“the current user’s profile”) whereas #2 is for updates about the state of a specific action on the resource (“changing the user’s password”).

Take some time to digest “Request vs. Load” in the user guide. Then, once you’ve made sense of that, read on.


In this code, you are attaching SVProgressHUDResourceObserver.sharedInstance as an observer of the resource itself:

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

…which means it will only get notifications of load() requests. But you never load it; you only request it:

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

…which means that only the request hooks (onSuccess, onFailure) that you attach to that specific request will be notified that it’s completed.


If you only need a progress bar, ditch ResourceObserver and use the onProgress hook of the request instead.

(If you need to save the result of the login, then the user guide lays out how to update the resource’s state in response to a post request. However, it looks like you are already storing the auth credentials through other means, which is a typical and fine approach.)

查看更多
登录 后发表回答