5 // Created by Christian Brunschen on 29/05/2008.
7 * Copyright 2008 ZXing authors
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
22 #import "AddContactAction.h"
23 #import "AddressBook/AddressBook.h"
26 @implementation AddContactAction
29 @synthesize phoneNumbers;
32 @synthesize urlString;
35 + (id)actionWithName:(NSString *)n
36 phoneNumbers:(NSArray *)nums
39 address:(NSString *)ad
41 AddContactAction *aca = [[[self alloc] init] autorelease];
43 aca.phoneNumbers = nums;
52 return NSLocalizedString(@"AddContactAction title", @"Add Contact");
55 - (void) addContactWithController:(UIViewController *)controller {
56 CFErrorRef *error = NULL;
57 NSCharacterSet *whitespaceSet = [NSCharacterSet whitespaceCharacterSet];
59 ABRecordRef person = ABPersonCreate();
61 NSRange commaRange = [name rangeOfString:@","];
62 if (commaRange.location != NSNotFound) {
63 NSString *lastName = [[name substringToIndex:commaRange.location]
64 stringByTrimmingCharactersInSet:whitespaceSet];
65 ABRecordSetValue(person, kABPersonLastNameProperty, lastName, error);
66 NSArray *firstNames = [[[name substringFromIndex:commaRange.location + commaRange.length]
67 stringByTrimmingCharactersInSet:whitespaceSet]
68 componentsSeparatedByCharactersInSet:whitespaceSet];
69 ABRecordSetValue(person, kABPersonFirstNameProperty, [firstNames objectAtIndex:0], error);
70 for (int i = 1; i < [firstNames count]; i++) {
71 ABRecordSetValue(person, kABPersonMiddleNameProperty, [firstNames objectAtIndex:1], error);
74 NSArray *nameParts = [name componentsSeparatedByCharactersInSet:whitespaceSet];
75 int nParts = nameParts.count;
77 ABRecordSetValue(person, kABPersonFirstNameProperty, name, error);
78 } else if (nParts >= 2) {
79 int lastPart = nParts - 1;
80 ABRecordSetValue(person, kABPersonFirstNameProperty, [nameParts objectAtIndex:0], error);
81 for (int i = 1; i < lastPart; i++) {
82 ABRecordSetValue(person, kABPersonMiddleNameProperty, [nameParts objectAtIndex:i], error);
84 ABRecordSetValue(person, kABPersonLastNameProperty, [nameParts objectAtIndex:lastPart], error);
89 ABRecordSetValue(person, kABPersonNoteProperty, self.note, error);
92 if (self.phoneNumbers && self.phoneNumbers.count > 0) {
93 // multi-values: nultiple phone numbers
94 ABMutableMultiValueRef phoneNumberMultiValue =
95 ABMultiValueCreateMutable(kABStringPropertyType);
96 for (NSString *number in self.phoneNumbers) {
97 ABMultiValueAddValueAndLabel(phoneNumberMultiValue, number,
98 kABPersonPhoneMainLabel, NULL);
100 ABRecordSetValue(person, kABPersonPhoneProperty,
101 phoneNumberMultiValue, error);
102 CFRelease(phoneNumberMultiValue);
106 // a single email address
107 ABMutableMultiValueRef emailMultiValue =
108 ABMultiValueCreateMutable(kABStringPropertyType);
109 ABMultiValueAddValueAndLabel(emailMultiValue, self.email,
111 ABRecordSetValue(person, kABPersonEmailProperty, emailMultiValue, error);
112 CFRelease(emailMultiValue);
115 if (self.urlString) {
116 // a single url as the home page
117 ABMutableMultiValueRef urlMultiValue =
118 ABMultiValueCreateMutable(kABStringPropertyType);
119 ABMultiValueAddValueAndLabel(urlMultiValue, self.urlString,
120 kABPersonHomePageLabel, NULL);
121 ABRecordSetValue(person, kABPersonURLProperty, urlMultiValue, error);
122 CFRelease(urlMultiValue);
126 // we can't parse all the possible address formats, alas, so we punt by putting
127 // the entire thing into a multi-line 'street' address.
128 // This won't look great on the phone, but at least the info will be there,
129 // and can be syned to a desktop computer, adjusted as necessary, and so on.
131 // split the address into parts at each comma or return
133 [self.address componentsSeparatedByCharactersInSet:
134 [NSCharacterSet characterSetWithCharactersInString:@",;\r\n"]];
135 NSMutableArray *strippedParts = [NSMutableArray arrayWithCapacity:[parts count]];
137 for (NSString *part in parts) {
138 // strip the part of whitespace
139 NSString *strippedPart =
140 [part stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
141 if ([strippedPart length] > 0) {
142 // if there is anything in this address part, add it to the list of stripped parts
143 [strippedParts addObject:strippedPart];
146 // finally, create a 'street' address by concatenating all the stripped parts, separated by linefeeds
147 NSString *street = [strippedParts componentsJoinedByString:@"\n"];
149 CFMutableDictionaryRef addressDict =
150 CFDictionaryCreateMutable(NULL,
152 &kCFTypeDictionaryKeyCallBacks,
153 &kCFTypeDictionaryValueCallBacks);
154 CFDictionarySetValue(addressDict, kABPersonAddressStreetKey, street);
156 ABMutableMultiValueRef addressMultiValue =
157 ABMultiValueCreateMutable(kABStringPropertyType);
158 ABMultiValueAddValueAndLabel(addressMultiValue,
162 ABRecordSetValue(person, kABPersonAddressProperty, addressMultiValue, error);
163 CFRelease(addressMultiValue);
164 CFRelease(addressDict);
167 ABUnknownPersonViewController *unknownPersonViewController =
168 [[ABUnknownPersonViewController alloc] init];
169 unknownPersonViewController.displayedPerson = person;
170 unknownPersonViewController.allowsActions = true;
171 unknownPersonViewController.allowsAddingToAddressBook = true;
172 unknownPersonViewController.unknownPersonViewDelegate = self;
175 viewController = [controller retain];
176 [[viewController navigationController] pushViewController:unknownPersonViewController animated:YES];
177 [unknownPersonViewController release];
180 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
181 if (buttonIndex != [alertView cancelButtonIndex]) {
182 // perform the action
183 [self addContactWithController:viewController];
187 #ifdef CONFIRM_ADDING_CONTACT
188 #undef CONFIRM_ADDING_CONTACT
190 - (void)performActionWithController:(UIViewController *)controller
191 shouldConfirm:(bool)confirm {
192 #ifdef CONFIRM_ADDING_CONTACT
194 viewController = controller;
195 UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil
196 message:NSLocalizedString(@"AddContactAction alert message", @"Add Contact?")
198 cancelButtonTitle:NSLocalizedString(@"AddContactAction cancel button title", @"Cancel")
199 otherButtonTitles:NSLocalizedString(@"AddContactAction confirm button title", @"Add Contact"), nil];
204 [self addContactWithController:controller];
205 #ifdef CONFIRM_ADDING_CONTACT
210 - (void)dismissUnknownPersonViewController:(ABUnknownPersonViewController *)unknownPersonViewController {
211 [[viewController navigationController] popToViewController:viewController animated:YES];
212 [viewController release];
213 viewController = nil;
216 // ABUnknownPersonViewControllerDelegate
218 - (void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownPersonViewController
219 didResolveToPerson:(ABRecordRef)person {
221 [self performSelector:@selector(dismissUnknownPersonViewController:) withObject:unknownPersonViewController afterDelay:0.0];