Let's discuss watchers, cache and their flow.
Cold start of application - no cache at all.
Here are my debug logs:
isReachable true //Reachability change
User: nil //No user logged in
apollo.watch(query: SyncManagerQuery(), cachePolicy: .returnCacheDataDontFetch)
Watch SyncManagerQuery // We are interested ONLY in cached data.
Watch SyncManagerQuery error //Error cache is empty. It's ok
Missing value //Error description - missing value. Because cache is empty.
Here everything seems to be fine. We are starting application for the first time. Cache is empty. Query watcher is being triggered and is returning error because of lack of data in cache.
Now let's move forward and log in.
Optional(<FIRUser: 0x6000031c6000>) //Now we've got user
fetch. apollo.fetch(query: SyncManagerQuery(), cachePolicy: .fetchIgnoringCacheData)
Fetch Sync FETCH //Ignoring cache data is still creating cache am I right?
Sync Fetch success //Fetch is successful
BUT NOTHING IS HAPPENING :(
Question 1: Why watcher is not reacting? It is being stored in a parent object.
private var syncWatcher: GraphQLQueryWatcher<SyncManagerQuery>?
and is initialized before fetch trigger.
Ok let's start over again. Close the application and start again with already existing cache.
isReachable true //We've got internet
Optional(<FIRUser: 0x600003eba480>) //We've got user
Fetch Sync FETCH //Above conditions are triggering FETCH
Watch SyncManagerQuery //Hmm watch is also starting? Not that scary ok, it is just executing for the first time?
Watch SyncManagerQuery success //Success - because we already have cache so it's ok
Sync Fetch success //In the meantime FETCH just finished
Watch SyncManagerQuery // **1*** So it is triggering watch. Not sure why.
Watch SyncManagerQuery error //Error :(The operation couldn鈥檛 be completed. (Apollo.URLSessionClient.URLSessionClientError error 2.) **2**
Watch SyncManagerQuery // But hey it is trying once again
Watch SyncManagerQuery success // And this time we've got a success.
Question 2: - Fetch result had no changes at all. It was exactly the same. Is watcher reacting to just cache update or is it verifying actual changes?
Question 3: - Why it fails? And the retry is normal behavior after failure or is it a side effect of sth else?
Ok let's start over again. Exactly same conditions. We already have cache.
isReachable true //We've got internet
Optional(<FIRUser: 0x6000008ce080>) //We've got user
Fetch Sync FETCH //Starting fetch
Watch SyncManagerQuery
Watch SyncManagerQuery success //Watching cache successful
Sync Fetch success //Fetching data successful, cache is being refreshed
Watch SyncManagerQuery //And this is probably triggering watch
Watch SyncManagerQuery success //Watch is successful
Watch SyncManagerQuery //**1** But what is happening? Why it is triggering once again?
Watch SyncManagerQuery success
Question 4: - why my watch query seems to be triggering twice after fetch?
Hi! I renumbered your questions so it would be clearer which one i'm responding to once I get more information here. Some things that would be helpful to understand:
.returnCacheDataElseFetch? All problems seems to be similar to "cold start" problem described here
https://github.com/apollographql/apollo-ios/issues/99
Yeah, this from @martijnwalraven in #99 definitely seems to explain why your first watcher isn't called:
Because your watch uses
.returnCacheDataDontFetch, and the cache is initially empty, it will never get a valid response in that case.
Is there a chance you could send me a small repro project? I should at least be able to try to figure out why the watch is getting called twice, but it'd be pretty hard to do without something to debug. You can email it to ellen at apollographql dot com.
I'll do my best to prepare some sample however now I'm out of time. Hopefully will send you sth around weekend.
Right now, well, I can live with double watcher :)
@pgawlowski Were you ever able to get a sample together? If not, do you mind if we close this issue out?
Hey @designatednerd
Sorry for not providing my sample code. It's still on my personal ToDo however I am totally sucked into other work. Let's close this issue right now. Hope I will provide some sample that will be helpful to validate this issue in some time - maybe during my vacations :)
Thanks for everything!