How much setup is a model supposed to do? - ios

I'm using Apple's UIPageViewController template, which includes a "ModelController" class. I use this class to return individual pages in the form of a viewcontroller, but how much setup is the Model class responsible for? For example, I have a plist that contains an array of image layout info for each page. Should the model hold the entire array, and then set each viewcontroller with its specific layout information, or should each viewcontroller just get its own layout info? What exactly should the model take care of?

I would suggest to make the model as heavy as possible, and the viewcontoller as light as possible
Another thing is to use lazy initialization for the image in the viewcontollers
So ideally the model will contain the array of the names of all the images that you wish to load, and each time a new page is generated load the image and add it to the viewcontoller that you will create.
The viewcontroller will have all the information needed for it, this means that you could use this same viewcontoller as a stand alone controller outside of the context of pageviewcontroller
So the model will be only responsible to load the required variables,
the access to these files, the loading of the images will be done in the viewcontroller, in a way that viewcontroller will only receive strings as parameters, and the loading logic is done inside the viewcontoller, hence decoupling the views as much as you can

Related

What's the best way to load data for a ViewController before navigating to it?

In my application there are two view controllers that navigate to a DetailsViewController.
Right now, when the DetailsViewController appears, I fetch data from the server and display it on the UI. I dislike this because the UI is blank while the network request is going on. What I want is that the data be loaded in the previous view controllers and then passed to DetailsViewController.
Now the problem is that I have the exact same "load-data-and-then-push" code in two view controllers and I'm not sure what the most sensible way is to remove the repetition.
One idea is to have the two view controllers inherit from a common superclass which contains the loading/pushing method. I don't like this strategy because, supposing I have more ViewControllers like DetailsViewController down the line, I wouldn't like to write a loading superclass for each one.
Another idea would be to define a static method in the DetailsViewController which the two view controllers can invoke but this method contains UI related code (specifically, code to show an HUD Progressbar and a UIAlertView in case network fetch fails) which makes me uncomfortable.
I am very new to iOS and Objective-C so I might be missing something simple and obvious.
My favorite would be in this case to create a new class which handles the loading of the data (like http-request, etc.) and to create a delegate protocol for this class. This delegate callback might then be implemented in your two viewControllers which would then perform the push segue to your DetailsViewController when called. Delegation is a very nice and powerful feature, check out the documentation here: Delegation
Well, I'd better write it in the comments, but I have no reputation for that.
Imagine you are reading a json with several students information (name, year, etc.)
you can create a student object with the property that will be read and an object that will have a method that will run in the background that will be responsible for accessing your WS (JSON or whatever it is) and record this information to the student object. So if you have 10 students you will have an NSArray containing 10 students. This array is what you will for your next viewcontroller.
It is a lot of code, but you think examples easily.
If you use Storyboards you can use prepareForSegue: sender: to pass your data/model class to your DetailsViewController. If you use xib's you can do the same after instantiating the DetailsViewController and before pushing it.
If you need to load subsequent data from your server you should write a class that does this network stuff for you.
If DetailsViewController needs to load some additional data, you can use something like a loading view like Andy suggested. This is a widely used method.

Best way to simplify/refactor tableView code setup in objective-c

