IOS AddressBook update contact or merge records - ios

In my iOS app, I created my own contact form that appends to note an unique identifier for my app. I want to update the contact from address book as sql "update" statement.
In iOS i only see ABAddressBookAddRecord and ABAddressBookRemoveRecord methods. How can i do UpdateContact?

In our app, we let the user decide, whether to add a new contact or merge the new data into an existing one. We did it like that: (assuming you use a navigationViewController)
ABUnknownPersonViewController *view = [[ABUnknownPersonViewController alloc] init];
view.unknownPersonViewDelegate = self;
view.displayedPerson = <YOUR-ABRecordRef-HERE>;
view.allowsAddingToAddressBook = YES;
view.allowsActions = YES;
[self.navigationController pushViewController:view animated:YES];
The user then sees the record in single view (just your "new" data) and has buttons to import or merge to existing contact.

Related

Accessing iPhone call history on iOS

Is there any way to access the last time an ABAddressBook contact was accessed, interacted with, called, miss-called, etc.
I'm aware of the ABPerson properties, specifically kABPersonModificationDateProperty. But I was wondering if there any way of knowing more about the users interaction with that contact.
No apple does not allow access to the Call list. Since a call information is stored in the call and not in the addressbook there is no way to get the information you want from the addressbook.
I don't think you can access called history in iOS, especially after iOS 4. You can however know that a phone call was dialled using CoreTelephony framework.
I do it in applicationDidBecomeActive of my AppDelegate.m
...
typeof(self) __weak weakSelf = self;
self.center = [[CTCallCenter alloc]init];
self.center.callEventHandler = ^(CTCall *call) {
if(call.callState == CTCallStateDialing) {
weakSelf.callWasMade = YES;
}
};
...

how to get values from QuickDialog in iOs

I need some help in QuickDialog. I am using this tutorial QuickDialog but i cannot find what i would like to do in my QuickDialog.
First i have a controller A that will transfer to controller B using QuickDialog, values are in controller A. Now, my problem is how can i access the values when I'm already in controller B.
For example: i have declared QEntryElement *amountEntry = [[QEntryElement alloc] initWithTitle:#"Amount" Value:#""]; in controller A and passed this on controller B, how will i access amountEntry in controller B.
I hope i have explained it well. Please help on this.
You can access all values within the QRootElement. One way to do so is setting the key property of every QElement and afterwards fetch all key-value pairs into a NSMutableDicionary like so:
NSMutableDictionary *results = [[NSMutableDictionary alloc] init];
[fooRootElement fetchValueIntoObject:results];
You can use the onSelected completion code to trigger such action with a QButtonElement
QSection *confirmButtonSection = [[QSection alloc] init];
QButtonElement *confirmButton = [[QButtonElement alloc] initWithTitle:#"Accept"];
[fooRootElement addSection:confirmButtonSection];
[confirmButtonSection addElement:confirmButton];
[confirmButton setOnSelected:(^{[self fetchResultsAndCheckThemAndDismissControllerBMethod];})];
the button will then call the method on controller A which will leave you with a filled dictionary full of sweet information.

Show vcard data in a uitableview

Good evening.
I'm developing a QRcode reader and I have one question.
When I read a vcard, I want to show the contact data in a UItableview like the contact's default uitablview in iPhone.
I want to show the contact data as above:
And I want to add the option to save to.
I want to know how can I do it. I have to manually program the view or is there some easier way to do it?
Thanks so much.
CFDataRef vCardData = (CFDataRef)[vCard dataUsingEncoding:NSUTF8StringEncoding];
ABAddressBookRef addressBook = [AddressBook Instance].addressBook;
ABRecordRef defaultSource = ABAddressBookCopyDefaultSource(addressBook);
NSArray *contacts = (NSArray *)ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource,vCardData);
CFRelease(defaultSource);
if (contacts.count) {
ABRecordRef person = [contacts objectAtIndex:0];
ABUnknownPersonViewController *unknownPersonVC = [[ABUnknownPersonViewController alloc] init];
unknownPersonVC.unknownPersonViewDelegate = self;
unknownPersonVC.allowsAddingToAddressBook = YES;
unknownPersonVC.displayedPerson = person;
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:unknownPersonVC];
[unknownPersonVC release];
[self.navigationController pushViewController:unknownPersonVC animated:YES];
[navController release];
}
instead of creating custome Contact person View using table View use above code to first get all contact person record Ref and then display them one by one using
ABUnknownPersonViewController or ABPersonViewController..
may be help you..
You need to create the UITableView and implement all of its dataSource and delegate methods to draw the sections and cells. There's no free way to do this automatically, unfortunately.
You should probably check out a table view framework such as the free Sensible TableView. These frameworks automate a lot of these common tasks and will save you a lot of time.

