unread,
Nov 3, 2009, 5:00:34 AM11/3/09
to Three20
So, let's say that in my app, I have a list of things. That list is
originally sourced from the cloud someplace, and that's where updated
content will come from. Great, that's pretty much exactly what
Three20's table machinery (and TTURLRequestModel in particular) is
for.
Now the complication is this: I'd like to remember what I last saw in
that list, so that the next time that view is displayed, that content
comes up immediately, and the app checks for updates in the
background. That isn't how TTTableViewController typically works: the
refresh kicks off as soon as the view is displayed, and you get the
big loading view until it's done. So what's the best way to accomplish
this?
Some approaches that have crossed my mind so far:
- Rely on Three20's disk cache to keep the last data downloaded
around, and make the initial load quick. Maybe figure out a way to
make the caching policy keep content around longer. Trigger a forced
reload once the first load happens.
- Save the last content in the controller's view state when the app
shuts down. (But I don't think this really works, because I'm pretty
sure only views currently in the stack get persisted, and I want
persistence all over the place.)
- In my data source or model's init, before the model's load:more: is
called, load the last content from somewhere (archive on disk, Core
Data, whatever). Return YES for isLoaded, but also YES for isOutdated.
This is probably my leading candidate, but doing the loading in init
feels... dirty.
Has anyone done something similar in their application?
unread,
Nov 3, 2009, 7:36:46 PM11/3/09
to Three20
I am about to add data persistance to my application as well. I
honestly haven't given it much thought yet because I haven't started
the persistance code yet but I might have an idea you can play with.
Dump your models domain objects (or model objects or whatever you want
to call them) to disk when persistView: is called on your view
controller. You can then stick a tag in the the state dictionary with
the filename, date or any other info you may need. On restoreState:
or createModel, check _frozenState for a file and if there is one load
it up and set your model as outdated (like in your 3rd idea). That
will get your data displayed fast and kick off the update as well.
unread,
Nov 5, 2009, 7:22:53 PM11/5/09
to Three20
Sixten, have you tried anything with this yet? If so, what have you
played with? If all goes well, I will get to persistance next week
and will post my results.
unread,
Nov 5, 2009, 9:33:20 PM11/5/09
to Three20
On Nov 5, 1:22 pm, uprise78 <des...@gmail.com> wrote:
> Sixten, have you tried anything with this yet?
Right now, I'm sort of playing with trying to let Three20 do the heavy
lifting by caching the previous URL data. That there is a local-only
cache policy value gives me hope that this is possible, but I haven't
proven anything yet.
Currently, I'm up to my eyeballs in the giant state machine formed by
TTModel / TTModelViewController / TTTableViewController ("My god, it's
full of flags!"), trying to figure out what gets displayed when (in
particular, how do I get the table to display what's in the model now,
while I try to fetch new content?), and in which situations my model
gets loaded by the framework.
unread,
Nov 5, 2009, 10:14:36 PM11/5/09
to Three20
I am with you on that one. TTModelViewController has a TON of flags
and tracing through it can be tedious.
It seems like the following could work:
- load data from local cache (TTURL or disk) in init
- set the isLoaded flag to YES
- call refresh on your TTModelViewController sublcass
That will get load:more:YES called on your model IF shouldLoadMore
returns YES from your TTModelViewController subclass. That seems a
bit disconnected, but I guess shouldLoadMore could just forward to the
model.
unread,
Nov 6, 2009, 12:22:31 AM11/6/09
to Three20
On Nov 5, 4:14 pm, uprise78 <des...@gmail.com> wrote:
> It seems like the following could work:
> - load data from local cache (TTURL or disk) in init
> - set the isLoaded flag to YES
> - call refresh on your TTModelViewController sublcass
Essentially, that's what I'm doing right now. As things stand, I'm
doing most of the work in the controller's createModel method. It
creates the model and data source instances. Before hooking them up to
the controller, it calls a preload method on the model (which just
calls load:more: with TTURLCachePolicyLocal). After wiring things to
the controller (which will call refresh, which shouldn't do anything),
I explicitly call reload on the model (since at that point, I always
want to check the network).
This may, of course, turn out to be a horrible plan. :-)
unread,
Nov 11, 2009, 6:07:11 PM11/11/09
to Three20
I have tried a few different things and finally came up with this
which covers *almost* all my needs.
I made a base TTModel subclass that every model that wants to persist
its data subclasses. The only method the subclasses need to override
is cacheKey.
TTPersistableModel.h
// Returns a unique string for the cache
- (NSString*)cacheKey;
// Grabs the cacheKey and checks the TTURLCache for some data.
- (BOOL)restoreState;
// First deletes the data in the cache. Then writes domain objects to
cache after using NSKeyedArchiver to turn them into NSData
- (void)persistState;
TTPersistableModel.m
- (id)init
{
if( [self restoreState] )
{
// Set appropriate flags for successful loading of persisted data
}
else
{
// Set appropriate flags for not loading persisted data
}
}
- (void)dealloc
{
[self persistState];
// other stuff
}
Any view controllers that have TTPersistableModels will also need to
call [model persistState] in the - (void)persistView:(NSDictionary*)
state method so that app shutdowns get persisted as well. Hopefully
that all helps someone out there with the start of a persistable model
system.
unread,
Nov 11, 2009, 6:12:55 PM11/11/09
to Three20
don't get me wrong three20 is a great library. But the best way I've
found to add persistance to any app is core data. Maybe its because I
use sql a lot on my job, but core data just seems more natural.
unread,
Nov 11, 2009, 10:09:40 PM11/11/09
to thr...@googlegroups.com
The backing store for the persistance is less important in this
discussion then when and what to persist. Using CoreData, or SQLITE
or plists or writing to disk is the easy part of the equation. You
could very easily use any of them in the example above by just
overriding persistState and then save your managed object context,
write to disk, write a plist, write to sqlite, etc.
unread,
Nov 19, 2009, 1:34:14 AM11/19/09
to Three20
On Nov 11, 4:09 pm, Mike D <des...@gmail.com> wrote:
> You
> could very easily use any of them in the example above by just
> overriding persistState and then save your managed object context,
> write to disk, write a plist, write to sqlite, etc.
I mentioned that option in my initial message. Thing is that
persistView only gets called when the app is shutting down, on the
view controllers in the navigation stack. I'd really like to both a)
cache content more widely than that, and b) do it when I *get* the
content, and have plenty of time (time that I'm not guaranteed to have
during the shutdown process).
And if I'm going to add more infrastructure to call persistView more
often than that, the ease of using it instead of something else kind
of disappears.
unread,
Nov 19, 2009, 6:01:30 AM11/19/09
to Three20
I think you misread my post. It isn't persistVIEW that I am talking
about. The TTPersitableModels I made have persistSTATE that gets
called either in dealloc, by the viewController in persistVIEW, or any
other time you want to save your data.
unread,
Nov 19, 2009, 5:01:11 PM11/19/09
to Three20
On Nov 19, 12:01 am, uprise78 <des...@gmail.com> wrote:
> I think you misread my post. It isn't persistVIEW that I am talking
> about. The TTPersitableModels I made have persistSTATE that gets
> called either in dealloc, by the viewController in persistVIEW, or any
> other time you want to save your data.
Heh. Oops. Yeah, I didn't correlate your handles, and I read
persistState as a typo. Sorry!
unread,
Nov 24, 2009, 2:27:16 AM11/24/09
to thr...@googlegroups.com
I also want to have persistence implemented.
I will probably subclass TTURLRequestModel and make changes like
storing in coredata to display content now, and fetch new entries over
the network. The TTURLRequest response would process answers storing
content in the coredata.
But I would be interested about any implementation.
Reply all
Reply to author
Forward