How to detect changes to Address Book after ABPersonViewController presentation - iphone

I have two view controllers that allow changes to the Address Book.
The first one lets you add or create an entry based on an ABRedordRef or edit an existing ABRecordRef, by presentation of either ABUnknownPersonViewController or ABPersonViewController.
The second one is a standard ABPeoplePickerNavigationController that allows you to view/edit any of the contents of the Address Book.
Both views are accessible easily accessible to the use via the main application UITabBarController.
How can I determine that changes were made by either view controller, so that I can force data dependency changes to a third separate view controller.
I thought that I saw a notification center message that I could subscribe to, but I can't seem to find it again...
I don't care if the notification center is the method that should be used, or a delegate protocol or... whatever, I don't care, I just need to know how to detect the change or the need to re-sync with the Address Book.
Can someone Please point me in the right direction.
Thank you.

You can subscribe to address book changes via ABAddressBookRegisterExternalChangeCallback
See official documentation

Related

Need of Delegation in iPhone Development or Objective C

What is the need of delegation in iphone/ipad development or objective C?
I read so many articles on it. All were telling how to implement the concept, but no one was telling why we need to implement that, in which case we should implement it.
Suppose you want to implement Login functionality in your app ... now you won't show Login screen every time you run your app.. only when it is first started and you don't have a login and password...
So in this case..
Your app starts :
View 1 loads (default view )
You check no Login name is there..
You load a new view..(Login View ) .
User enter his details..you get your login and password...
now you want to go back to default view and load the main app with
the names the user entered in Login View....
Now you will use delegate to pass these information(login details) back to default View..so that it knows..its details. now there are many different ways to do these things...like notification and singleton classes.. but when you want to sent more than 3-4 sets of data.. it is best to use delegates
Think of all the components that iOS and Cocoa provide you with. TableViews, TextFields, PopOvers...etc.
When the developers wrote these components, they couldn't possibly know all the various implementations that us developers were going to create using these components. But we need somehow to communicate with them in a generic way.
These components use delegates. The delegate is an implementation independent way of describing some behaviour that your component can conform to.
When UITableView need to find out what is the height of the rows, the UITableView only needs to know about UITableViewDelegate. It doesn't need to know about MyTableViewController, JohnsTableViewController, BobsTableViewController... etc.
So the delegate is decoupling the component from the implementation and the type.
Decoupling is a good thing. It makes maintaing and changing code a lot easier, and makes code reusable.
Delegation is a simple and powerful pattern in which one object in a
program acts on behalf of, or in coordination with, another object.
The delegating object keeps a reference to the other object—the
delegate—and at the appropriate time sends a message to it. The
message informs the delegate of an event that the delegating object is
about to handle or has just handled. The delegate may respond to the
message by updating the appearance or state of itself or other objects
in the application, and in some cases it can return a value that
affects how an impending event is handled. The main value of
delegation is that it allows you to easily customize the behavior of
several objects in one central object.
SOURCE
Use a delegate if you want to talk to only one object. For example, a
tableView has a delegate - only one object should be responsible for
dealing with it.
Use notifications if you want to tell everyone that something has
happened. For example in low memory situations a notification is sent
telling your app that there has been a memory warning. Because lots of
objects in your app might want to lower their memory usage it's a
notification.
this was an answer posted to my question here
There are two key benefits of delegation: customizing objects without subclassing, and improving encapsulation.
Customization without subclassing is a benefit you get from many of the Cocoa and Cocoa-Touch APIs using the delegate pattern. If they didn't do so, you might have to subclass a UITableView every time you wanted to change its behavior by using different types of cells or a different data source. Instead, you just set the table view's delegate and data source to customize its behavior.
As for encapsulation, the delegate pattern helps you keep the different components of your code separate. For example, if your custom View needs to have some data, it would be bad practice to simply give it access to your Model, or even full access to your Controller. Instead, you'd probably set up some kind of delegate protocol for your View that your Controller would implement. That way your classes know no more about each other than they need to, so that changes in one part would be less likely to break others.

Changing Background Image for Mainview

I am fairly new to Objective-C, but haven't been able to find the answer I am looking for yet.
I am building a practice app which counts down days till specific events (christmas). It all works well, but I wanted to implement a simple way to change the background image (created from storyboards). The current setup of the app is a basic utility app, with the alternate view containing a UISegmentedControl that will set which background image will be displayed behind the countdown label.
I know I can just push separate views, but that seems quite inefficient. I am fairly sure I can use NSNotifications to update the background image, but am still unclear after reading the documentation how to implement it.
One way is to use delegates. A delegate is a callback. That avoids one view passing a reference to another view and having it poke (introduces coupling). Instead, one provides a callback via a formal protocol and delegate to the other.
Here's an SO question that covers it:
What exactly does delegate do in xcode ios project?
Another option is to have a shared model. Using a singleton pattern, multiple views can share a model (data and operations) and you can use NSNotificationCenter to send notifications. When the other view gets the notification that the background changed, it can query the model and update the background.
Related posts:
Giving notification to another class with NSNotificationCenter
How to share an object with the entire project?
As far as the pros and cons go, basically a notification is good when you want to broadcast a change to multiple views. Delegation is good when two items need to communicate directly with some abstraction.
NSNotificationCenter vs delegation( using protocols )?