Every single time I need to create a simply tableview that is populated by a simple data set retrieved from my web server which has its code executed like this: SELECT * FROM table I find myself spending two blady whole hours trying to get the new view controller up and running as I try to update some variable names, copy and paste the required code from my previous view controllers. etc its ridiculous.
This is the end result for all my view controller pages where each will contain different data sets depending on the web service url being called:
Here is a link:
Link to downloading staple code .h .m and .xib files
This view controller contains a few simple elements seen throughout all data viewing pages:
UITableView
Titled header views
table indices.
refresh table control feature
data connection retrieval code
data connection succeeded
data connection failed
setting up all my bloody delegate and data source methods.
I find myself having to copy and paste all the staple code, functions, variables, properties, and IBOutlets; and to be frank, its getting ridiculously paintaking to have to repeat the same procedure over and over again but changing variable names between the different view controllers.
This is why I believe people create simple component like structures that make it easy for users to get tables setup and up and running.
How can I reduce this big chunk of code:
to something that will allow me at most do this:
Create a new view controller
Setup xib file
create appropriate IBOutlets, and hook them up to the xib.
Here's where it needs to change
I need to now simply able to write something like this the next time I am goin to create another data viewing View Controller:
[self setupTableForDataSetType:]; //This will make sure the tableView knows which data set its dealing with and so therefor know which DataModel classes to use
[self retrieveDataWithWebServerURL:]; //of course so that the connection code can make the right server connection with the URL given for the data set required.
Thats it. So that it is super easy for me to create the tableView pages desired and show the results quickly! Atm I have the same code everywhere in different view controllers.
Whats the best way to go about doing this?
Create a viewcontroller with all your customizable values as properties and reuse changing its values.
Well, subclassing is probably the best (maybe only) way. I've done something like this for tables with an index, since they're a bit of a pain to set up. I created a IndexedTableViewController that handles almost all the load. I make my app table view controller a subclass of that controller, and then I only need to feed a simple array of custom objects to the method, convertArray:usingSectionKey:secondarySortKey:(implemented in the IndexedTableViewController) which creates the sections and the index. The only other method I have to implement in my app table view controller is cellForRowAtIndexPath:(though I would have to implement more, especially didSelectRowAtIndexPath:, if I were doing more things with this table).
Your needs sound a bit more ambitious than this, so it would take quite a bit of work to make a superclass that would be general enough to work with most of your apps. A method like setupTableForDataSetType: could be quite complicated if it needs to handle many different data types.

newbie ios - where is the model in MVC?

I'm making an application that does calculations.
i have a bunch of views and view controllers.
the user clicks buttons to open up and close areas of the screen triggering animations. certain text fields are disabled when others are edited. when you click calculate a bunch of math is done, and results are animated to the screen.
the views.. are all that stuff we do with the xib file or storyboard
the controller is.. the view controller that we start with when we make an ios app.. we reference outlets and actions
3.. the model is ??? im assuming the math i perform should go in the model.. any computational stuff that isnt directly affecting the view. but where the hell is the model?! do i just create a general object and instantiate it inside the controller? In all the tutorials ive seen .. i just see people use view controllers and associated views.
The model is not something that comes standard like the rest of the things you mentioned. When building a single view application in Xcode it comes with a viewController and an appDelegate. As you noticed, the model is missing.
That is because you build your own model. A model is typically an object you instantiate in your view controller and then manipulate your data through its methods. The model will be a .h and .m file that you make to create an object that, through its methods, manipulates the data from the user input.
Because it is not good practice to have your view directly talking to your model, and vice versa, your viewController acts as a liaison. The view (buttons, labels) contains on screen data that the viewController can access. Once the viewController has access to this data, it sends that data to the model. As stated earlier, the model can be an object that you instantiate in your viewController. It does the thinking of your app and manipulates the data that your viewController sends it.
A good place to instantiate your model is in the viewDidLoad method. This ensures that when your app is ready, your model will be too.
- (void)viewDidLoad
{
[super viewDidLoad];
self.myModel = [[Model alloc] init];
}
And the reference to your model as an instance variable should be put in your private class extension at the top of your viewController's .m file.
#interface ViewController ()
#property (nonatomic) Model *myModel;
#end
As always the design is upto you. I would suggest creating a core data model with what ever model objects you require (This will generate the class files for you). Becoming familiar with core data early in your iOS learning is a great way to pick up best practices.
This should get you started. Doing it this way will also allow you to easily persist the programs state, is easy to maintain and extend.
Good luck with your iOS development.
Yes, you should create an NSObject subclass and put your calculations inside it.
Yes, your Controller should then create the Model object, and use it to coordinate the View.
The term "Model" just refers to the collection of classes that you use independently of the UI. A poorly designed app may not have a Model at all. A well designed app will keep its Controllers free from being cluttered with business logic by providing a suitable Model.
A rough guideline to keep your Model delineated from everything else is that your Model should never #import <UIKit/UIKit.h>.
Your math actually goes in your view controller. Unless you want to reuse the same functions for various other methods.
Your model would be anything you want to store to Core Data or some other persistent storage.
Basically Views talk to the UI, Models to the Database, and everything else to the controllers

