iOS model view controller design with XML - objective-c

I am making a tabbed bar application that has a section for Quizzes (which are written in XML). I am trying to conform to the MVC paradigm so I created a parser-delegate class, and a class for a quiz object which contains an array of questions and an array of their associated answers. My problem is that my parsing method has no way of sending it's quiz objects back to the view controller. Do I need to set up a delegate for the view controller to communicate with the Parser? Or should I just set the view controller to be the delegate for the parser and not have a separate class for the parser delegate.
Note: I am using NSXMLParser..
Any input as to the best way to do this is much appreciated.

Is your problem that you UIViewController is already created when then parsing finishes, I would usually use NSNotifications for this. And then the UIViewController can wait for the NSNotification or your app delegate can and then pass it onto your ViewController. Alternatively you can use a delegate callback or a callback blocks if you are supporting iOS4+. Hope this answers your questions.

Related

Get WatchKit interface controller instances created with presentControllerWithNames:contexts:

I'm presenting a page based modal using [self presentControllerWithNames:self.controllerNames contexts:self.controllerContexts];, where controllerNames is just an NSArray of NSStrings containing my interface controllers names. The problem is that I would like to access the created controllers.
The documentations says that
WatchKit loads and initializes the new interface controllers and animates them into position on top of the current interface controller.
but I would like to have a reference to them, in order to call the becomeCurrentPage method from outside.
So, I would like to be able to save those controllers after they are created in a list, and programmatically change the page using something like [self.controllers[2] becomeCurrentPage].
Because you're allowed to provide a context when you present an interface controller, you can pass a reference to self. That way, you can establish a reference from the presented controller to its parent. Once that relationship exists, you can use things like delegation patterns to communicate.
I use this extensively in my own Watch app, and I've wrapped a lot of these mechanics in my JBInterfaceController subclass on GitHub.

Delegation coding style?

I have just a minor question about coding style.
I have a subclass of UIViewController which is a delegate to an MKMapView object. Naturally, I have an ivar in my view controller which points to said MKMapView. When I'm writing one of the callback methods mapView:didUpdateUserLocation:, is it smarter to send messages to the passed-in reference of the map view or to the ivar reference of the map view?
I'm aware these are essentially the same thing. I use the ivar reference of the map view object. What are the pros and cons of both styles?
Since you know that both MKMapView objects are one and the same thing, it doesn't matter in this particular case. The reason for the convention requiring the first delegate parameter to be the calling object is to handle the situation when a class is a delegate to more than one object. E.g. if you show two different UIAlertView's in your view controller, and the view controller is a delegate to both (a common scenario), then you want to know in the delegate methods which alert view you're dealing with.

How should a Model be implemented in iOS using Objective-C?

EDIT: Although the answers are teaching me things, I still have no
idea how I might "implement" a model. Can anyone give me an example as
to how I would create a simple model class that has a few basic
functions that make calls to NSUserDefaults or JSON web calls and how
I would access this from ANY of my view controllers?
I am just beginning iOS development and have come to the point where my app will require a Model to interact with the overall data flow between controllers, but am unsure as to how they should be implemented properly.
I understand that the View's are in the storyboard, and the Controllers are the classes associated with those views.
What is the proper way to implement a central Model for an app? Do i create a class (ie "MyModel.h/.m") and then import it from all of my view controllers?
I also see people using a UINavigationController->RootViewController as their model, is this viable?
I have googled this question and searched stack overflow for a few hours, but am now resorting to a new question.
EDIT: Although the answers are teaching me things, I still have no
idea how I might "implement" a model. Can anyone give me an example as
to how I would create a simple model class that has a few basic
functions that make calls to NSUserDefaults or JSON web calls and how
I would access this from ANY of my view controllers?
In iOS, a model (MyModel class) is usually a subclass of NSObject or in the case of Core Data (an iOS framework that helps save data to a database locally on the device) NSManagedObject. As with any model object it contains instance variables and getter / setter methods. Most object-oriented languages have a mechanism to provide encapsulation, in iOS a property provides encapsulation and the keyword synthesize automatically generates the getter and setter methods.
View is subclass from *UIView* which provides the capability for handling touch events and drawing.
The UIKit framework contains classes to draw typical interface elements such as tables (lists), buttons, textfields, sliders and more.
Controller is generally a subclass of **UIViewController** that manages a view, it is also responsible for responding to delegation messages and target-action messages.you can have a UITableViewController which is a subclass of UIViewController that manages a UITableView
TabBar and Navigation View Controllers manages an array of view controllers, but Navigation VC manages VC as a “stack” data structure and yes it is a viable usage
please have a look at Design Patterns in ios apple library resource for further reference and here is a apple sample code to understand how to create a network application using the Model-View-Controller design pattern
this tutorial teaches you how to get started with JSON , try integrating FB in your app for understanding JSON as its fun and easy
start coding NSUserDefault in your app for example
// create a standardUserDefaults variable
NSUserDefaults * standardUserDefaults = [NSUserDefaults standardUserDefaults];
// saving an NSString
[standardUserDefaults setObject:#"mystring" forKey:#"string"];
here is a good tutorial i started with..
happy coding :)

Communication between UIViewControllers