Objective C Callbacks and Notifications

I'm new to Objective-C and not a full time programmer. I'm beginning to understand the Model-View-Controller design pattern for differentiating the UI from the model. So the user takes an action and the view controller sends a message to the delegate (model). But I'm not sure what the best way to send actions from the delegate back to the view controller.
For example, the user pushes a button, the VC messages the Delegate. That part I understand. Then the delegate takes action, and following that the delegate wants to update the VC (e.g., update a label).
So what I missed (or have forgotten) is how this gets done, while maintaining separation between the UI and the model. I suppose I can use the notification center. Or I think I can just have the view controller pass a callback to the delegate. Or maybe there's another choice I don't know of. Can someone give me a recommendation, please?
I think you're slightly misunderstanding the MVC paradigm. Models should never be delegates of views, since models should have no dependencies or knowledge of any view classes. Typically, a view sends a message to its delegate or target (if you're using target/action), which is usually a controller (often a subclass of UIViewController on iOS). The controller then accesses data from the model and can update any views that need updating. I'd recommend reading the MVC fundamentals guide for a more complete explanation.
Basically you're right, you could do all the notification-related things yourself (i.e. with NotificationCenter) but since we're talking about UI-Stuff here I would greatly recommend you to use IBAction-Methods and IBOutlet-Properties in your code which you can easily connect to UI-Elements respectively their Callbacks in Interface Builder.
A very basic introduction to this topic can be found here:
iPhone SDK Interface Builder basic training
i hope that it is not too basic tough, and that I could lead you on the right track.
First of all delegate is NOT a Model.
Model is something passive that only holds the data (DB, plist, array, dictionary etc.).
While delegate is some set of functions that exist in order to react to some events.
Delegate is more likely to be a view controller in your case.
The view controller should react to user's action.
If the button tap should display some data from your model in some label then view controller should do all the work (receive user's action, take the necessary data from the model and display it on the view...).

Passing Non-Static Objects Between View Controllers

I'm a newb to iphone development and objective c, but hoping some folks smarter than me can lend a hand. Here's my problem:
I have a view based app with about 7 different view controllers. The user navigates via a bottom tab bar. I have the users entering data in the first view controller to an object named "copies". I need to get the copies value to another controller so it can be used for calculations. This needs to be done for many objects in the apps other controllers too.
Example:
User enters Copies value in 1st view controller.
User enters Price value in 6th view controller.
7th view controller calculates copies x price = grand total
In my research I worked out the singleton method, but that seems limited to static data.
What's the best way to ensure that another view controller can access an object the user has filled in? I'm trying to avoid going a SQLite route currently. I want to stick to something basic and work my way up in complexity. Does anyone have any sample code I can review? It really helps to see how others have tackled this before.
Thanks in advance!
If I've understood you correctly there is just one copies value and one price value in the whole app. If that is the case...
There are many ways to do this. Easiest way (perhaps): you could make a Singleton object of a class that you define that has copies and price as properties. Singleton in Objective-C is here, and you would define your properties within the Singleton class. Then you would just call its shared instance and use the values on that. So your code would look like this:
[ThatCrazySingleton sharedInstance].copies = 5;
for writing.
Hope this is what you're looking for.
If you don't want to use a Singleton, at some point one of the UIViewControllers would need to send a message to the others with the copies and price values (hopefully wrapped up ["encapsulated"] in an object). This means that you have to get a reference to the other View controllers, which you can always do by going through the hierarchy.

Core Data best practices question for Navigation iPhone App

Using Apple's Mail application as an example; pretend it uses Core Data. When you touch an email account, it shows you all the messages in that account. So the controller did a fetch request for all the messages in that account.
Then you touch a message and drill one level deeper, now you are viewing a single message. This single message was probably passed from the message list controller, but -- you can also click the triangles in the upper right to move through all the messages in the same email account. This means the view controller for viewing a single email message also needs the exact same list of messages.
So you could cut and paste the fetch request logic from the list view, but that isn't DRY/don't-repeat-yourself.
Any suggestions for a best practice in solving this problem?
Create an object to manage your messages, then interact with that object to fetch the messages that you need for any of your view controllers.
This would also allow you to switch from CoreData without changing any of your view controller logic if you decided to at a later time.
The solution I've been using to solve this problem is to use the delegate design pattern. I.e., in an application with a rootViewController and a detailViewController, the rootViewController acts as a delegate for the detailViewController.
So, for example, when the user is viewing an email message (on the detail view), and they click a button to iterate to new a message, then the detailViewController informs the rootViewController via a delegate method that the rootViewController needs to display a new message.
This way, the detailViewController only every needs to know information about one model object (the email being displayed). While the rootViewController handles interaction that involve the rest of the objects.
To me, this is a nice division of responsibility, so this is the solution I've been using.