io looking for insert and cancel pattern

I've been looking around for a good pattern to implement a insert then cancel pattern when working with a UINavigationBar and UITableView.
I have I have a "insert"button in my TeamsViewController navigation bar (screenshot)
Which when I run it runs this code:
-(void)insertTeam
{
if( !detailViewController ) {
detailViewController = [[TeamDetailViewController alloc] init];
}
if( !teams ) {
teams = [NSMutableArray array];
}
Team *team = [[Team alloc] init];
[teams addObject:team];
int lastIndex = [teams count];
[detailViewController setEditingTeam:[teams objectAtIndex:lastIndex - 1]];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
[self presentModalViewController:navigationController animated:YES];
}
Which is great if the user fills out all the info, but if they hit cancel on the next view, there's an empty object in my arrary.
I'm sure there's a great pattern to achieve this but I've looked at all the TableView sample codes, two different ios books, and tried googling it, but haven't found a pattern for this.
My thought is something like the following:
When user cancels, set a canceled ivar in my Team object to YES
Back in my TeamsViewController, when the view appears check the last object in my teams array and see if it's property canceled is YES, if so remove that last object.
But this doesn't seem so slick and I was figuring there was some better way to achieve this. TIA.
I would be tempted to make the TeamsViewController a delegate of the TeamDetailViewController. The delegate would implement a method such as - (void)teamCreated:(Team *)team; and it would update the array. Since there seems to be no point to having a Team in the array that's incomplete, I would have the TeamDetailViewController create the Team and pass it back in the delegate call. On a cancel, there would be no need to do anything except pop the controller.

Using Core Data with Images or buttons (or anything besides a tableView)

I'm trying to build an application that uses something like the following data model. I can do this fine in a tableView but I would like to be more creative. For Example, Inside a navigation controller, I want to have a view that has 10 images (or buttons with an image as a background).
(three entities)
entity 1: House
attribute: houseName
relationship:person
entity 2:Person
attribute: personName
relationship:house
relationship:children
entity 3:Children
attribute:name
attribute:birthPlace
relationship: adult
relationships are one to many down from
attributes are all strings
person<---->>house, children<--->>adult
In the first view there are images and each image is assigned to entity House (houseName 1, houseName 2, etc.). When you select a house it pushes the next view with 5 images (that is linked to the Person Entity (personName 1, personName2, etc). When you select the PersonName it will push the next view populated with the Children Entity.
I've read quite a bit of info on core data and I'm comfortable doing this:
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [[managedObject valueForKey#"houseName"] description];
but very unsure where I should even start with using and image or button to do this
I was thinking of something like this:
-(id)initWithHouseViewController:(HouseViewController*)aHouseViewController house:(NSManagedObject *)aHouse{
if blah blah
self.houseViewController = aHouseViewController;
self.house = aHouse
}return self;
}
// for a selector
-(void) showPersonView{
PersonViewController *pvc = [[PersonViewController alloc] initWithHouseViewController:self house:house];
in the viewDidLoad
{
if (house != nil) {
UIImageView *house1 = [[ UIImageView alloc.. blah blah
some kind of.. action:#selector(showPersonView)
((for each houseName in house) instead of house1, house2,)
...
}
Any suggestions with the viewDidLoad where I wouldn't need to hard code in each image (or button) would be great to make this more portable. Also, I'm not rooted to doing it this way if there are suggestions as to a nicer/more creative way to do this.
Sorry if this is a bit messy. It's messy in my mind as well.
Thanks for taking your time to read this,
I wouldn't use FetchResultController in this case.
Instead You can try This:
Create a view controller that will show all the houses as buttons, you can dynamically create the buttons according to the "Houses" count.
It will look something like this:
NSArray * allHouses = [Houses allObjects];
//you can sort them if you need
[allHouses enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
//create the buttons as custom and you can add any image to the button
UIButton *button....
button
//store the house index as the button tag, so you can get it later
button.tag = idx;
//add a selector to the button
[button addTarget:self
action:#selector(getPersons:)
forControlEvents:UIControlEventTouchUpInside];
}];
Create a new PersonViewController that will hold the persons. the view controller should get the house as the parameter and not the person. After it gets the house you will get the persons with the relationShip.
Now add this method to get the :
-(void)getPersons(UIButton*)sender{
NSInteger *tag = sender.tag;
House * house = (House*)[allHouses objectAtIndex:tag];
PersonViewController *pvc = [[PersonViewController alloc] init];
pvc.house = house;
[self.navigationController pushViewController.....];
}
Inside the person view controller you can get all the persons or with fetch request or simply with :
NSArray *allPersons = [house.person all objects];
Again create the persons buttons the same as you did with the first view controller.
Reapit the same procedure with the Children view controller.
GoodLuck
Shani

Resources