Reputation:
In my app, some studies I've done show that when the user views an article, the vast majority of the time (85%+) they load the accompanying comments view controller that goes along with the article.
I'd love to load this view controller while they're reading the article, so when they tap the comments button to transition to the comments view controller the view controller is ready without any loading times.
How would I go about accomplishing something like this? At the moment when the user taps the button I call performSegueWithIdentifier:
and pass it the identifier I set in the Storyboard.
And obviously, for the cases where the user decides to go back to the root view controller (say, a list of articles) I'd want to cancel the loading of that comments view controller as it would be wasteful to continue at that point.
Upvotes: 1
Views: 229
Reputation: 508
The solution I'm about to describe is a bit of a hack - it doesn't really conform to the proper model-view-controller design pattern that Ryan mentioned. That being said, it might give you an idea about how to proceed. Perhaps you can improve on it to make it cleaner.
First, define a @protocol
in the App Delegate. Let's call this protocol CommentQueryDelegate
; it should define a method called -(void)handleCommentQuery
. Also give your App Delegate a strong property to store the comment data and a weak property to store a delegate object, like so:
@property (nonatomic, strong) NSMutableArray* arrayOfComments;
@property (nonatomic, weak) id<CommentQueryDelegate> commentQueryDelegateObject;
Make sure to initialize the both of these properties to nil
.
Somewhere in the article view controller, use dispatch_async()
to asynchronously query your database and retrieve the comments while the user is reading the article:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
// query your database here
appDelegate.arrayOfComments = [NSMutableArray array];
[appDelegate.arrayOfComments addObject:@"someComment"];
[appDelegate.commentQueryDelegateObject handleCommentQuery];
}
If the query is completed before the user segues into the comments view, the handleCommentQuery
message will be sent to the nil
object, which will have no effect.
Now, in the comments view controller's viewDidLoad
method, set the commentQueryDelegateObject
property of the App Delegate to self
. You will need to specify that the comments view controller conforms to the comment query protocol. Next, check to see if the App Delegate's arrayOfComments
property is nil
. If it isn't, great - display the comments immediately. Otherwise, display a UIActivityIndicatorView
.
Implement the -(void)handleCommentQuery
method in your comments view controller. This method should disable the activity indicator and display the comments.
One final thing to consider - the strong pointer to the arrayOfComments
object will keep it from being deallocated, so you should set this pointer to nil
once you're done with your article view controller.
Upvotes: 0
Reputation: 1931
If you keep the data model separate from the UI, you shouldn't have any trouble creating the views on the fly, and almost nothing to gain from creating them earlier.
A reasonably standard approach is to bring the view in with blank or filler data, and have the data call go out to the middle tier, with asynchronous handlers processing callbacks.
This is much easier with the block based completion handlers available in the iOS 7 flavored NSURLSession, and only slightly harder with NSURLConnection (which listens for responses on the main thread, but can be thrown into the background once you catch the response).
So my advice would be to focus on backgrounding the data calls and responses, and strongly differentiate between displaying UI and populating the UI with data. If your data manager is separate from your View Controller, nothing is stopping you from "pre-fetching" the data a little early, and then potentially having it ready when the ViewController needs it. It's a perfectly normal load balancing / customer experience technique for high value data.
Upvotes: 2