Three20 is a nice iPhone library, but the documentation is pretty much limited to the TTCatalog example app code…one thing that’s left as an exercise for the reader is the implementation of a datasource that fetches its data over the network and how it interacts with its associated TTTableViewController.
One approach to this problem is to subclass a canned datasource, which gets us a bunch of stuff for free right off the bat:
@interface MyDataSource : TTListDataSource<TTURLRequestDelegate> {
@private
BOOL _loading;
BOOL _loaded;
}
You’ll want to provide meaningful implementations of accessors like loadedTime:, isLoading:, isLoadingMore:, isLoaded:, etc. Your controller will query the datasource using those selectors to know what state to show (e.g. loading, error, data, no data).
Write a load:nextPage: implementation that hits the network:
- (void)load:(TTURLRequestCachePolicy)cachePolicy nextPage:(BOOL)nextPage {
TTURLRequest *request =
[TTURLRequest requestWithURL:@"http://test.com/test.json" delegate:self];
request.cachePolicy = cachePolicy;
request.response = [[[TTURLDataResponse alloc] init] autorelease];
request.httpMethod = @"GET";
[request send];
}
Write a requestDidFinishLoad: implementation that pulls JSON out of the response (maybe using Stig Brautaset’s very nice JSON framework) and let your controller know that data’s available via dataSourceDidFinishLoad:.
- (void)requestDidFinishLoad:(TTURLRequest*)request {
TTURLDataResponse *response = request.response;
NSString *json = [[NSString alloc] initWithData:response.data encoding:NSUTF8StringEncoding];
// Load up self.items with json data however you'd like
[json release];
_loading = NO;
_loaded = YES;
[self dataSourceDidFinishLoad];
}
Don’t forget to implement requestDidStartLoad:, request:didFailLoadWithError:, and requestDidCancelLoad: and have them notify any interested delegates of the request’s status. Here’s an example:
- (void)request:(TTURLRequest*)request didFailLoadWithError:(NSError*)error {
_loading = NO;
_loaded = YES;
[self dataSourceDidFailLoadWithError:error];
}
In your controller, createDataSource: might look like this:
- (id<TTTableViewDataSource>)createDataSource {
MyDataSource *dataSource = [[[MyDataSource alloc] init] autorelease];
[dataSource.delegates addObject:self];
[dataSource load:TTURLRequestCachePolicyDefault nextPage:NO];
return dataSource;
}
Have fun out there.
Update, April 11 10:30 AM EDT
I’ve added a new post with a downloadable example project and (finally) cleaned up the above code. I apologize for previous typos; I really should make sure the code I post actually compiles instead of writing/tweaking it in a wordpress edit window.
Update, October 3 9:30 AM EDT
It’s come to my attention that some people are still using this code – please don’t! It was based on three20 as it existed back in March/April 2009 and is now very much out-of-date. If you’re looking for current and correct three20 sample code, Keith Lazuka’s github has what you need. Thanks!
7 Comments
Nice write up. Do you have a full example of a json datasource you’d be willing to post?
Do you have a complete datasource example that you’d be will in to post? Thanks!
Hey,
Thankyou very much for the helpful article. I’ve followed it with one of my projects but I’m currently getting an error in the createDataSource method.
When I add the line [dataSource.delegates addObject:self], the compiler complains with: “error: request for member ‘delegates’ in something not a structure or union”.
I’m a bit unsure what this means. I don’t have a delegates property in my DataSource but I didn’t notice one in your tutorial either.
Cheers,
Rob
Hey thanks a ton for the tutorial!!
My only confusion is lies with [dataSource.delegates addObject:self]
My app says “request for member delegates is something not a structure… etc etc”
What do i need to do?
Sorry about that – was careless in posting the code snippets and the protocol bits were interpreted as HTML
Anyway, I’ve updated the examples and will try to post a full example project later tonight or tomorrow (busy at work at the moment). For now, see if your problems are solved by extending TTListDataSource like this:
@interface MyDataSource : TTListDataSource<TTURLRequestDelegate>
Hey man any chance you could post that example? Would be a huuuuge help.
Thanks
Matt, I’ve added a new post which includes a downloadable example project. HTH
One Trackback
[...] techniques consisted of searching the web for blog posts (most of them outdated like mine since Three20 has gone through some pretty big refactorings), reading the source, and [...]