Ravi shankar Ravi shankar - 1 month ago 17
Objective-C Question

Navigating between View controllers?

In my Iphone application I am trying to navigate from one table view controller to next table view controller. Problem I am facing is that I have to fetch data using http request and then parse this data when the user select a cell. I am able to fetch and parse the data but the view controller is not waiting for the data to parsed and the next view controller is shown (which is empty). How to over come this problem.

indexSelected = [NSString stringWithFormat: @"%d",[indexPath row] ];

[[MySingletonClass sharedMySingleton] doAnAuthenticatedAPIFetch_Subscriber_Detail : indexSelected];

SubscribersDetailViews2 *viewController = [[SubscribersDetailViews2 alloc] initWithNibName:@"SubscribersDetailViews2" bundle:nil];

[[self navigationController] pushViewController:viewController animated:YES];

[viewController release];

Answer

This is what you do:

indexSelected = [NSString stringWithFormat: @"%d",[indexPath row] ];

SubscribersDetailViews2 *viewController = [[SubscribersDetailViews2 alloc] initWithNibName:@"SubscribersDetailViews2" bundle:nil];

[[MySingletonClass sharedMySingleton] doAnAuthenticatedAPIFetch_Subscriber_Detail:indexSelected delegate:self];

[[self navigationController] pushViewController:viewController animated:YES];

[viewController release];

You define a protocol that your view controller conforms to and when the fetching and parsing of data is done you call a method on the delegate to let the view controller know that the data is ready to be displayed.

If you need more information on how to do this, leave a comment.

EDIT: So here's how to declare and use a protocol. I'm going to try to keep it as simple as possible. I'm not sure if I like your naming convention, but I'll still use it for this example.

So let's get down to the code. This is how you declare a protocol:

@protocol MySingletonClassDelegate <NSObject>

@optional
- (void)didDoAnAuthenticatedAPIFetch_Subscriber_Detail_WithData:(NSArray *)data;

- (void)failedToDoAnAuthenticatedAPIFetch_Subscriber_Detail_WithError:(NSError *)error;

@end

Again, I'm not too fond of the naming convention. You shouldn't have underscores in objective-c method names.

The protocol should be defined in MySingletonClass.h before the declaration of MySingletonClass.

I declared two methods in the protocol, one for delivering the data and one for delivering an error if it fails, so that you can notify the user that it failed.

To use the protocol you need the following:

@interface SubscribersDetailViews2 : UITableViewController <MySingletonClassDelegate>

You also need to implement the methods declared in the protocol, but I'll leave that implementation to you.

Since the fetching of data already seems to be happening in the background I don't think I'll need to explain how to do that. One important thing to remember is that you want to execute the delegate methods on the main thread. Here's the code to do that:

- (void)doAnAuthenticatedAPIFetch_Subscriber_Detail:(NSUInteger)index delegate:id<MySingletonClassDelegate>delegate {
    // Fetching data in background
    if (successful) {
        [self performSelectorOnMainThread:@selector(didDoAnAuthenticatedAPIFetch_Subscriber_Detail_WithData:) withObject:data waitUntilDone:NO];
    } else {
        [self performSelectorOnMainThread:@selector(failedToDoAnAuthenticatedAPIFetch_Subscriber_Detail_WithError:) withObject:error waitUntilDone:NO];
    }
}

Just to be clear the // Fetching data in background is supposed to be replaced by your code. I assume that your code produces the variables (NSArray *data, NSError *error, BOOL successful) that I use.

That's about it, if you need clarification on anything let me know.

Comments