What is the correct location (MVC-wise) for iOS app event handlers? - iphone

I am writing an iOS app that registers for call events (not-in-call, dialing, disconnected etc).
I have code that registers for the call event, but I'm not sure where is the correct location to put it (in the Model? In the Controller?).
All samples place the code in the app delegate, but that seems awkward. After all, the app delegate is not part of MVC.
Thanks!

After all, the app delegate is not part of MVC.
I could argue, but I have a feeling you worry too much about the "correct design". If you want to change the place of these event handlers, I'd put them somewhere in the controller (certainly not model, because they are not data providers...)
But after all, why are they "awkward" in the app delegate? That's exactly why the singleton application object has a delegate: system-wide events shall notify the app (and its delegate), respectively, and not some internal part of the application. That's mixing things up.

Since these events control parts of your application the best answer would be: in a controller.
This Apple style to put lots of stuff in the delegate is indeed bad coding practice.

Related

Aspect Oriented Programming in Objective-C for iPhone

Could anyone help me first when I can use AOP, and what is it exactly in an iphone programming.
I need to access to the app project source code and call some of the functions and be notified their views loaded from outside like a library.
I found these so far, but looks very complicated to follow. Some doesnt build or the source code removed.
https://github.com/ndcube/AOP-for-Objective-C
https://github.com/moszi/AOP-in-Objective-C
ACAspect on cocoadev
If you have a specific view in a view controller and want to be notified when it is loaded, you can register for a KVO notification when that instance variable (the outlet) changes.
You'll want to read up on Key Value Observing in Cocoa. There are several methods you will need to learn how to use.
Do a search on "Introduction to Key-Value Observing Programming Guide" in the XCode docs and read that section.
Make sure you balance each call to addObserver:forKeyPath:options:context: with a call to removeObserver:forKeyPath:, or your app may crash after the observing object is deallocated.

Universal iOs Applications and Windows based application in Xcode

I am creating a Universal iOs application as part of an assignment (iPad and iPhone :) ).
Naturally, they have a UI which I have been accustomed to create through the NIB files, using the fancy drag and drop schemes. This obviously seems like a great strategy when you are making a dedicated iOS device application.
However, with the universal application, I notice that this strategy can be a challenge since the 2 UIs differ and human error can promote a lack of consistency in the two UI's + double the work!!!
I noticed the solution to the assignment I am doing has the UI created through the AppDelegate file, I have never really done this, and from this stems the questions:
What is the appDelegate files for anyways?
Is it the way to create the UI for the Universal application through the App delegate? Or do you people still create the UI's through the NIB files meticulously for both iPhone and iPad?
P.S: Side question: This assignment requires me to create a Windows based application vs a View based application which is what I have naturally learnt to do. I understand a Windows based App can grow into a view based application and vice versa. However, I do not understand when you should choose to create a Windows based application?
The AppDelegate in Cocoa is your central Singleton that controls the app workflow. It's used by the underlying Framework to start the application, signal runtime envrionment changes and terminate the app. Being a singleton, it's always there and easy to reference ([UIApplication applicationDelegate]) and it loads up your first view controller.
It's generally common to let the application delegate keep refernces to model and controller objects. But what you describe, the whole UI programmed through the appDelegate, is bad style.
No matter if you use NIB's or you code your UI by manually adding UIElements to the view in code, you should do so in ViewController. Generally, the appDelegate will call the first view controller and that viewcontroller will call all view controller afterwards.

How mvc pattern is implemented in iOS user interface? (view-based XCode temlpate)

I'm new to iphone development. There's a lot of books on this topic available. But most of the beginner's guides are mostly concerned with Interface Builder usage and lack the information about existing built in XCode code templates or something that could help me in understanding MVC implementation in code. I found that it is possible to write working iOS program without ViewController at all. Well, it seems to me like that after working with the sample code called ViewTransitions.
So, the question is - why is that possible to avoid ViewController implementation in a program that has an interface with a button? If the answer is going to be too long, could you please recommend kind of tutorial or manual covering this topic.
Thanks in advance.
#user697562's answer is essentially correct: in the case of ViewTransitions, the role of the controller is played by the app delegate. The app does next to nothing -- it just switches betweeen two views to demonstrate several possible transition effects -- so a UIViewController isn't really needed there.
Notice that there's also nothing in ViewTransitions that you could really call a model object. If you're looking for a strong example of MVC, ViewTransitions isn't the best project to look at. Other sample projects, such as TheElements, give a better demonstration of MVC in action.
There is a concept called delegation. A concept which helps maintain MVC. It helps to keep the model separate from controllers. For eg: - UITableView/UICollectionView , which knows how to display the data and other ui stuff.
But it does not know which cell to display or what data to display at a particular index. And this is where delegation and the delegate object comes into place. UICollectionView handles all the view part whereas all the non view part is handled by the delgate object, which gives the required data for the view. This way a delegate(usually a separate view controller) acts as a data source and UICollectionView as a ui renderer.
in ViewTransitions, there IS an App Delegate, which is kind of your sole "controller". Even ViewTransitions has:
transition.delegate = self;
IOS is a bit different from some frameworks in that you aren't as "in control" of what is going on. It often uses a delegation model where you set your code as the delegate, but it (IOS) is in control. Still, you can write in MVC style, it's just your "C" isn't fully in charge.

