How to use CNContactPickerViewController with objective c? - ios

Hi I'm new to iOS development. I want to pick a contact from default contacts app. For that i created an application that lets user to pick a contact from the iPhone default contacts app. For iOS 9+ version, I'm using the following snipped.
- (IBAction)btnAction:(id)sender {
CNContactPickerViewController *contactPicker = [[CNContactPickerViewController alloc] init];
contactPicker.delegate = self;
contactPicker.displayedPropertyKeys = (NSArray *)CNContactGivenNameKey;
[self presentViewController:picker animated:YES completion:nil];
}
-(void) contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact{
NSLog(#"Contact : %#",contact);
}
-(void)contactPickerDidCancel:(CNContactPickerViewController *)picker {
NSLog(#"Cancelled");
}
I also added CNContactPickerDelegate delegate in my uiviewcontroller. When i execute the above code, it opens the contacts app, But when Tap a contact the app becomes blank.
Thanks in advance and can anyone please share your knowledge to use CNContactPickerViewController in Objective-C.

The issue is caused by this code:
contactPicker.displayedPropertyKeys = (NSArray *)CNContactGivenNameKey;
The displayedPropertyKeys expects an NSArray which contains NSString values. In your code, you are trying to type cast an NSString to NSArray and set as the value of this property.
You need to change your code to:
contactPicker.displayedPropertyKeys = #[CNContactGivenNameKey];

#pragma mark - CNContactPickerViewController Delegate method implementation
(void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact
{
NSMutableArray *contactNumberArray = [[NSMutableArray alloc]init];
selectedName=[NSString stringWithFormat:#"%#",contact.givenName];
NSLog(#"%#",selectedName);
NSString *tempString = [NSString stringWithFormat:#"name : %# %# %#\n",contact.givenName, contact.familyName, contact.organizationName];
// // 1. (Phone Numbers)
tempString = [NSString stringWithFormat:#"%#phoneNumbers : ",tempString];
// NSArray*phoneNumber = contact.phoneNumbers;
for (CNLabeledValue *phoneNumber in contact.phoneNumbers)
{
CNPhoneNumber *phone = phoneNumber.value;
tempString = [NSString stringWithFormat:#"%#<%#>",tempString,phone.stringValue];
[contactNumberArray addObject:phone];
selectedPhNumber=[[NSString stringWithFormat:#"%#",phone.stringValue] stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"%#",selectedPhNumber);
}
//2. (Emails)
tempString = [NSString stringWithFormat:#"%#\n Email : ",tempString];
for (CNLabeledValue *email in contact.emailAddresses)
{
selectedEmail=[NSString stringWithFormat:#"%#", email.value];
tempString = [NSString stringWithFormat:#"%#<%#>",tempString,email.value];
[contactNumberArray addObject:email];
NSLog(#"%#",selectedEmail);
}
[self sendRefferelDetailsToServer];
}

-(void)contactPicker:(CNContactPickerViewController *)picker didSelectContacts:(NSArray<CNContact *> *)contacts{
NSLog(#" %#",contacts);
CNContact *contact=[contacts objectAtIndex:0];
NSLog(#"name = %#",contact.givenName);
}
[1]: https://i.stack.imgur.com/9Sp1G.png use above code to for fetch given name from multiple selections,

comment the following line and try again.
//contactPicker.displayedPropertyKeys = (NSArray *)CNContactGivenNameKey;

Related

How to use CNContactPickerdelegate to pick multiple numbers in one contact in objective c?

How to select multiple numbers in one single contact by using with cncontact picker delegate ?
i am using below method but i couldnt able to select numbers
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty;
i have resolved my issue long back , posting lately
this is my answer it may helpful for other thats why i am posting here.
#pragma mark - CNContactPickerViewController Delegate method implementation
(void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact
{
NSMutableArray *contactNumberArray = [[NSMutableArray alloc]init];
selectedName=[NSString stringWithFormat:#"%#",contact.givenName];
NSLog(#"%#",selectedName);
NSString *tempString = [NSString stringWithFormat:#"name : %# %# %#\n",contact.givenName, contact.familyName, contact.organizationName];
// // 1. (Phone Numbers)
tempString = [NSString stringWithFormat:#"%#phoneNumbers : ",tempString];
// NSArray*phoneNumber = contact.phoneNumbers;
for (CNLabeledValue *phoneNumber in contact.phoneNumbers)
{
CNPhoneNumber *phone = phoneNumber.value;
tempString = [NSString stringWithFormat:#"%#<%#>",tempString,phone.stringValue];
[contactNumberArray addObject:phone];
selectedPhNumber=[[NSString stringWithFormat:#"%#",phone.stringValue] stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"%#",selectedPhNumber);
}
//2. (Emails)
tempString = [NSString stringWithFormat:#"%#\n Email : ",tempString];
for (CNLabeledValue *email in contact.emailAddresses)
{
selectedEmail=[NSString stringWithFormat:#"%#", email.value];
tempString = [NSString stringWithFormat:#"%#<%#>",tempString,email.value];
[contactNumberArray addObject:email];
NSLog(#"%#",selectedEmail);
}
[self sendRefferelDetailsToServer];
}

Why my custom protocol is not being call? Objective - C

I have 2 VC, one where the users write the data, with textfield or pickerview, and the main screen where i show the data on a tableview. The problem is that when i click on done button, it might call the delegate, but on the first vc, where is implemented, it doesnt receive any call. What should i do? I have been for 2 days trying to find the bug, and nothings happens. Thanks for any Help.
2VC.h
#protocol AddCountryDelegate <NSObject>
#required
-(void)didCreateCountry:(CountryClass*)country;
#end
#interface AddCountryViewController : UIViewController
#property (assign, nonatomic) id<AddCountryDelegate> customDelegate;
2VC.m
- (IBAction)actionDone:(id)sender {
NSString* itemName = self.itemNameTextField.text;
NSString* countryName = self.countryNameTextField.text;
NSDate *countryDate = [datePickerView date];
NSString *daysLeftString = [NSString stringWithFormat:#"%# days", self.daysLeftTextField.text];
NSInteger daysLeftInt = [daysLeftString integerValue];
NSNumber *daysLeft = [NSNumber numberWithInteger:daysLeftInt];
NSString *paymentMethod = self.paymentMethodTextField.text;
CountryClass* newCountryItem =
[[CountryClass alloc] initWithCountryName:countryName countryLogo:#"" itemName:itemName countryDate:countryDate daysLeft:daysLeft andPaymentMethod:paymentMethod];
[self.customDelegate didCreateCountry:newCountryItem];
[self dismissViewControllerAnimated:YES completion:nil];
}
And finally the implementation on the 1st VC:
-(void)didCreateCountry:(CountryClass *)country{
//Add new country-itemCountry - UPDATING OUR MODEL DATA
NSMutableArray *mutableCountries = [self.countries mutableCopy];
[mutableCountries addObject:country];
self.countries = [mutableCountries copy];
//UPDATING THE VIEW
[self.tableView reloadData];
NSLog(#"Created");
[self saveCountriesToDisc];
}
-(void)saveCountriesToDisc{
NSMutableArray* convertedCountries = [NSMutableArray array];
//Converting the model to dictionary
for(CountryClass *country in self.countries)
{
NSDictionary *convertedCountry = [shop countriesToDictionary];
[convertedCountries addObject:convertedCountry];
}
//NOW convertedShows CONTAINS ONLY STRINGS, NUMBERS,
//ARRAYS AND DICTIONARY
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = paths.firstObject;
NSString *destinationPath = [documentsDirectory stringByAppendingPathComponent:#"countriesListData.plist"];
//NOW TELL THE ARRAY TO SAVE
[convertedCountries writeToFile:destinationPath atomically:YES];
NSLog(#"Saved");
[self.tableView reloadData];
}
I initialize my delegate on the prepareforsegue
-(void)prepareForSegue:(UIStoryboardSegue *)segue
sender:(id)sender
{
if ([segue.identifier isEqualToString:#"AddSegue"]) {
AddCountryViewController* addCountryVC =
segue.destinationViewController;
addCountryVC.customDelegate = self;
}
where in VC1 did you set the customDelegate to self?
also you should set your delegate to weak not assign

JSMessageViewController = Passing PFObject into (id<JSMessageData>)

I am using parse as my database to store the text a user enters, and then display it onto the JSMessageViewController.
I am having difficulty understanding why my PFObject will not pass, and instead, I see empty message cells..
In my code here as you can see, if i pass either of the // code, it crashes, i know nil wont work and thats why i am getting the blank... but how do I pass a PFObject into the JSMessageData ?
- (id<JSMessageData>)messageForRowAtIndexPath:(NSIndexPath *)indexPath
{
//PFObject *chat = self.chats[(NSUInteger) indexPath.row];
//return chat;
//PFObject *chat = self.chats[indexPath.row];
//NSString *message = chat[kMMKChatTextKey];
//return message;
return nil;
}
JSMessageData has 3 instances : - (NSDate *)date, - (NSString *)sender, and - (NSString *)text ....
http://cocoadocs.org/docsets/JSMessagesViewController/4.0.0/Protocols/JSMessageData.html
Has anyone worked with this ? or can you help me figure out how I can pass the PFOject through - Parse is working fine, and the text entered, and after that when i press send, its stored in Parse.
-(void)didSendText:(NSString *)text fromSender:(NSString *)sender onDate:(NSDate *)date
{
if (text.length != 0){
PFObject *chat = [PFObject objectWithClassName:#"Chat"];
[chat setObject:self.chatRoom forKey:kMMKChatChatroomKey];
[chat setObject:self.currentUser forKey:kMMKChatFromUserKey];
[chat setObject:self.withUser forKey:kMMKChatToUserKey];
[chat setObject:text forKey:kMMKChatTextKey];
[chat saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
[self.chats addObject:chat];
//[JSMessageSoundEffect playMessageSentSound];
[self.tableView reloadData];
[self finishSend];
[self scrollToBottomAnimated:YES];
}];
}
}
use objectForKey method on PFObject, and pass appropriate key to retrieve text
The code below should do what you need.
- (id<JSMessageData>)messageForRowAtIndexPath:(NSIndexPath *)indexPath
{
PFObject *chat = self.chats[indexPath.row];
NSString *message = chat[kMMKChatTextKey];
JSMessage *jsMessage = [[JSMessage alloc] initWithText:message sender:nil date:nil];
return jsMessage;
}

Cancel button action in zbar shows blank view

I am using tab bar in my iOS app. When I tap on the scan tab, i invoked the delegate method to start the camera immediately on scan tab. When I start the camera to scan the QR Code and tap on cancel button before scanning, I get the blank view. How to display the view when camera is dismissed
- (void) openCameraScanner
{
ZBarReaderViewController *reader = [[ZBarReaderViewController alloc] init];
reader.readerDelegate = self;
reader.supportedOrientationsMask = ZBarOrientationMaskAll;
reader.showsZBarControls = YES;
ZBarImageScanner *scanner = reader.scanner;
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
[self presentViewController:reader animated:YES completion:nil];
reader.showsZBarControls = YES;
//reader.cameraOverlayView = [self commonOverlay];
}
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
// EXAMPLE: just grab the first barcode
break;
// EXAMPLE: do something useful with the barcode data
//resultsView.text = symbol.data;
NSString *urlString = symbol.data;
NSURL *url = [NSURL URLWithString:urlString];
NSLog(#"Query after scan = %#", [url query]);
//Extract id from URL which is there in QR Code --- start
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
for(NSString *param in [urlString componentsSeparatedByString:#"&"])
{
NSArray *elements = [param componentsSeparatedByString:#"="];
if([elements count]<2)
continue;
[dictionary setObject:[elements objectAtIndex:1] forKey:[elements objectAtIndex:0]];
NSLog(#"value is == %#", [elements objectAtIndex:1]);
//Extract id from URL which is there in QR Code --- end
if([[elements objectAtIndex:1] intValue])
{
NSUserDefaults *defaultsForAsk = [NSUserDefaults standardUserDefaults];
idToAsk = [NSString stringWithFormat:#"%d",[[elements objectAtIndex:1] intValue]];
[defaultsForAsk setObject:idToAsk forKey:#"IDTOASKVIEW"];
flagToShowView = YES;
listViewCntrl.getFlag = flagToShowView;
[self viewDidLoadForDynamicFields];
}
else if([elements objectAtIndex:1] == [NSNull null])
{
[reader dismissViewControllerAnimated:YES completion:Nil];
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Invalid QR Code scanned" message:#"Please scan Collaborator's QR Code" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[message show];
}
}
image.image =
[info objectForKey: UIImagePickerControllerOriginalImage];
// ADD: dismiss the controller (NB dismiss from the *reader*!)
//[reader dismissViewControllerAnimated:YES completion:nil];
[reader dismissViewControllerAnimated:YES completion:Nil];
}
You can re display the view using -(void)viewWillAppear:(BOOL)animated method of your ViewController class.

Why returning (null) from MPMediaPicker (iOS)

I am programming to get the iPhone music library to display, the user selects a song, then this song title is reflected in a UILabel. If only it was that simple! I have tried getting the MPMediaItem into a NSString then the UILabel reflecting this, but i'm just getting (null) returned!
- (IBAction)showMediaPicker:(id)sender {
MPMediaPickerController *mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeAny];
mediaPicker.delegate = self;
//mediaPicker.allowsPickingMultipleItems = YES;
mediaPicker.prompt = #"Select Your Favourite Song!";
[self presentModalViewController:mediaPicker animated:YES];
}
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItem *) mediaItemCollection {
NSString *titleString = [mediaItemCollection valueForProperty:MPMediaItemPropertyTitle];
titleLabel.text = [NSString stringWithFormat:#"Title: %#",titleString];
[self dismissModalViewControllerAnimated: YES];
}
Thanks in advance
You're trying to grab the title for a mediaItemCollection. You need to get the individual song title like this:
MPMediaItem *selectedSong = [mediaItemCollection items] objectAtIndex:0];
NSString *titleString = [selectedSong valueForProperty:MPMediaItemPropertyTitle];
Also by the way, you have the wrong delegate setup for your MPMediaPickerControllerDelegate:
It should be:
- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
-You have the MPMediaItemCollection as just an MPMediaItem

Resources