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.