Need to grab data from server before loading a view in a tabcontroller
What im trying to do is this
1)User presses tab on tab controller
2)when that happens NSURLConnection grabs data from server
3)upon completion of getting data from server the view associated with that tab is then loaded on the screen using data from server
This would normally done sending a URL with name/value pairs to a php script on a server. Script sends back JSON data for parsing and displaying in your app.
yes im getting the data from the server but the viewdidload method of my view controller is loading the view before i grab the data, i want to load up the view after the data gets grabbed from the server
im not sure that is what is being asked for though.
Could you post the code you have in the viewDidLoad? It may be something as simple as the order in your code. Alternatively could you put a delay on viewDidLoad? have that hold up until your data has finished loading?
- (void)tabBarController:(UITabBarController *)tabController didSelectViewController:(UIViewController *)viewController {
if([tabController selectedIndex]==0){
}
else if([tabController selectedIndex]==1){
ArtistsMenuViewController *artistsMenuViewController = [[ArtistsMenuViewController alloc]initWithNibName:@"ArtistsMenuViewController" bundle:nil];
[artistsMenuViewController setInGettingArtistCount:TRUE];
artists.pageCount=1;
dispatch_queue_t queue = dispatch_queue_create("LogIn Queue", 0);
dispatch_async(queue, ^{[artistsMenuViewController callToServer;});
dispatch_async(queue, ^{[artistsMenuViewController.tableView reloadData];});
}
//when i load it like this my tableview loads as null untill i scroll and then my data loads up
}
.
what i got working was the data loads and the tableView reloads itself but i want to be able to disable the view from loading and wait untill i want to load the data, so pretty much where im writing [artistsMenuViewController.tableView reloadData]; i want to place code that will insert the view i need at the selected index of the tabController
i know this is a bit of a simple thing to suggest, but have you tried:
Code:
- (void)tabBarController:(UITabBarController *)tabController didSelectViewController:(UIViewController *)viewController {
if([tabController selectedIndex]==0){
}
else if([tabController selectedIndex]==1){
[artistsMenuViewController setInGettingArtistCount:TRUE];
artists.pageCount=1;
dispatch_queue_t queue = dispatch_queue_create("LogIn Queue", 0);
dispatch_async(queue, ^{[artistsMenuViewController callToServer;});
dispatch_async(queue, ^{[artistsMenuViewController.tableView reloadData];});
}
ArtistsMenuViewController *artistsMenuViewController = [[ArtistsMenuViewController alloc]initWithNibName:@"ArtistsMenuViewController" bundle:nil];
//when i load it like this my tableview loads as null untill i scroll and then my data loads up
}
as you can see i have moved the loading of the nib to the end of the method, may or may not work but something i would try at least. hope this helps
i know this is a bit of a simple thing to suggest, but have you tried:
Code:
- (void)tabBarController:(UITabBarController *)tabController didSelectViewController:(UIViewController *)viewController {
if([tabController selectedIndex]==0){
}
else if([tabController selectedIndex]==1){
[artistsMenuViewController setInGettingArtistCount:TRUE];
artists.pageCount=1;
dispatch_queue_t queue = dispatch_queue_create("LogIn Queue", 0);
dispatch_async(queue, ^{[artistsMenuViewController callToServer;});
dispatch_async(queue, ^{[artistsMenuViewController.tableView reloadData];});
}
ArtistsMenuViewController *artistsMenuViewController = [[ArtistsMenuViewController alloc]initWithNibName:@"ArtistsMenuViewController" bundle:nil];
//when i load it like this my tableview loads as null untill i scroll and then my data loads up
}
as you can see i have moved the loading of the nib to the end of the method, may or may not work but something i would try at least. hope this helps
IM pretty sure that wont work since your just making an object of the view controller and not placing it in the view programmatically in anyway, but ill try it out just to make sure.
Thanks
seems i ay have made a hasty copy paste there, i should have left it just above that curly bracket, not outside it so like this:
Code:
- (void)tabBarController:(UITabBarController *)tabController didSelectViewController:(UIViewController *)viewController {
if([tabController selectedIndex]==0){
}
else if([tabController selectedIndex]==1){
[artistsMenuViewController setInGettingArtistCount:TRUE];
artists.pageCount=1;
dispatch_queue_t queue = dispatch_queue_create("LogIn Queue", 0);
dispatch_async(queue, ^{[artistsMenuViewController callToServer;});
dispatch_async(queue, ^{[artistsMenuViewController.tableView reloadData];});
ArtistsMenuViewController *artistsMenuViewController = [[ArtistsMenuViewController alloc]initWithNibName:@"ArtistsMenuViewController" bundle:nil];
}
//when i load it like this my tableview loads as null untill i scroll and then my data loads up
}
if that does work then thats about the 50th typo of my day grr!!!
seems i ay have made a hasty copy paste there, i should have left it just above that curly bracket, not outside it so like this:
Code:
- (void)tabBarController:(UITabBarController *)tabController didSelectViewController:(UIViewController *)viewController {
if([tabController selectedIndex]==0){
}
else if([tabController selectedIndex]==1){
[artistsMenuViewController setInGettingArtistCount:TRUE];
artists.pageCount=1;
dispatch_queue_t queue = dispatch_queue_create("LogIn Queue", 0);
dispatch_async(queue, ^{[artistsMenuViewController callToServer;});
dispatch_async(queue, ^{[artistsMenuViewController.tableView reloadData];});
ArtistsMenuViewController *artistsMenuViewController = [[ArtistsMenuViewController alloc]initWithNibName:@"ArtistsMenuViewController" bundle:nil];
}
//when i load it like this my tableview loads as null untill i scroll and then my data loads up
}
if that does work then thats about the 50th typo of my day grr!!!
What im saying is that your just making an object, you still would have to place the viewController on the screen programmatically using for instance
[self.navigationController pushViewController:artistsMenuViewController animated:TRUE];
which is what im trying to do only with a tab controller not a navigation controller
but i dont see anywhere in your code that is pushing the view controller, or however you want to be doing it. so what i am suggesting is you initialize and load after you have done your webservice call rather than before like you had in your post of code.
Fo instance when i set my activity indicator running i initialize and start it at the beginning of my ViewDidLoad, then my xml parsing code does its dirty work, then at the end of that code, and before i close my ViewDidLoad method i call a stop to the activity indicator.
I know they are two different things but what i am saying is that sometimes to get the order of things like this working the order that your code is in can and does make a difference. And like i said it may or may not work anyways.
If you cant get that to work have you looked into notifications? Maybe you could set one up to watch for when your webservice call finishes and then use that notification to load the view instead? If Notifications will work for you then i cant help much more as so far i havnt had much need for them so dont really know much about them
but i dont see anywhere in your code that is pushing the view controller, or however you want to be doing it. so what i am suggesting is you initialize and load after you have done your webservice call rather than before like you had in your post of code.
Fo instance when i set my activity indicator running i initialize and start it at the beginning of my ViewDidLoad, then my xml parsing code does its dirty work, then at the end of that code, and before i close my ViewDidLoad method i call a stop to the activity indicator.
I know they are two different things but what i am saying is that sometimes to get the order of things like this working the order that your code is in can and does make a difference. And like i said it may or may not work anyways.
If you cant get that to work have you looked into notifications? Maybe you could set one up to watch for when your webservice call finishes and then use that notification to load the view instead? If Notifications will work for you then i cant help much more as so far i havnt had much need for them so dont really know much about them
Ill look into notifications ive heard they are very usefull but never used them before , im using a tabBarController project, and in each tab is a navigation controller. so in my mainWindow i have the tabController and on tab 1 i have selected artistMenuViewController so thats how its loading whenever i touch the tab on the bottom of the screen . But what i did now was Take it off the mainView and now its not loading(which is what im guessing i have to do now), so all i have to figure out now is how to insert that viewcontroller on to that tabs navigation controller which is what im trying to figure out now.
so if i am understanding, all you need now is how to "push" your new viewController onto the current tabs navigation controller?
If that is the case, then you have achieved points 1, and 2 from the original post, and now half of point 3? the tab is displaying after your data has arrived but hasnt got the viewController displayed that you want?
Which would possibly bring me to the conclusion that you want to add the new viewController from tab 1's class rather then your rootViewController class?
for instance i have a tabbar and nav bar app. i load all my tabbar views our of my rootview. then within these i have to push more view controllers onto my stack to get deeper into my table view, so outside of the rootViewController i have to push onto the navigation stack. So i go from: RootView to Sales to CustomerList to CustomerDetailList etc etc.to get to the sales i have to add to the stack from Sales.m not from my rootContoller.m
so if i am understanding, all you need now is how to "push" your new viewController onto the current tabs navigation controller?
If that is the case, then you have achieved points 1, and 2 from the original post, and now half of point 3? the tab is displaying after your data has arrived but hasnt got the viewController displayed that you want?
Which would possibly bring me to the conclusion that you want to add the new viewController from tab 1's class rather then your rootViewController class?
for instance i have a tabbar and nav bar app. i load all my tabbar views our of my rootview. then within these i have to push more view controllers onto my stack to get deeper into my table view, so outside of the rootViewController i have to push onto the navigation stack. So i go from: RootView to Sales to CustomerList to CustomerDetailList etc etc.to get to the sales i have to add to the stack from Sales.m not from my rootContoller.m
do you follow me?
joe
Yes im following you so im guessing i have to place my artistMenuViewController in the rootview of my navigation controller. I have done this about a minute ago using [artistNC setViewController:artistArray];,where artistNS is an IBOUtlet in my mainView where i setup my tabbarController and artistArray just holds one viewController and placing it in the viewController array of my navagation controller,
this works but now im getting a lag issue between the actual grabbing of the data and then loading it on the screen so im going to look into it further, its about a 5 second delay from when the data is grabbed and loaded and when the tableViews ,- (UITableViewCell *)tableViewUITableView *)tableView cellForRowAtIndexPathNSIndexPath *)indexPath is running. So i think i got exactly how to load the controller. Am i correct?
You are saying that everything is working as you expect - but you are having a delay issue involved not that the workflow is correct?
I have a few lag points on my app, and they seems to be server/internet speed issues rather than my apps fault (this has been determined as the lag is different each time) If you are in the same boat as me with that then all i can suggest is an activity indicator to show the user that something is at least working its socks off for the user!
You are saying that everything is working as you expect - but you are having a delay issue involved not that the workflow is correct?
I have a few lag points on my app, and they seems to be server/internet speed issues rather than my apps fault (this has been determined as the lag is different each time) If you are in the same boat as me with that then all i can suggest is an activity indicator to show the user that something is at least working its socks off for the user!
Ya i think i am also , but what i do is i have NSLogs that show me where i am in my program so i know the delay is from when the data is done being grabbed and then trying to load. Do you know of a way i can look at all functions being ran? possibly using the instruments of some sorts?
Yeah, everyone wants it NOW! Hopefully as mobile device get faster access, these problems will go away.
5 seconds doesn't seem long, but I know users and they get bored after 2 seconds. A "loading bar" or some type of spinner might help. I'm not 100% sure about iOS, but in Android we can spin-off another thread from the main app's thread; could that possibly be done and speed things up?
Can you make multiple calls to server and get "more" smaller chunks of data? It seems counter intuitive to make more calls, but you never know.
How about caching some of the data?
Have you tired commenting-out all your NSLogs to see if they might be eating some clock? I know, you probably put the NSLogs in to see why it was slowing down LOL
i actually figured out what i was doing wrong since my code was placing the controller on the screen from another thread it was taking longer then it was supposed to. What i read online was all the user interface updates must be done on the main thread so i used this code instead of the one up above and now theres no delay. As soon as the data is grabbed my tableview loads up fine.
The first queue i create runs the parser in the background and the second queue i create updates the user interface on the main thread. So im sure it was because i was trying to update the userinterface in the background and not on the main thread,which was causeing my lag in the program