I am new with Objective-C so apologies for a dumb question.
I am opening an "options" view controller from my main view controller. Both are built in the storyboard. Before and after presenting the options controller I need to stop and start a timer on my main view controller. After the options controller is closed (a button calls dismiss) I need to send some info back to my main controller or at least let my main controller know that it needs to refresh some values.
MAIN QUESTION
What's the best way of presenting a view controller and executing some presenter's methods before and after opening?
WHAT I'VE TRIED
I found a few ways to do it, but they are all cumbersome and I assume that there must be some plausible way of doing it.
Ideally I'd like to use the segue I set up in the storyboard between the two controllers.
I managed to call the options controller programmatically by accessing the storyboard and calling instantiateViewControllerWithIdentifier. It worked but looks a bit complex.
I was not able to find a delegate method on the UIViewController to handle the dismiss event
When I was trying to access the main controller in the options controller via presentingViewController and downcasting it, I got a linkage error by including my .h file twice (not sure what are the Obj-C standards of using #define).
Appreciate your help...
For communication between ViewControllers that are weakly linked, you could use the NSNotificationCenter:
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html
Here you can send a message to all ViewControllers listening, which need to process some changes (for example an option to change the font size).
It's really easy to implement and it keeps certain ViewControllers less dependent on each other.
All of this can be done quite easily with storyboard and NSNotificationCenter, and NSCoding. In the viewDidLoad method of your main controller, put this code:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveNotification:)
name:#"Update"
object:nil];
Then create this method in the same controller:
(void)receiveNotification:(NSNotification*)notification
{
//...
}
When you want to make the main controller update from the options controller:
[[NSNotificationCenter defaultCenter] postNotificationName:#"Update" object:self];
Also, I would suggest using NSArchiving for Basic Data Persistence. Just found this tutorial, looks pretty good.
http://samsoff.es/posts/archiving-objective-c-objects-with-nscoding
Basically, create an object that can store information, code it using nscoding, and then uncode it whenever you need it. It has worked great for me.
Hope that helps!
MAIN QUESTION What's the best way of presenting a view controller and executing some presenter's methods before and after opening?
Just in case the answers above are a bit more involved than you'd like, I'll suggest that the easiest way to execute a presenter's methods before opening is to do so in the presenter's prepareForSegue method. If you need to send data to the destination view controller, you can access its properties this way:
ViewController *destinationVC = [segue destinationViewController];
An easy way to execute the presenter's methods after opening would be:
ViewControllerSubclass *previousVC = [self presentingViewController];
And then use the class or instance to execute your class or instance methods. You could do this in the destination's viewWillAppear.
Sorry if you already knew all this; it's often difficult to surmise what level of complexity is needed.
I have run into this with almost every app I have on the market. Difference is I have never decided to go down the storyboard path.
The way I have always been able to accomplish this is to provide accessor functions between the controllers. You get past the linker issue by defining the cross defined controller as simply a UIViewController type within your options view header, then including the main view controller' header only in the .m file. Now when you call a main view controller routine from your options view, you will have to cast it to the type of your main view controller!
You will also have to provide a routine in your options view that will allow you to set the variable that will hold a pointer to your main view controller to self.
Example for your optionsView
#interface optionsViewController : UIViewController{
UIViewController * myReactiveMainViewController;
}
-(void)setMyReactiveMainViewController:(UIViewController *)controller;
No in the .m file for the optionsView
#import "myMainViewController.h"
-(void)setMyReactiveMainViewController:(UIViewController *)controller{
myReactiveMainViewController = controller;
}
In any other call back to the main view controller you will have to do this:
-(void)returnToMain{
[(myMainViewController *)myReactiveMainViewController someCall:variable];
}
This example would of course assume that your myMainViewController implements a method called "someCall" that take on input parameter.
Thanks for replies.
I ended up with
Calling prepareForSegue to execute pre-transition code
Calling performSelector on presentingViewController when releasing presented view controller.
I am sure other suggestions would work too.

Getting mouse events from a View in the Parent ViewController

I need to understanding how to get the mouse events from a View in the Parent view Controller.
Lets say I have a view controller, and among many things It manages an NSMutableArray of points. I can initialize the array and pass it to the view class where it will draw to the
rect of the view.
If I have configured some typical mouse events in the view, I could add points in the view
and have them also draw.
What I don't understand is how to send that information back to the parent view controller so it can add the point to the point array.
I'm not sure if I am supposed to some how overload the methods(they do not respond in a controller) or if I can set up a delegate(Which I don't know exactly how to do for this).
Advice is greatly appreciated, and an example would be great too.
FYI this was a simple example of a more complex problem I need to solve, but the solution would still apply.
Thanks
As a newbie to Cocoa, Using custom delegate is still foreign to me, but that is the solution. Good old object message passing.
1 Create a delegate in your view class --> id mouseDelagate.
2 Create a simple protocol class with at least one method.
3 in the actual mouse event method in the view class. call the protocol method with
the delegate [mouseDelegate mouseDidMove: point ].(however you defined the method).
4 set the delegate in the view controller class in the awakeFromNib file([viewClass setMouseDelegate: self]);
5 implement the protocol method;
-(void)MouseDidMove{
NSLog(#"moving");
}
6 remember to import the protocol in both classes