I have a UISplitViewController
which implements a masterNavigationController
and a detailNavigationController
, basic from the XCode template.
The masterNavigationController
calls an other NSObject
called "API" which in its turn uses ASIHTTPRequest
to retrieve certain JSON data from an server.
Everything is fine and dandy, until I the call from the request starts. It shows the GUI of iPad and crashes straight after with an EXC_BAD_ACCESS
. The error message I get is the following:
2012-10-10 21:13:42.357 myapp[24409:c07] Splitview controller is expected to have a view controller at index 0 before it's used!
I have tried different things to try to solve the issue, one of them being setting the SplitViewController delegate after settings the view controllers, an other is using the NetworkQueue instead.
This is the code of the masterNavigationController
:
[...]
- (void)viewDidLoad
{
[UIHelper setNavigationBackBackground:self.navigationController.navigationBar widePage:NO];
[UIHelper setViewBackground:self.parentViewController.view widePage:NO];
[UIHelper setTableViewStyle:self.tableView];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
API *api = [[API alloc] init];
[api setDelegate:self];
[api setDidFinishSelector:@selector(didFinish:)];
[api getCommingRetrievals];
}
[...]
The AppDelegate:
[...]
MasterViewController *masterViewController = [[MasterViewController alloc] initWithStyle:UITableViewStylePlain];
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
masterViewController.detailViewController = detailViewController;
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.view.opaque = NO;
self.splitViewController.view.backgroundColor = [UIColor clearColor];
self.splitViewController.viewControllers = @[masterNavigationController, detailNavigationController];
masterViewController.managedObjectContext = self.managedObjectContext;
self.splitViewController.delegate = detailViewController;
self.window.rootViewController = self.splitViewController;
[self.window makeKeyAndVisible];
[...]
This is the API object's code:
- (void)getCommingRetrievals
{
[self getRetrievalsForDate:[NSDate date]];
}
- (void)getRetrievalsForDate:(NSDate*)date
{
NSString *stringFromDate = @"";
if (date != nil)
{
// Set date string
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyyMMdd"];
stringFromDate = [formatter stringFromDate:date];
}
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/bookings/%@", API_BASE_DOMAIN, stringFromDate]];
[self callApi:url requestMethod:@"GET"];
}
#pragma mark -
#pragma mark API methods
- (void)callApi:(NSURL*)url requestMethod:(NSString*)requestMethod
{
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setRequestMethod:requestMethod];
[request setDelegate:self];
[request setDidFinishSelector:@selector(requestFinished:)];
[request setDidFailSelector:@selector(didFailWithError:)];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
if (self.delegate && [self.delegate respondsToSelector:didFinishSelector]) {
[self.delegate performSelector:didFinishSelector withObject:self];
}
}
If I comment out the line [request startAsynchronous];
, the app doesn't crash.
What am I missing here, and how can I solve the problem?
Check that your UISplitViewController has been passed 2 view controllers.
Other than that, some idiomatic stuff:
This should go right at the beginning of any setting up stuff:
[super viewDidLoad];
e.g. `[super viewDidLoad]` convention
And consider using another framework than ASI. It's a dead library. AFNetworking, MKNetworkingKit or RESTKit are good alternatives.