Trouble understanding viewControllers in iOS

I'm new to obj-c/iOS and I'm having trouble understanding conceptually at least viewControllers. I've read a lot of the Apple Doc's, I've even used viewControllers to some extent in xCode, but I still don't quite get what they are, or what are the best ways to use them.
I've been an AS3 dev for many years so my mind works in the context of MovieClips/Sprites and the Display list to get graphics on the screen.
Ok so from my understanding...
A viewController is a kind of class that handles graphics in some
fashion and then allows you to do something with them?? What is it in it's most basic sense?
You seem to add viewControllers to a Window class, which I guess is a bit like
adding a display Object to the Display list?
What is it that a viewController does for you in it's most basic sense?
Are there certain things you definitely can't do with them or shouldn't do
with them?
Do viewControllers need to be connected in some way to the rest of the iOS framework to function (apart from being added to a window).
How exactly do they use data? (I've read up on MVC, I understand that conceptually this is a slightly different question) as I understand it you don't hardcode data into a viewController, so how does a viewController access any static data?
Let's say I just wanted to throw an image up on the screen, exactly what part would the viewController play in that process? is it just something which handles only one small aspect of that process or is it the whole show and handles everything?
Does one viewController handle multiple images? is it like it's term, a "controller" for all the images presented on screen, or does it handle one image at a time?
What is a viewControllers connection to the image(s) it handles? it contains references to them?
I'm using the Sparrow framework which is helping but I would still like to be able to get my head around what viewControllers are so I know how to use them properly.
Ha, I apologise for the above I know it must look like I'm completely confused :) thanks for any advice.
Hope this helps you:
A viewController is a kind of class that handles graphics in some fashion and then allows you to do something with them??
It's the glue between a View (Xib File) and the Data (Could be
CoreData or whatever you're using in the backend). All the UI Elements
you are using in the View you normally define as properties in the
controller to get access to them.
What is it in it's most basic sense?
You seem to add viewControllers to a Window class, which I guess is a bit like adding a display Object to the Display list?
I don't really know AS3 so I cannot compare Display lists with ViewControllers. But basically ViewControllers are there to handle
different types of transitions between the views and accessing
(setting/reading) the data which is displayed in the view.
What is it that a viewController does for you in it's most basic sense?
Like I've written above. Most basic sense they interpret what the user
does on the view and depending on the action of the user changes the
model.
Are there certain things you definitely can't do with them or shouldn't do with them?
It is always hard to keep the border between model and controller.
They are pretty close to each other. So what I normally try is to
delocate all logic stuff (like calculations, database access and so
on) this does more belong into the model part. But of couse you're
using these external classes in the controller.
Do viewControllers need to be connected in some way to the rest of the iOS framework to function (apart from being added to a window).
Well like you already have written the ViewController needs to be
connected to a view. Otherwise it would not make much sense. There are
different subtypes of UIViewController such as UINavigationController
where you probably need to overwrite some other methods to provide the
whole functionality wanted by these special subtypes.
How exactly do they use data? (I've read up on MVC, I understand that conceptually this is a slightly different question) as I understand it you don't hardcode data into a viewController, so how does a viewController access any static data?
There could be different approaches to store the data. Simplest way
would be to have the data directly stored in the UIViewController.
This could be a custom class which is the container of the data. All
changes are directly written into this class and displayed by the
UIViewController. But in most of the cases it makes sense to use
CoreData (Which is responsible for reading/writing the data into a
sqlite database). You could look at CoreData as your model and the
UIViewController gets the data from there and passes the data which
the UIViewController has received from the View back to it.
Let's say I just wanted to throw an image up on the screen, exactly what part would the viewController play in that process? is it just something which handles only one small aspect of that process or is it the whole show and handles everything?
The UIViewController would store an internal Property (UIImageView *)
which is in the Interface Builder connected with the UIImageView you
have created in the Xib file. So over these property you can change
through your Controller the image.
Does one viewController handle multiple images? is it like it's term, a "controller" for all the images presented on screen, or does it handle one image at a time?
Yes, this isn't a big problem. You can have as many images you want.
You just need to have the properties defined in the UIViewController
and linked to the View.
What is a viewControllers connection to the image(s) it handles? it contains references to them?
Yeah, its like a reference to the UIElement. You can then change
whatever property of the UIImageView you want directly from the
UIViewController
Some useful links:
Apple Official ViewController Guide
Apple Official ViewController Basics
You should have a look at Storyboards (U can use them since IOS 5.0)
I recommend you to check:
https://stackoverflow.com/questions/1939/how-to-articles-for-iphone-development-and-objective-c
Here are the answers to your questions:
No, it's doesn't handle graphics. It's the controller of the MVC design pattern. It handles the lifecycle of it's contents (for instance the views) and the data linked with.
A UIViewController is set as a root of an UIWindow. For instance, a UINavigationController is a subclass of UIViewController that stacks UIViewController in order to deal with the navigation.
Response in (1)
Try to be more specific with this question please.
As already commented, it's useful if you use the already built-in components like UINavigationController or UITabBarController.
For instance, you can have the data in instance variables and the display them in the contained UIView.
The UIView attached to your UIViewController will contain an UIImageView. Your UIViewController would have a connection with it in order to whatever changes you need, for instance, changing the image when the user press a button.
It can contain multiple UIViewsand therefore multiple UIImageViews (it's a subclass of UIView)
As commented, they would be contained on an UIImageView and would be linked programmatically or with an IBOutlet.
In a nutshell, a view controller is the controller in the MVC pattern. Please check this link before reading further so you're up to date with this pattern:
http://developer.apple.com/library/mac/#documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html
OK, basically a controller manages a collection of views. It also fetches data from your model and sets the state of the views. It's important to note that the views know nothing of your model (your data), and the model knows nothing about your views. A controller also receives events from the views and decides how to change your model accordingly. It is essentially managing the synchronisation between your views and model.
There are technologies that help automate this such as KVO and key value binding. A google search will help you there.
One more thing. No other part of your application should access your views except for the controller. So generally in an application controllers tend to communicate with each other, for example via transitions or the delegate patterns between controllers under a navigation controller. So your application backbone tends to be controllers talking to each other.

iPad - UIPageViewController - "dequeueReusableCellWithIdentifier" kind of option

I'm creating an app to show a book by using UIPageViewController (to have the default page turn animation which is very nice)
I'm maintaining all the data related to each page in form of core data.
In my MyModelController.m file, under init method, I'm fetching all the data and initializing pageData array.
But the book that I'm going to show is huge one. So, is there any way to do something like dequeueReusableCellWithIdentifier so that only required pages will be loaded into memory?
Please correct me if my expectation is wrong.
Set the initial view controller using UIPageViewController's
-setViewControllers:direction:animated:completion:
Next, implement he following UIPageViewControllerDataSource methods:
– pageViewController:viewControllerBeforeViewController:
– pageViewController:viewControllerAfterViewController:
These methods allow you to provide the UIPageViewController with the view controllers before and after the current view controller.
This way you only keep a single view controller (and corresponding model data) in memory. I'm sure it does some caching behind the scenes, but if so, that would be freed when a low memory warning was triggered.
Instead of loading your entire data model in a single array, load only the required objects for the current view controller on-demand page-by-page inside your view controller representing a single page, or inside the two datasource methods mentioned above.
If you create an new UIPageViewController-based project in Xcode 4.2, you will see the default template has code demonstrating this.
Correct me if I'm mistaken, but I believe UIPageViewController, by default, only loads the next and previous page into the memory, so you shouldn't have to worry about memory management.
Not positive I understand your question, but it sounds like you don't want to have all of the content of your book loaded as page objects. Instead of loading the entire contents of the book in your init method only load the page being displayed, then when the user "turns" the page load the next, or previous, page based on the currently displayed page.
If you are using a PDF book, you can only load the desired page and pass to the view controller when these two methods are called
– pageViewController:viewControllerBeforeViewController:
– pageViewController:viewControllerAfterViewController:

Resources