Fix UIScrollView to pass events UP the chain rather than DOWN

UIView's that don't handle their events pass them up the chain. By default, this passes them to their parent View, and if not handled (ultimately) to their parent UIViewController.
UIScrollView breaks this (there's lots of questions on SO, variations on the theme of "why does my app stop working once I add a UIScrollView?)
UISV decides whether the event is for itself, and if not, it passes it DOWN (into its subviews); if they don't handle the event, UISV just throws it away. That's the bug.
In that case, it's supposed to throw them back up to its own parent view - and ultimately parent UIVC. AFAICT, this is why so many people get confused: it's not working as documented (NB: as views are documented; UISV simply is "undocumented" on this matter - it doesn't declare what it aims to do in this situation).
So ... is there an easy fix for this bug? Is there a category I could write that would fix UISV in general and avoid me having to create "fake" UIView subclasses who exist purely to capture events and hand them where they're supposed to go? (which makes for bug-prone code)
In particular, from Apple's docs:
If the time fires without a significant change in position, the scroll view sends tracking events to the touched subview of the content view. If the user then drags their finger far enough before the timer elapses, the scroll view cancels any tracking in the subview and performs the scrolling itself.
...if I could override that "if the timer fires" method, and implement it correctly, I believe I could fix all my UISV instances.
But:
- would apple consider this "using a private API" (their description of "private" is nonsensical in normal programming terms, and I can't understand what they do and don't mean by it)
- does anyone know what this method is, or a good way to go about finding it? (debugging the compiled ObjC classes to find the symbol names, perhaps?)
I've found a partial answer, that's correct, but not 100% useable :(.
iPhone OS 4.0 lets you remotely add listeners to a given view, via the UIGestureRecognizer class. That's great, and works neatly.
Only problem is ... it won't work on any 3.x iPhones and iPod Touches.
(but if you're targetting 4.0 and above, it's an easy way forwards)
EDIT:
On OS 3.x, I created a custom UIView subclass that has extra properties:
NSObject *objectToDelegateToOnTouch;
id touchSourceIdentifier;
Whenever a touch comes in, the view sends the touch message directly to the objectToDelegateToOnTouch, but with the extra parameter of the touchSourceIdentifier.
This way, whenever you get a touch, you know where it came from (you can use an object, or a string, or anything you want as the "identifier").

App development: Always subclass, always load from NIBs - caveats?

This is Cocoa Touch (et al), iPhone, XCode only.
After completing my first commercial iPhone app, I'm struggling a bit to find a way to start and expand an app from scratch which gives the most linear development (i.e., the least scrapping, re-write or re-organization of code, classes and resources) as app specs change and I learn more (mostly about what Cocoa Touch and other classes and components are designed to be capable of and the limitation of their customization).
So. File, New Project. Blank window based app? Create the controllers I need, with .xib if necessary, so I can localize them and do changes requested by the customer in IB? And then always subclass each class except those extremely unlikely to be customized? (I mean framework classes such as UIButton, CLLocation etc here.)
The question is a generic 'approach' type question, so I'll be happy to listen to handy dev practices you've found paid off. Do you have any tips for which 're-usable components' you've found have become very useful in subsequent projects?
Clients often describe programs in terms of 'first, this screen appears, and then you can click this button and on the new screen you can select... (and so on)' terms. Are there any good guides to go from there to vital early-stage app construction choices, i.e. 'functions-features-visuals description to open-ended-app-architecture'?
For example, in my app I went from NavBar, to Toolbar with items, to Toolbar with two custom subviews in order to accommodate the functions-features-visuals description. Maybe you have also done such a thing and have some advice to offer?
I'm also looking for open-ended approaches to sharing large ("loaded data") objects, or even simple booleans, between controllers and invoking methods in another controller, specifically starting processes such as animation and loading (example: trigger a load from a URL in the second tab viewcontroller after making sure an animation has been started in the first tab viewcontroller), as these two features apply to the app architecture building approach you advocate.
Any handy pointers appreciated. Thanks guys.
Closing this up as there's no single correct answer and was more suitable for the other forum, had I known it existed when I asked :)
If you want to know the method I ended up with, it's basically this:
Window-based blank app
Navigation Controller controls all, whether I need to or not (hide when not used)
Tab Bar Controller if necessary
Connect everything <-- unhelpful, I know.
Set up and check autorotation, it might get added to some view later.
Add one viewcontroller with xib for each view, you never know when they want an extra button somewhere. It's easier to copy code than make the max ultra superdynamic adjustable tableviewcontroller that does all list-navigation, etc.
Re-use a viewcontroller only when just the content differs in it, such as a detail viewcontroller.
Minimize code in each viewcontroller by writing functions and methods and shove them in a shared .m
Everything that's shared ends up in the App delegate, except subclassed stuff.
Modal viewcontrollers are always dynamically created and never have an xib.