-
-
Notifications
You must be signed in to change notification settings - Fork 159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Non-retaining multi-resource observers #154
Comments
Actually, just to add. When i set the actual full path, then the observer works fine. |
I created a quick fix for my code for now: extension Configuration {
public mutating func listenToRequests() {
decorateRequests {
resource, request in
request.onFailure { _ in
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.resourceChanged(resource, event: .error)
}
}
request.onSuccess { _ in
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.resourceChanged(resource, event: .newData(.network))
}
}
return request
}
}
} Then to use it, service.configure {
$0.useNetworkActivityIndicator()
$0.listenToRequests()
} |
There are many compelling reasons for this feature or something like it: automatic retry after reestablishing a lost connection, for example, or automatically polling resources while they’re in use. It’s more complicated than just extending the domain of We need a beast that’s slightly different from a
That’s a big chunk of API design to bite off, so I’ve been deferring it. I’d prioritize it just after having a standard drop-in |
I've been looking at ways to cache some images in a way so that volatile views (observers) are likely, but not required, to find the image locally. This happens in the reuse (q.v.) of CollectionCells as the user scrolls back and forth; a cell scrolls out of view, gets reused, and the original request is dropped on the floor only to be re-requested when the users reverses the scrolling. I'm thinking of creating a dedicated Service with an EntityCache that implements a "keep the most n recently used" (or such). This way a request for a particular image (URL) is likely to still be available if it is re-requested within a short time. Thoughts? |
This is exactly what Siesta is designed for as it stands, and the GithubBrowser example project contains code that demonstrates exactly what you describe (with table views, even). This issue is about making an observer that can keep watching a resource as long as it is in use by others, but without causing it to be retained forever. For example, such an observer could say, “As long as anyone is using a ‘current temperature’ resource, keep refreshing it.” |
Hi @pcantrell, I would like to weigh in with another use case. I'm currently trying to implement some kind of in-app debug/network monitor. I'm trying to mimic something that sniffs on the network traffic (like Charles, https://www.charlesproxy.com does) but in a very Siesta-kind of way. I want to be able to track the used resources, responses and combine this with the data before transformation happens. @Reedyuk's // This no real implementation, just snippets
struct NetworkResourceState {
static var collected: [String: NetworkResourceState]
let rawData: Any?
let entity: Entity<Any>?
}
extension Configuration {
public mutating func sniffRequests() {
// I want to hook into the initial data before it passes the transformations,
// so I get the "cleanest" data possible
pipeline[.rawData].add(NetworkSniffer())
decorateRequests { resource, request in
// here I can track the resources and hook in into their requests
// I will save the needed data into memory using the resource's `absolutePath` as
// the key
var state = NetworkResourceState.collected[resource.url.absolutePath] ?? NetworkResourceState()
NetworkResourceState.collected[resource.url.absolutePath] = state
request.onCompletion { _ in
switch responseInfo.response {
case .success(let entity):
state?.latestData = entity
case .failure(_):
break
}
}
}
}
struct NetworkSniffer: ResponseTransformer {
func process(_ response: Siesta.Response) -> Siesta.Response {
switch response {
case .success(let entity):
// While I can easily get the response data in a very basic state here
// I have no chance to reference it to the request (OR resource) that
// ended in this response
...
case .failure(let error):
break
}
return response
}
}
Now if the response would e.g. include the absolute path of the initial resource/request I would be able to link these two steps together. But as it stand Siesta is too closed to be able to understand where things are coming from. I totally understand the reasoning and I believe it's very good practice to have all these little parts be independent from each other as possible, but maybe there is a way to piggy-pack some introspection information in the chains so one could connect the dots easier? PS: I could try to merge something like https://github.com/Kofktu/Sniffer and Siesta, but that's not really what I'm looking at (at least not right now). I would like to keep the flow in context of Siesta: Resources -> Responses, with the small issue to get to the rawest form of data as possible before Siesta's transformation chain does it's magic. |
Hi Paul,
I'm having a little trouble in adding an observer which is called upon All network requests made by a Siesta service object.
service.resource("*").addObserver(self)
Where self is adopting the resourceObserver protocol.
I get the observer callback when i add and remove the observer but it doesn't seem to be latching onto my network requests.
Thoughts? I'm sure its something simple.
The text was updated successfully, but these errors were encountered: