How do I save information retrieved from an Addressbook to NSUserDefaults? - iphone

I am trying to use a PeoplePicker to retrieve the name and address of a contact and store it into the NSUserDefaults, which i eventually want to retrieve it on a tableview.
My question is how do I save the information in NSUserDefaults.
I have used NSDictionary, but I am not making any progress.
so I'm trying to save the array to the NSUserDefaults.
Can someone help me?
My code look like this:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier {
// Only inspect the value if it's an address.
if (property == kABPersonAddressProperty) {
ABMutableMultiValueRef multiValue = ABRecordCopyValue(person, property);
for(CFIndex i=0;i<ABMultiValueGetCount(multiValue);i++)
{
ABMultiValueRef multi = ABRecordCopyValue(person, property);
// Set up an NSArray and copy the values in.
NSArray *theArray = [(id)ABMultiValueCopyArrayOfAllValues(multi) autorelease];
// Figure out which values we want and store the index.
const NSUInteger theIndex = ABMultiValueGetIndexForIdentifier(multi, identifier);
// Set up an NSDictionary to hold the contents of the array.
NSDictionary *dictionary = [theArray objectAtIndex:theIndex];
// Set up NSStrings to hold keys and values. First, how many are there?
const NSUInteger theCount = [dictionary count];
NSString *keys[theCount];
NSString *values[theCount];
// Get the keys and values from the CFDictionary. Note that because
// we're using the "GetKeysAndValues" function, you don't need to
// release keys or values. It's the "Get Rule" and only applies to
// CoreFoundation objects.
[dictionary getObjects:values andKeys:keys];
// Set the address label's text.
NSString *address;
address = [NSString stringWithFormat:#"%#, %#, %#",
[dictionary objectForKey:(NSString *)kABPersonAddressStreetKey],
[dictionary objectForKey:(NSString *)kABPersonAddressCityKey],
[dictionary objectForKey:(NSString *)kABPersonAddressCountryKey]];
NSLog(#"%#", address);
[self dismissModalViewControllerAnimated:YES];
[self.navigationController popViewControllerAnimated:YES];
}
NSUserDefaults *locatie = [NSUserDefaults standardUserDefaults];
CFRelease(multiValue);
}
return NO;
}

[locatie setObject:yourObject forKey:#"YoureKey"];
If you want to store the adress use:
[locatie setObject:adress forKey:#"adressKey"];
to retrive use:
adress = [locatie valueForKey:#"adressKey"];
NOTE:
In these examples locatie is: NSUserDefaults *locatie = [NSUserDefaults standardUserDefaults];

Related

How to remove a null value directly from NSDictionary

I´m a beginer and have lately got a great deal of trouble with this issue.
I want to pass a NSDictnonary Data to a server from my app and in some cases if the user hasen´t chosen any option I want to remove nil objects.
I have looked into this thread that seems be the right method but I haven't succeed to implement in my code.
How to remove a null value from NSDictionary
My guess would be to implement the code to Null directly in my NSDictonary
Here´s my Dictionary code
-(NSDictionary*)parametersForCreateActivities
{
NSString *token = [[A0SimpleKeychain keychain] stringForKey:tokenConstant];
NSString *userId = [[A0SimpleKeychain keychain] stringForKey:child_id];
NSString *userCreate = [[NSUserDefaults standardUserDefaults] objectForKey:#"CreateTitle"];
NSString *createDescription = [[NSUserDefaults standardUserDefaults] objectForKey:#"DescriptionText"];
NSString *createTimestart = [[NSUserDefaults standardUserDefaults] objectForKey:#"TimeStartString"];
NSString *createTimestop = [[NSUserDefaults standardUserDefaults] objectForKey:#"TimeStopString"];
NSString *createImage = [[NSUserDefaults standardUserDefaults] objectForKey:#"DefaultcreateImageID"];
NSDictionary *parameters;
if (userId && token) {
parameters = #{child_id: userId, tokenConstant:token, activity_name :userCreate, create_Description :createDescription, create_Timestart :createTimestart, create_Timestop :createTimestop, create_Image :createImage};
}
return parameters;
}
My guess is that It should check somewhere in the code for nil objects and remove theme. But I have really struggled with figuring out how to format the code.
I´m guessing the code should be something like this but I have no idea where to place it and how to format it.
NSMutableDictionary *dict = [parametersForCreateActivities mutableCopy];
NSArray *keysForNullValues = [dict allKeysForObject:[NSNull null]];
[dict removeObjectsForKeys:DefaultcreateImageID];
Try below code
NSMutableDictionary *yourDictionary; // Your dictionary object with data
NSMutableDictionary *updatedDic = [yourDictionary mutableCopy];
for (NSString *key in [yourDictionary allKeys]) {
if ([yourDictionary[key] isEqual:[NSNull null]] || [yourDictionary[key] isKindOfClass:[NSNull class]]) {
updatedDic[key] = #"";
}
}
yourDictionary = [updatedDic copy];
NSLog(#"%#",yourDictionary);

E-mail dialog box is not open in iphone sdk

In my app, I am fetching the e-mail id from address box using PersonPicker view.
When i select any e-mail id, i try to open the e-mail dialog. But it will just open & close immediatly.
I can't able to solve this issue.
I got code from Here
My code is as follow:
-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier{
// Get the first and the last name. Actually, copy their values using the person object and the appropriate
// properties into two string variables equivalently.
// Watch out the ABRecordCopyValue method below. Also, notice that we cast to NSString *.
NSString *firstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *lastName = (NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
// Compose the full name.
NSString *fullName = #"";
// Before adding the first and the last name in the fullName string make sure that these values are filled in.
if (firstName != nil) {
fullName = [fullName stringByAppendingString:firstName];
}
if (lastName != nil) {
fullName = [fullName stringByAppendingString:#" "];
fullName = [fullName stringByAppendingString:lastName];
}
// Get the multivalue e-mail property.
CFTypeRef multivalue = ABRecordCopyValue(person, property);
// Get the index of the selected e-mail. Remember that the e-mail multi-value property is being returned as an array.
CFIndex index = ABMultiValueGetIndexForIdentifier(multivalue, identifier);
// Copy the e-mail value into a string.
email = (NSString *)ABMultiValueCopyValueAtIndex(multivalue, index);
NSLog(#"%#",email);
// Create a temp array in which we'll add all the desired values.
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
[tempArray addObject:fullName];
// Save the email into the tempArray array.
[tempArray addObject:email];
// Now add the tempArray into the contactsArray.
[contactsArray addObject:tempArray];
NSLog(#"%#",contactsArray);
// Release the tempArray.
[tempArray release];
// Reload the table to display the new data.
[table reloadData];
// Dismiss the contacts view controller.
[contacts dismissModalViewControllerAnimated:YES];
[contacts release];
MFMailComposeViewController* Apicker = [[MFMailComposeViewController alloc] init];
if (Apicker != nil)
{
[Apicker setSubject:#""];
NSString * someString = nil;
someString=#"Google";
[Apicker setMessageBody:someString isHTML:YES];
NSArray *toRecipients = [NSArray arrayWithObjects:email, nil];
[Apicker setToRecipients:toRecipients];
Apicker.mailComposeDelegate = self;
[self presentModalViewController:Apicker animated:YES];
[Apicker release];
}
return NO;
}
I think it may be the issue of dismiss & present the modal view.
your problem with dismiss and present is that the two overlap. -- dismiss it and THEN show it kinda like you did BUT you run into a problem because the stuff is animated. dont animate there or delay the presetting till after the dismissal

how can adding Key float values from NSDictionary to NSarray?

My brain is fried! I can't think.
i am new to iphone programming
am doing json parsing ....in that am storeing data from json to nsdictionary but .......
I want to add all nsdictionary float values from the dictionary to the array. This is what I am doing right now.As code below:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
self.responseData = nil;
dict = [responseString JSONValue];
NSMutableArray *array = [NSMutableArray array];
for (NSString *key in [dict allKeys])
{
array = [dict objectForKey:key];
// array return float values but
[array addObject:array ]; // geting carsh dude to array return float values like 120.01
}
Please guide me i am not getting a part where i am doing a mistake.
Thanks in advance.
Your app is crashing because you are adding data to NSArray , this is static array, you can not add value at run time, so just Make NSMutableArray and add your data in NSMutableArray.
Your code is broken in a couple of ways.
This line assigns the array pointer to the object in the dictionary:
array = [dict objectForKey:key];
Then you are trying to add the array to itself, which does not make sense. But worse, since array does no longer point to your NSMutableArray you cannot even call that method.
[array addObject:array ];
You probably wanted to do something like this:
for (NSString *key in [dict allKeys])
{
id value = [dict objectForKey:key];
[array addObject:value];
}

Reduce time to perform big operation on iphone app

When I launch an app, I need to retrieve all contacts from Address Book & store it in array to display it in table view. I wrote this code in viewDidAppear method. While contacts are retrieving from Address Book , I am showing activity indicator. I have around 1100 contacts in my address book. For this it took 14 seconds to retrieve data & store it in array. Its not acceptable time. So I need to optimize this & reduce time to max 2 to 3 seconds.
I need all contacts because when my app launches , I need to search for contacts so I need all the data available in my array.
How can I reduce this timing ? If you need more information just let me know.
Any kind of help is highly appreciated. Thanks.
UPDATE 1 : My code
- (NSMutableArray*)getAddressBookData {
self.tempArray = [[NSMutableArray alloc]init];
addressBook = ABAddressBookCreate();
APP_DELGATE.people = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
peopleCount = [APP_DELGATE.people count];
for (int i=0; i<peopleCount; i++) {
ABRecordRef record = [APP_DELGATE.people objectAtIndex:i];
NSNumber *recordId = [NSNumber numberWithInteger:ABRecordGetRecordID(record)];
NSLog(#"record id is %#",recordId);
// Get fname, lname, company
NSString *fnm = (NSString *)ABRecordCopyValue(record, kABPersonFirstNameProperty) ;
NSString *lnm = (NSString *)ABRecordCopyValue(record, kABPersonLastNameProperty) ;
NSString *comp = (NSString*)ABRecordCopyValue(record,kABPersonOrganizationProperty);
// Get Ph no
ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(record, kABPersonPhoneProperty);
NSArray* phoneNumbers = [self getPhoneNoWithoutSymbols:(NSArray*)ABMultiValueCopyArrayOfAllValues(phoneNumberProperty)];
NSString *strPhoneNos = [self getStringRepresentaionFromArray:phoneNumbers];
NSLog(#"strPhoneNos => %#",strPhoneNos);
// Get emails
ABMultiValueRef emailProperty = ABRecordCopyValue(record, kABPersonEmailProperty);
NSArray* emails = (NSArray*)ABMultiValueCopyArrayOfAllValues(emailProperty);
NSString *strEmails = [self getStringRepresentaionFromArray:emails];
NSLog(#"strEmails => %#",strEmails);
// Get URL
ABMultiValueRef urlProperty = ABRecordCopyValue(record, kABPersonURLProperty);
NSArray* urls = (NSArray*)ABMultiValueCopyArrayOfAllValues(urlProperty);
NSString *strURLs = [self getStringRepresentaionFromArray:urls];
NSLog(#"strURLs => %#",strURLs);
// Get Address
ABMultiValueRef address=ABRecordCopyValue(record, kABPersonAddressProperty);
CFDictionaryRef dic=nil;
NSMutableArray *addressArray = [[NSMutableArray alloc]init];
for (int index=0; index<ABMultiValueGetCount(address); index++) {
dic=ABMultiValueCopyValueAtIndex(address, index);
NSString* labelName=(NSString*)ABMultiValueCopyLabelAtIndex(address, index);
if (labelName) {
NSString *street =(NSString*) CFDictionaryGetValue(dic, kABPersonAddressStreetKey);
NSString *city= (NSString*)CFDictionaryGetValue(dic, kABPersonAddressCityKey) ;
NSString *state= CFDictionaryGetValue(dic, kABPersonAddressStateKey);
NSString *country=CFDictionaryGetValue(dic, kABPersonAddressCountryKey);
NSString *zipcode=CFDictionaryGetValue(dic, kABPersonAddressZIPKey);
NSString *addressDetails=#"";
if (street) {
addressDetails=[NSString stringWithFormat:#"%# ",street];
}
if (city) {
addressDetails=[NSString stringWithFormat:#"%# %# ",addressDetails,city];
}
if (state) {
addressDetails=[NSString stringWithFormat:#"%# %# ",addressDetails,state];
}
if (country) {
addressDetails=[NSString stringWithFormat:#"%# %# ",addressDetails,country];
}
if (zipcode) {
addressDetails=[NSString stringWithFormat:#"%# %# ",addressDetails,zipcode];
}
[addressArray addObject:addressDetails];
}
}
NSString *strAddress = [self getStringRepresentaionFromArray:addressArray];
NSLog(#"strAddress => %#",strAddress);
// Get Notes
NSString *noteString=(NSString *)ABRecordCopyValue(record, kABPersonNoteProperty);
// Get Birthdate
NSDate *birthDate=(NSDate*)ABRecordCopyValue(record, kABPersonBirthdayProperty) ;
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMMM dd yyyy"];
NSString *birthdateString = [formatter stringFromDate:birthDate];
[formatter release];
// Get user image
UIImage *image = nil;
if( ABPersonHasImageData( record ) ) {
NSData *imageData = (NSData*)ABPersonCopyImageData(record);
image = [UIImage imageWithData:imageData];
[imageData release];
}
// Create User object & add it to array
User *user = [[User alloc]initUserWithUniqID:recordId.intValue FirstName:fnm lastName:lnm company:comp phoneNumbers:strPhoneNos emails:strEmails urls:strURLs address:strAddress notes:noteString dob:birthdateString userImage:image];
[self.tempArray addObject:user];
[user release];
}
self.tempArray = [NSMutableArray arrayWithArray:[self.tempArray sortedArrayUsingSelector:#selector(compare:)]];
APP_DELGATE.allUsersArray = self.tempArray;
return tempArray;
}
-(NSMutableArray*)getPhoneNoWithoutSymbols:(NSArray*)array {
self.phNoArray = [[NSMutableArray alloc]init];
for (NSString *str in array) {
[self.phNoArray addObject:[self getPhNo:str]];
}
return self.phNoArray;
}
-(NSString*)getPhNo:(NSString*)str {
NSString *str0 = [str stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *str1 = [str0 stringByReplacingOccurrencesOfString:#"(" withString:#""];
NSString *str2 = [str1 stringByReplacingOccurrencesOfString:#")" withString:#""];
NSString *str3 = [str2 stringByReplacingOccurrencesOfString:#"-" withString:#""];
return str3;
}
-(NSString*)getStringRepresentaionFromArray:(NSArray*)array {
return [array componentsJoinedByString:DELIMITER_SYMBOL];
}
Firstly, try some general approaches to reduce time by using more optimized code and less repetition of code and also through less use of loops or may be only iterate loops only till the data is obtained. Also you can check whether your code is properly distributed as far as the Time Profiling is concerned.
Secondly, we feel that time required is more because user is shown an Activity Indicator till 14 seconds. If you don't show it and don't block the User Interface till data is getting copied into your array, then user may feel that it is more smooth So here is how you can do that:
You can use NSThread to allow the application to launch while you retrieve all your data from the AddressBook and Store it in your array.
You can use
[NSThread detachNewThreadSelector:#selector(fetchAddressContacts:) withObject:nil];
For more information you can refer to detachNewThreadSelector: from NSThread
So basically in AppDelegate you need to code as following in AppDelegate.m
-(void)applicationDidFinishLaunching:(UIApplication *)application {
[NSThread detachNewThreadSelector:#selector(fetchAddressContacts) withObject:nil];
}
-(void)fetchAddressContacts {
//Do your stuff to copy your contacts from address book to array
// Once you finish this task you can trigger an NSNotification which could be caught on some other viewController or implement a delegate to transfer data to a viewController and proper actions can be executed once the data is loaded.
}
Let me know if you need more help.
Hope this helps you.
Perform your contacts retrieval method diagnostics and identify what calls are causing the bottleneck here.
Share your code and describe the bottlenecks
Any operation taking serious amount of time should be performed in a thread. In this case, I'd gather the data on first startup only and store them internally. You can refresh the primary data anytime later on demand (refresh button?) otherwise work with the internally stored "clone" of the contacts rather than calling any time-consuming operation on every app's start.
BTW: Be careful about the address book contacts these days :-)
When your app first install fetch all the contacts and save in coredate/plist file when next time app opens then show the contacts from the storage which is very fast as compare to fetching contacts from iPhone database. Now the problem how to update contacts which newly added, so for every contact there is property called "kABPersonModificationDateProperty" and "kABPersonCreationDateProperty" ,use this to find only updated contacts and add in the storage. Hope this helps.

iPhone: can i use NSString search in NSArray

can i use like this r not
for (NSString *string in userInfo){
lblUserName.text = (NSString *) [userInfo objectForKey:#"name"];
lblLocation.text = (NSString *) [userInfo objectForKey:#"location"];
lblDescription.text =(NSString *) [userInfo objectForKey:#"description"];
NSLog(#"User profileData Received: %#", userInfo);
}
here userInfo = NSArray (this is delegate i can change )
lblUserName = label name
ObectForKey is using for searching NSString
thank you, is this Right r wrong one
if not how i have to work out
NSArray are not key based but index based. Use NSDictionary instead or use index to retrieve items.
and I don't understand what is the loop for, you don't even use the string var in it ???