diff --git a/ABContact.h b/ABContact.h old mode 100644 new mode 100755 index 29130fa..8f24ebc --- a/ABContact.h +++ b/ABContact.h @@ -8,6 +8,103 @@ #import #import + +#pragma mark - Human Readable Name Strings for Dictionary Conversion + +#define FIRST_NAME_STRING @"First Name" +#define MIDDLE_NAME_STRING @"Middle Name" +#define LAST_NAME_STRING @"Last Name" + +#define PREFIX_STRING @"Prefix" +#define SUFFIX_STRING @"Suffix" +#define NICKNAME_STRING @"Nickname" + +#define PHONETIC_FIRST_STRING @"Phonetic First Name" +#define PHONETIC_MIDDLE_STRING @"Phonetic Middle Name" +#define PHONETIC_LAST_STRING @"Phonetic Last Name" + +#define ORGANIZATION_STRING @"Organization" +#define JOBTITLE_STRING @"Job Title" +#define DEPARTMENT_STRING @"Department" + +#define NOTE_STRING @"Note" + +#define BIRTHDAY_STRING @"Birthday" +#define CREATION_DATE_STRING @"Creation Date" +#define MODIFICATION_DATE_STRING @"Modification Date" + +#define KIND_STRING @"Kind" + +#define EMAIL_STRING @"Email" +#define ADDRESS_STRING @"Address" +#define DATE_STRING @"Date" +#define PHONE_STRING @"Phone" +#define IM_STRING @"Instant Message" +#define URL_STRING @"URL" +#define RELATED_STRING @"Related Name" +#define SOCIAL_STRING @"Social Profile" + +#define IMAGE_STRING @"Image" + +#pragma mark Label Quick Reference + +/* + // Generic + const CFStringRef kABWorkLabel; + const CFStringRef kABHomeLabel; + const CFStringRef kABOtherLabel; + + // Relation + const CFStringRef kABPersonMotherLabel; + const CFStringRef kABPersonFatherLabel; + const CFStringRef kABPersonParentLabel; + const CFStringRef kABPersonSisterLabel; + const CFStringRef kABPersonBrotherLabel; + const CFStringRef kABPersonChildLabel; + const CFStringRef kABPersonFriendLabel; + const CFStringRef kABPersonSpouseLabel; + const CFStringRef kABPersonPartnerLabel; + const CFStringRef kABPersonManagerLabel; + const CFStringRef kABPersonAssistantLabel; + + // URL + const CFStringRef kABPersonHomePageLabel; + + // Social + const CFStringRef kABPersonSocialProfileServiceTwitter; + const CFStringRef kABPersonSocialProfileServiceGameCenter; + const CFStringRef kABPersonSocialProfileServiceFacebook; + const CFStringRef kABPersonSocialProfileServiceMyspace; + const CFStringRef kABPersonSocialProfileServiceLinkedIn; + const CFStringRef kABPersonSocialProfileServiceFlickr; + + // IM + const CFStringRef kABPersonInstantMessageServiceYahoo; + const CFStringRef kABPersonInstantMessageServiceJabber; + const CFStringRef kABPersonInstantMessageServiceMSN; + const CFStringRef kABPersonInstantMessageServiceICQ; + const CFStringRef kABPersonInstantMessageServiceAIM; + const CFStringRef kABPersonInstantMessageServiceFacebook; + const CFStringRef kABPersonInstantMessageServiceGaduGadu; + const CFStringRef kABPersonInstantMessageServiceGoogleTalk; + const CFStringRef kABPersonInstantMessageServiceQQ; + const CFStringRef kABPersonInstantMessageServiceSkype; + + // Phone Numbers + const CFStringRef kABPersonPhoneMobileLabel; + const CFStringRef kABPersonPhoneIPhoneLabel; + const CFStringRef kABPersonPhoneMainLabel; + const CFStringRef kABPersonPhoneHomeFAXLabel; + const CFStringRef kABPersonPhoneWorkFAXLabel; + const CFStringRef kABPersonPhonePagerLabel; + const CFStringRef kABPersonPhoneOtherFAXLabel; + + // Date + const CFStringRef kABPersonAnniversaryLabel; +*/ + +#pragma mark ABContact + @interface ABContact : NSObject { ABRecordRef record; @@ -23,20 +120,39 @@ + (ABPropertyType) propertyType: (ABPropertyID) aProperty; + (NSString *) propertyTypeString: (ABPropertyID) aProperty; + (NSString *) propertyString: (ABPropertyID) aProperty; -+ (BOOL) propertyIsMultivalue: (ABPropertyID) aProperty; ++ (BOOL) propertyIsMultiValue: (ABPropertyID) aProperty; + (NSArray *) arrayForProperty: (ABPropertyID) anID inRecord: (ABRecordRef) record; + (id) objectForProperty: (ABPropertyID) anID inRecord: (ABRecordRef) record; // Creating proper dictionaries + (NSDictionary *) dictionaryWithValue: (id) value andLabel: (CFStringRef) label; -+ (NSDictionary *) addressWithStreet: (NSString *) street withCity: (NSString *) city - withState:(NSString *) state withZip: (NSString *) zip - withCountry: (NSString *) country withCode: (NSString *) code; -+ (NSDictionary *) smsWithService: (CFStringRef) service andUser: (NSString *) userName; ++ (BOOL) isMultivalueDictionary: (NSDictionary *) dictionary; ++ (NSDictionary *) addressWithStreet: (NSString *) street withCity: (NSString *) city withState:(NSString *) state withZip: (NSString *) zip withCountry: (NSString *) country withCode: (NSString *) code; ++ (NSDictionary *) imWithService: (CFStringRef) service andUser: (NSString *) userName; ++ (NSDictionary *) socialWithURL: (NSString *) url withService: (NSString *) serviceName withUsername: (NSString *) username withIdentifier: (NSString *) key; // Instance utility methods - (BOOL) removeSelfFromAddressBook: (NSError **) error; +- (BOOL) addAddress: (NSDictionary *) dictionary; +- (BOOL) addAddressItem:(NSDictionary *)dictionary withLabel: (CFStringRef) label; +- (BOOL) addSocial: (NSDictionary *) dictionary; +- (BOOL) addSocialItem: (NSDictionary *) dictionary withLabel: (CFStringRef) label; +- (BOOL) addIM: (NSDictionary *) dictionary; +- (BOOL) addIMItem:(NSDictionary *)dictionary withLabel: (CFStringRef) label; + +- (BOOL) addEmail: (NSDictionary *) dictionary; +- (BOOL) addEmailItem: (NSString *) value withLabel: (CFStringRef) label; +- (BOOL) addPhone: (NSDictionary *) dictionary; +- (BOOL) addPhoneItem: (NSString *) value withLabel: (CFStringRef) label; +- (BOOL) addURL: (NSDictionary *) dictionary; +- (BOOL) addURLItem: (NSString *) value withLabel: (CFStringRef) label; + +// Sorting +- (BOOL) isEqualToString: (ABContact *) aContact; +- (NSComparisonResult) caseInsensitiveCompare: (ABContact *) aContact; + +#pragma mark RECORD ACCESS @property (nonatomic, readonly) ABRecordRef record; @property (nonatomic, readonly) ABRecordID recordID; @property (nonatomic, readonly) ABRecordType recordType; @@ -68,8 +184,10 @@ @property (nonatomic, readonly) NSDate *creationDate; @property (nonatomic, readonly) NSDate *modificationDate; +#pragma mark IMAGES +@property (nonatomic, assign) UIImage *image; + #pragma mark MULTIVALUE -// Each of these produces an array of NSStrings @property (nonatomic, readonly) NSArray *emailArray; @property (nonatomic, readonly) NSArray *emailLabels; @property (nonatomic, readonly) NSArray *phoneArray; @@ -82,9 +200,12 @@ @property (nonatomic, readonly) NSArray *dateLabels; @property (nonatomic, readonly) NSArray *addressArray; @property (nonatomic, readonly) NSArray *addressLabels; -@property (nonatomic, readonly) NSArray *smsArray; -@property (nonatomic, readonly) NSArray *smsLabels; +@property (nonatomic, readonly) NSArray *imArray; +@property (nonatomic, readonly) NSArray *imLabels; +@property (nonatomic, readonly) NSArray *socialArray; +@property (nonatomic, readonly) NSArray *socialLabels; +// Each of these produces an array of strings @property (nonatomic, readonly) NSString *emailaddresses; @property (nonatomic, readonly) NSString *phonenumbers; @property (nonatomic, readonly) NSString *urls; @@ -96,20 +217,17 @@ @property (nonatomic, assign) NSArray *urlDictionaries; @property (nonatomic, assign) NSArray *dateDictionaries; @property (nonatomic, assign) NSArray *addressDictionaries; -@property (nonatomic, assign) NSArray *smsDictionaries; - -#pragma mark IMAGES -@property (nonatomic, assign) UIImage *image; +@property (nonatomic, assign) NSArray *imDictionaries; +@property (nonatomic, assign) NSArray *socialDictionaries; #pragma mark REPRESENTATIONS - // Conversion to dictionary -- (NSDictionary *) baseDictionaryRepresentation; // no image -- (NSDictionary *) dictionaryRepresentation; // image where available +@property (nonatomic, readonly) NSDictionary *baseDictionaryRepresentation; // no image +@property (nonatomic, readonly) NSDictionary *dictionaryRepresentation; // image where available // Conversion to data -- (NSData *) baseDataRepresentation; // no image -- (NSData *) dataRepresentation; // image where available +@property (nonatomic, readonly) NSData *baseDataRepresentation; // no image +@property (nonatomic, readonly) NSData *dataRepresentation; // image where available + (id) contactWithDictionary: (NSDictionary *) dict; + (id) contactWithData: (NSData *) data; diff --git a/ABContact.m b/ABContact.m old mode 100644 new mode 100755 index 5b84166..169aab0 --- a/ABContact.m +++ b/ABContact.m @@ -6,284 +6,178 @@ #import "ABContact.h" #import "ABContactsHelper.h" - -#define CFAutorelease(obj) ({CFTypeRef _obj = (obj); (_obj == NULL) ? NULL : [(id)CFMakeCollectable(_obj) autorelease]; }) - -#define FIRST_NAME_STRING @"First Name" -#define MIDDLE_NAME_STRING @"Middle Name" -#define LAST_NAME_STRING @"Last Name" - -#define PREFIX_STRING @"Prefix" -#define SUFFIX_STRING @"Suffix" -#define NICKNAME_STRING @"Nickname" - -#define PHONETIC_FIRST_STRING @"Phonetic First Name" -#define PHONETIC_MIDDLE_STRING @"Phonetic Middle Name" -#define PHONETIC_LAST_STRING @"Phonetic Last Name" - -#define ORGANIZATION_STRING @"Organization" -#define JOBTITLE_STRING @"Job Title" -#define DEPARTMENT_STRING @"Department" - -#define NOTE_STRING @"Note" - -#define BIRTHDAY_STRING @"Birthday" -#define CREATION_DATE_STRING @"Creation Date" -#define MODIFICATION_DATE_STRING @"Modification Date" - -#define KIND_STRING @"Kind" - -#define EMAIL_STRING @"Email" -#define ADDRESS_STRING @"Address" -#define DATE_STRING @"Date" -#define PHONE_STRING @"Phone" -#define SMS_STRING @"Instant Message" -#define URL_STRING @"URL" -#define RELATED_STRING @"Related Name" - -#define IMAGE_STRING @"Image" +#import "ABStandin.h" @implementation ABContact @synthesize record; +#pragma mark - Contacts + // Thanks to Quentarez, Ciaran - (id) initWithRecord: (ABRecordRef) aRecord { - if (self = [super init]) record = CFRetain(aRecord); - return self; + if (self = [super init]) + record = CFRetain(aRecord); + return self; } + (id) contactWithRecord: (ABRecordRef) person { - return [[[ABContact alloc] initWithRecord:person] autorelease]; + return [[ABContact alloc] initWithRecord:person]; } + (id) contactWithRecordID: (ABRecordID) recordID { - ABAddressBookRef addressBook = ABAddressBookCreate(); - ABRecordRef contactrec = ABAddressBookGetPersonWithRecordID(addressBook, recordID); - ABContact *contact = [self contactWithRecord:contactrec]; - // CFRelease(contactrec); // Thanks Gary Fung - return contact; + ABAddressBookRef addressBook = [ABStandin addressBook]; + ABRecordRef contactrec = ABAddressBookGetPersonWithRecordID(addressBook, recordID); + if (!contactrec) return nil; // Thanks, Frederic Bronner + + ABContact *contact = [self contactWithRecord:contactrec]; + return contact; } // Thanks to Ciaran + (id) contact { - ABRecordRef person = ABPersonCreate(); - id contact = [ABContact contactWithRecord:person]; - CFRelease(person); - return contact; + ABRecordRef person = ABPersonCreate(); + id contact = [ABContact contactWithRecord:person]; + CFRelease(person); + return contact; } -- (void) dealloc +// Thanks to Eridius for suggestions re: error +// Thanks Rincewind42 for the *error transfer bridging +- (BOOL) removeSelfFromAddressBook: (NSError **) error { - if (record) CFRelease(record); - [super dealloc]; + CFErrorRef cfError = NULL; + BOOL success; + + ABAddressBookRef addressBook = [ABStandin addressBook]; + + success = ABAddressBookRemoveRecord(addressBook, self.record, &cfError); + if (!success) + { + if (error) + *error = (__bridge_transfer NSError *)cfError; + return NO; + } + + return success; } -#pragma mark utilities -+ (NSString *) localizedPropertyName: (ABPropertyID) aProperty +- (void) dealloc { - return [(NSString *)ABPersonCopyLocalizedPropertyName(aProperty) autorelease]; + if (record) + CFRelease(record); } -+ (ABPropertyType) propertyType: (ABPropertyID) aProperty -{ - return ABPersonGetTypeOfProperty(aProperty); -} +#pragma mark Sorting -// Thanks to Eridius for suggestions re switch -+ (NSString *) propertyTypeString: (ABPropertyID) aProperty +- (BOOL) isEqualToString: (ABContact *) aContact { - switch (ABPersonGetTypeOfProperty(aProperty)) - { - case kABInvalidPropertyType: return @"Invalid Property"; - case kABStringPropertyType: return @"String"; - case kABIntegerPropertyType: return @"Integer"; - case kABRealPropertyType: return @"Float"; - case kABDateTimePropertyType: return DATE_STRING; - case kABDictionaryPropertyType: return @"Dictionary"; - case kABMultiStringPropertyType: return @"Multi String"; - case kABMultiIntegerPropertyType: return @"Multi Integer"; - case kABMultiRealPropertyType: return @"Multi Float"; - case kABMultiDateTimePropertyType: return @"Multi Date"; - case kABMultiDictionaryPropertyType: return @"Multi Dictionary"; - default: return @"Invalid Property"; - } + return [self.compositeName isEqualToString:aContact.compositeName]; } -+ (NSString *) propertyString: (ABPropertyID) aProperty +- (NSComparisonResult) caseInsensitiveCompare: (ABContact *) aContact { - /* switch (aProperty) // Sorry, this won't compile - { - case kABPersonFirstNameProperty: return FIRST_NAME_STRING; - case kABPersonMiddleNameProperty: return MIDDLE_NAME_STRING; - case kABPersonLastNameProperty: return LAST_NAME_STRING; - - case kABPersonPrefixProperty: return PREFIX_STRING; - case kABPersonSuffixProperty: return SUFFIX_STRING; - case kABPersonNicknameProperty: return NICKNAME_STRING; - - case kABPersonFirstNamePhoneticProperty: return PHONETIC_FIRST_STRING; - case kABPersonMiddleNamePhoneticProperty: return PHONETIC_MIDDLE_STRING; - case kABPersonLastNamePhoneticProperty: return PHONETIC_LAST_STRING; - - case kABPersonOrganizationProperty: return ORGANIZATION_STRING; - case kABPersonJobTitleProperty: return JOBTITLE_STRING; - case kABPersonDepartmentProperty: return DEPARTMENT_STRING; - - case kABPersonNoteProperty: return NOTE_STRING; - - case kABPersonKindProperty: return KIND_STRING; - - case kABPersonBirthdayProperty: return BIRTHDAY_STRING; - case kABPersonCreationDateProperty: return CREATION_DATE_STRING; - case kABPersonModificationDateProperty: return MODIFICATION_DATE_STRING; - - case kABPersonEmailProperty: return EMAIL_STRING; - case kABPersonAddressProperty: return ADDRESS_STRING; - case kABPersonDateProperty: return DATE_STRING; - case kABPersonPhoneProperty: return PHONE_STRING; - case kABPersonInstantMessageProperty: return SMS_STRING; - case kABPersonURLProperty: return URL_STRING; - case kABPersonRelatedNamesProperty: return RELATED_STRING; - } */ - - if (aProperty == kABPersonFirstNameProperty) return FIRST_NAME_STRING; - if (aProperty == kABPersonMiddleNameProperty) return MIDDLE_NAME_STRING; - if (aProperty == kABPersonLastNameProperty) return LAST_NAME_STRING; - - if (aProperty == kABPersonPrefixProperty) return PREFIX_STRING; - if (aProperty == kABPersonSuffixProperty) return SUFFIX_STRING; - if (aProperty == kABPersonNicknameProperty) return NICKNAME_STRING; - - if (aProperty == kABPersonFirstNamePhoneticProperty) return PHONETIC_FIRST_STRING; - if (aProperty == kABPersonMiddleNamePhoneticProperty) return PHONETIC_MIDDLE_STRING; - if (aProperty == kABPersonLastNamePhoneticProperty) return PHONETIC_LAST_STRING; - - if (aProperty == kABPersonOrganizationProperty) return ORGANIZATION_STRING; - if (aProperty == kABPersonJobTitleProperty) return JOBTITLE_STRING; - if (aProperty == kABPersonDepartmentProperty) return DEPARTMENT_STRING; - - if (aProperty == kABPersonNoteProperty) return NOTE_STRING; - - if (aProperty == kABPersonKindProperty) return KIND_STRING; - - if (aProperty == kABPersonBirthdayProperty) return BIRTHDAY_STRING; - if (aProperty == kABPersonCreationDateProperty) return CREATION_DATE_STRING; - if (aProperty == kABPersonModificationDateProperty) return MODIFICATION_DATE_STRING; - - if (aProperty == kABPersonEmailProperty) return EMAIL_STRING; - if (aProperty == kABPersonAddressProperty) return ADDRESS_STRING; - if (aProperty == kABPersonDateProperty) return DATE_STRING; - if (aProperty == kABPersonPhoneProperty) return PHONE_STRING; - if (aProperty == kABPersonInstantMessageProperty) return SMS_STRING; - if (aProperty == kABPersonURLProperty) return URL_STRING; - if (aProperty == kABPersonRelatedNamesProperty) return RELATED_STRING; - - return nil; -} - -+ (BOOL) propertyIsMultivalue: (ABPropertyID) aProperty; -{ - if (aProperty == kABPersonFirstNameProperty) return NO; - if (aProperty == kABPersonMiddleNameProperty) return NO; - if (aProperty == kABPersonLastNameProperty) return NO; - - if (aProperty == kABPersonPrefixProperty) return NO; - if (aProperty == kABPersonSuffixProperty) return NO; - if (aProperty == kABPersonNicknameProperty) return NO; - - if (aProperty == kABPersonFirstNamePhoneticProperty) return NO; - if (aProperty == kABPersonMiddleNamePhoneticProperty) return NO; - if (aProperty == kABPersonLastNamePhoneticProperty) return NO; - - if (aProperty == kABPersonOrganizationProperty) return NO; - if (aProperty == kABPersonJobTitleProperty) return NO; - if (aProperty == kABPersonDepartmentProperty) return NO; - - if (aProperty == kABPersonNoteProperty) return NO; - - if (aProperty == kABPersonKindProperty) return NO; - - if (aProperty == kABPersonBirthdayProperty) return NO; - if (aProperty == kABPersonCreationDateProperty) return NO; - if (aProperty == kABPersonModificationDateProperty) return NO; - - return YES; - /* - if (aProperty == kABPersonEmailProperty) return YES; - if (aProperty == kABPersonAddressProperty) return YES; - if (aProperty == kABPersonDateProperty) return YES; - if (aProperty == kABPersonPhoneProperty) return YES; - if (aProperty == kABPersonInstantMessageProperty) return YES; - if (aProperty == kABPersonURLProperty) return YES; - if (aProperty == kABPersonRelatedNamesProperty) return YES; - */ + return [self.compositeName caseInsensitiveCompare:aContact.compositeName]; } -+ (NSArray *) arrayForProperty: (ABPropertyID) anID inRecord: (ABRecordRef) record +#pragma mark Utilities ++ (NSString *) localizedPropertyName: (ABPropertyID) aProperty { - // Recover the property for a given record - CFTypeRef theProperty = ABRecordCopyValue(record, anID); - NSArray *items = (NSArray *)ABMultiValueCopyArrayOfAllValues(theProperty); - CFRelease(theProperty); - return [items autorelease]; + return (__bridge_transfer NSString *)ABPersonCopyLocalizedPropertyName(aProperty); } -+ (id) objectForProperty: (ABPropertyID) anID inRecord: (ABRecordRef) record ++ (ABPropertyType) propertyType: (ABPropertyID) aProperty { - return [(id) ABRecordCopyValue(record, anID) autorelease]; + return ABPersonGetTypeOfProperty(aProperty); } -+ (NSDictionary *) dictionaryWithValue: (id) value andLabel: (CFStringRef) label +// Thanks to Eridius for switchification ++ (NSString *) propertyTypeString: (ABPropertyID) aProperty { - NSMutableDictionary *dict = [NSMutableDictionary dictionary]; - if (value) [dict setObject:value forKey:@"value"]; - if (label) [dict setObject:(NSString *)label forKey:@"label"]; - return dict; + switch (ABPersonGetTypeOfProperty(aProperty)) + { + case kABInvalidPropertyType: return @"Invalid Property"; + case kABStringPropertyType: return @"String"; + case kABIntegerPropertyType: return @"Integer"; + case kABRealPropertyType: return @"Float"; + case kABDateTimePropertyType: return DATE_STRING; + case kABDictionaryPropertyType: return @"Dictionary"; + case kABMultiStringPropertyType: return @"Multi String"; + case kABMultiIntegerPropertyType: return @"Multi Integer"; + case kABMultiRealPropertyType: return @"Multi Float"; + case kABMultiDateTimePropertyType: return @"Multi Date"; + case kABMultiDictionaryPropertyType: return @"Multi Dictionary"; + default: return @"Invalid Property"; + } } -+ (NSDictionary *) addressWithStreet: (NSString *) street withCity: (NSString *) city - withState:(NSString *) state withZip: (NSString *) zip - withCountry: (NSString *) country withCode: (NSString *) code ++ (NSString *) propertyString: (ABPropertyID) aProperty { - NSMutableDictionary *md = [NSMutableDictionary dictionary]; - if (street) [md setObject:street forKey:(NSString *) kABPersonAddressStreetKey]; - if (city) [md setObject:city forKey:(NSString *) kABPersonAddressCityKey]; - if (state) [md setObject:state forKey:(NSString *) kABPersonAddressStateKey]; - if (zip) [md setObject:zip forKey:(NSString *) kABPersonAddressZIPKey]; - if (country) [md setObject:country forKey:(NSString *) kABPersonAddressCountryKey]; - if (code) [md setObject:code forKey:(NSString *) kABPersonAddressCountryCodeKey]; - return md; + if (aProperty == kABPersonFirstNameProperty) return FIRST_NAME_STRING; + if (aProperty == kABPersonMiddleNameProperty) return MIDDLE_NAME_STRING; + if (aProperty == kABPersonLastNameProperty) return LAST_NAME_STRING; + + if (aProperty == kABPersonPrefixProperty) return PREFIX_STRING; + if (aProperty == kABPersonSuffixProperty) return SUFFIX_STRING; + if (aProperty == kABPersonNicknameProperty) return NICKNAME_STRING; + + if (aProperty == kABPersonFirstNamePhoneticProperty) return PHONETIC_FIRST_STRING; + if (aProperty == kABPersonMiddleNamePhoneticProperty) return PHONETIC_MIDDLE_STRING; + if (aProperty == kABPersonLastNamePhoneticProperty) return PHONETIC_LAST_STRING; + + if (aProperty == kABPersonOrganizationProperty) return ORGANIZATION_STRING; + if (aProperty == kABPersonJobTitleProperty) return JOBTITLE_STRING; + if (aProperty == kABPersonDepartmentProperty) return DEPARTMENT_STRING; + + if (aProperty == kABPersonNoteProperty) return NOTE_STRING; + + if (aProperty == kABPersonKindProperty) return KIND_STRING; + + if (aProperty == kABPersonBirthdayProperty) return BIRTHDAY_STRING; + if (aProperty == kABPersonCreationDateProperty) return CREATION_DATE_STRING; + if (aProperty == kABPersonModificationDateProperty) return MODIFICATION_DATE_STRING; + + if (aProperty == kABPersonEmailProperty) return EMAIL_STRING; + if (aProperty == kABPersonAddressProperty) return ADDRESS_STRING; + if (aProperty == kABPersonDateProperty) return DATE_STRING; + if (aProperty == kABPersonPhoneProperty) return PHONE_STRING; + if (aProperty == kABPersonInstantMessageProperty) return IM_STRING; + if (aProperty == kABPersonURLProperty) return URL_STRING; + if (aProperty == kABPersonSocialProfileProperty) return SOCIAL_STRING; + if (aProperty == kABPersonRelatedNamesProperty) return RELATED_STRING; + + return nil; } -+ (NSDictionary *) smsWithService: (CFStringRef) service andUser: (NSString *) userName ++ (NSArray *) arrayForProperty: (ABPropertyID) anID inRecord: (ABRecordRef) record { - NSMutableDictionary *sms = [NSMutableDictionary dictionary]; - if (service) [sms setObject:(NSString *) service forKey:(NSString *) kABPersonInstantMessageServiceKey]; - if (userName) [sms setObject:userName forKey:(NSString *) kABPersonInstantMessageUsernameKey]; - return sms; + // Recover the property for a given record + CFTypeRef theProperty = ABRecordCopyValue(record, anID); + NSArray *items = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(theProperty); + CFRelease(theProperty); + return items; } -// Thanks to Eridius for suggestions re: error -- (BOOL) removeSelfFromAddressBook: (NSError **) error ++ (id) objectForProperty: (ABPropertyID) anID inRecord: (ABRecordRef) record { - ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate()); - if (!ABAddressBookRemoveRecord(addressBook, self.record, (CFErrorRef *) error)) return NO; - return ABAddressBookSave(addressBook, (CFErrorRef *) error); + return (__bridge_transfer id) ABRecordCopyValue(record, anID); } #pragma mark Record ID and Type + - (ABRecordID) recordID {return ABRecordGetRecordID(record);} - (ABRecordType) recordType {return ABRecordGetRecordType(record);} - (BOOL) isPerson {return self.recordType == kABPersonType;} -#pragma mark Getting Single Value Strings +#pragma mark String Retrieval + - (NSString *) getRecordString:(ABPropertyID) anID { - return [(NSString *) ABRecordCopyValue(record, anID) autorelease]; + NSString *result = (__bridge_transfer NSString *) ABRecordCopyValue(record, anID); + return result; } - (NSString *) firstname {return [self getRecordString:kABPersonFirstNameProperty];} - (NSString *) middlename {return [self getRecordString:kABPersonMiddleNameProperty];} @@ -302,313 +196,657 @@ - (NSString *) jobtitle {return [self getRecordString:kABPersonJobTitleProperty] - (NSString *) department {return [self getRecordString:kABPersonDepartmentProperty];} - (NSString *) note {return [self getRecordString:kABPersonNoteProperty];} -#pragma mark Contact Name Utility + +#pragma mark Setting Strings +- (BOOL) setString: (NSString *) aString forProperty:(ABPropertyID) anID +{ + CFErrorRef cfError = NULL; + BOOL success = ABRecordSetValue(record, anID, (__bridge CFStringRef) aString, &cfError); + if (!success) + { + NSError *error = (__bridge_transfer NSError *) cfError; + NSLog(@"Error: %@", error.localizedFailureReason); + } + return success; +} + +- (void) setFirstname: (NSString *) aString {[self setString: aString forProperty: kABPersonFirstNameProperty];} +- (void) setMiddlename: (NSString *) aString {[self setString: aString forProperty: kABPersonMiddleNameProperty];} +- (void) setLastname: (NSString *) aString {[self setString: aString forProperty: kABPersonLastNameProperty];} + +- (void) setPrefix: (NSString *) aString {[self setString: aString forProperty: kABPersonPrefixProperty];} +- (void) setSuffix: (NSString *) aString {[self setString: aString forProperty: kABPersonSuffixProperty];} +- (void) setNickname: (NSString *) aString {[self setString: aString forProperty: kABPersonNicknameProperty];} + +- (void) setFirstnamephonetic: (NSString *) aString {[self setString: aString forProperty: kABPersonFirstNamePhoneticProperty];} +- (void) setMiddlenamephonetic: (NSString *) aString {[self setString: aString forProperty: kABPersonMiddleNamePhoneticProperty];} +- (void) setLastnamephonetic: (NSString *) aString {[self setString: aString forProperty: kABPersonLastNamePhoneticProperty];} + +- (void) setOrganization: (NSString *) aString {[self setString: aString forProperty: kABPersonOrganizationProperty];} +- (void) setJobtitle: (NSString *) aString {[self setString: aString forProperty: kABPersonJobTitleProperty];} +- (void) setDepartment: (NSString *) aString {[self setString: aString forProperty: kABPersonDepartmentProperty];} + +- (void) setNote: (NSString *) aString {[self setString: aString forProperty: kABPersonNoteProperty];} + +#pragma mark Contact Name - (NSString *) contactName { - NSMutableString *string = [NSMutableString string]; - - if (self.firstname || self.lastname) - { - if (self.prefix) [string appendFormat:@"%@ ", self.prefix]; - if (self.firstname) [string appendFormat:@"%@ ", self.firstname]; - if (self.nickname) [string appendFormat:@"\"%@\" ", self.nickname]; - if (self.lastname) [string appendFormat:@"%@", self.lastname]; - - if (self.suffix && string.length) - [string appendFormat:@", %@ ", self.suffix]; - else - [string appendFormat:@" "]; - } - - if (self.organization) [string appendString:self.organization]; - return [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + NSMutableString *string = [NSMutableString string]; + + if (self.firstname || self.lastname) + { + if (self.prefix) [string appendFormat:@"%@ ", self.prefix]; + if (self.firstname) [string appendFormat:@"%@ ", self.firstname]; + if (self.nickname) [string appendFormat:@"\"%@\" ", self.nickname]; + if (self.lastname) [string appendFormat:@"%@", self.lastname]; + + if (self.suffix && string.length) + [string appendFormat:@", %@ ", self.suffix]; + else + [string appendFormat:@" "]; + } + + if (self.organization) [string appendString:self.organization]; + return [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; } - (NSString *) compositeName { - NSString *string = (NSString *)ABRecordCopyCompositeName(record); - return [string autorelease]; + return (__bridge_transfer NSString *)ABRecordCopyCompositeName(record); } -#pragma mark NUMBER +#pragma mark Numbers + - (NSNumber *) getRecordNumber: (ABPropertyID) anID { - return [(NSNumber *) ABRecordCopyValue(record, anID) autorelease]; + return (__bridge_transfer NSNumber *) ABRecordCopyValue(record, anID); } - (NSNumber *) kind {return [self getRecordNumber:kABPersonKindProperty];} + +#pragma mark Setting Numbers +- (BOOL) setNumber: (NSNumber *) aNumber forProperty:(ABPropertyID) anID +{ + CFErrorRef cfError = NULL; + BOOL success = ABRecordSetValue(record, anID, (__bridge CFNumberRef) aNumber, &cfError); + if (!success) + { + NSError *error = (__bridge_transfer NSError *) cfError; + NSLog(@"Error: %@", error.localizedFailureReason); + } + return success; +} + +// const CFNumberRef kABPersonKindPerson; +// const CFNumberRef kABPersonKindOrganization; +- (void) setKind: (NSNumber *) aKind {[self setNumber:aKind forProperty: kABPersonKindProperty];} + #pragma mark Dates + - (NSDate *) getRecordDate:(ABPropertyID) anID { - return [(NSDate *) ABRecordCopyValue(record, anID) autorelease]; + return (__bridge_transfer NSDate *) ABRecordCopyValue(record, anID); } - (NSDate *) birthday {return [self getRecordDate:kABPersonBirthdayProperty];} - (NSDate *) creationDate {return [self getRecordDate:kABPersonCreationDateProperty];} - (NSDate *) modificationDate {return [self getRecordDate:kABPersonModificationDateProperty];} -#pragma mark Getting MultiValue Elements +#pragma mark Setting Dates + +- (BOOL) setDate: (NSDate *) aDate forProperty:(ABPropertyID) anID +{ + CFErrorRef cfError = NULL; + BOOL success = ABRecordSetValue(record, anID, (__bridge CFDateRef) aDate, &cfError); + if (!success) + { + NSError *error = (__bridge_transfer NSError *) cfError; + NSLog(@"Error: %@", error.localizedFailureReason); + } + return success; +} + +- (void) setBirthday: (NSDate *) aDate {[self setDate: aDate forProperty: kABPersonBirthdayProperty];} + + +#pragma mark Images + +- (UIImage *) image +{ + if (!ABPersonHasImageData(record)) return nil; + CFDataRef imageData = ABPersonCopyImageData(record); + if (!imageData) return nil; + + NSData *data = (__bridge_transfer NSData *)imageData; + UIImage *image = [UIImage imageWithData:data]; + return image; +} + +- (void) setImage: (UIImage *) image +{ + CFErrorRef cfError = NULL; + BOOL success; + + if (image == nil) // remove + { + if (!ABPersonHasImageData(record)) return; // no image to remove + success = ABPersonRemoveImageData(record, &cfError); + if (!success) + { + NSError *error = (__bridge_transfer NSError *) cfError; + NSLog(@"Error: %@", error.localizedFailureReason); + } + return; + } + + NSData *data = UIImagePNGRepresentation(image); + success = ABPersonSetImageData(record, (__bridge CFDataRef) data, &cfError); + if (!success) + { + NSError *error = (__bridge_transfer NSError *) cfError; + NSLog(@"Error: %@", error.localizedFailureReason); + } + return; +} + +#pragma mark MultiValue ++ (BOOL) propertyIsMultiValue: (ABPropertyID) aProperty; +{ + if (aProperty == kABPersonFirstNameProperty) return NO; + if (aProperty == kABPersonMiddleNameProperty) return NO; + if (aProperty == kABPersonLastNameProperty) return NO; + + if (aProperty == kABPersonPrefixProperty) return NO; + if (aProperty == kABPersonSuffixProperty) return NO; + if (aProperty == kABPersonNicknameProperty) return NO; + + if (aProperty == kABPersonFirstNamePhoneticProperty) return NO; + if (aProperty == kABPersonMiddleNamePhoneticProperty) return NO; + if (aProperty == kABPersonLastNamePhoneticProperty) return NO; + + if (aProperty == kABPersonOrganizationProperty) return NO; + if (aProperty == kABPersonJobTitleProperty) return NO; + if (aProperty == kABPersonDepartmentProperty) return NO; + + if (aProperty == kABPersonNoteProperty) return NO; + + if (aProperty == kABPersonKindProperty) return NO; + + if (aProperty == kABPersonBirthdayProperty) return NO; + if (aProperty == kABPersonCreationDateProperty) return NO; + if (aProperty == kABPersonModificationDateProperty) return NO; + + return YES; + + /* + if (aProperty == kABPersonEmailProperty) return YES; // multistring + if (aProperty == kABPersonPhoneProperty) return YES; // multistring + if (aProperty == kABPersonURLProperty) return YES; // multistring + + if (aProperty == kABPersonAddressProperty) return YES; // multivalue + if (aProperty == kABPersonDateProperty) return YES; // multivalue + if (aProperty == kABPersonInstantMessageProperty) return YES; // multivalue + if (aProperty == kABPersonRelatedNamesProperty) return YES; // multivalue + if (aProperty == kABPersonSocialProfileProperty) return YES; // multivalue + */ +} + +// Determine whether the dictionary is a proper value/label item ++ (BOOL) isMultivalueDictionary: (NSDictionary *) dictionary +{ + if (dictionary.allKeys.count != 2) + return NO; + if (![dictionary objectForKey:@"value"]) + return NO; + if (![dictionary objectForKey:@"label"]) + return NO; + + return YES; +} + +// Return multivalue-style dictionary ++ (NSDictionary *) dictionaryWithValue: (id) value andLabel: (CFStringRef) label +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (value) [dict setObject:value forKey:@"value"]; + if (label) [dict setObject:(__bridge NSString *)label forKey:@"label"]; + return dict; +} + +#pragma mark Accessing MultiValue Elements (value and label) + - (NSArray *) arrayForProperty: (ABPropertyID) anID { - CFTypeRef theProperty = ABRecordCopyValue(record, anID); - NSArray *items = (NSArray *)ABMultiValueCopyArrayOfAllValues(theProperty); - CFRelease(theProperty); - return [items autorelease]; + CFTypeRef theProperty = ABRecordCopyValue(record, anID); + if (!theProperty) return nil; + + NSArray *items = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(theProperty); + CFRelease(theProperty); + return items; } - (NSArray *) labelsForProperty: (ABPropertyID) anID { - CFTypeRef theProperty = ABRecordCopyValue(record, anID); - NSMutableArray *labels = [NSMutableArray array]; - for (int i = 0; i < ABMultiValueGetCount(theProperty); i++) - { - NSString *label = (NSString *)ABMultiValueCopyLabelAtIndex(theProperty, i); - [labels addObject:label]; - [label release]; - } - CFRelease(theProperty); - return labels; + CFTypeRef theProperty = ABRecordCopyValue(record, anID); + if (!theProperty) return nil; + + NSMutableArray *labels = [NSMutableArray array]; + for (int i = 0; i < ABMultiValueGetCount(theProperty); i++) + { + NSString *label = (__bridge_transfer NSString *)ABMultiValueCopyLabelAtIndex(theProperty, i); + [labels addObject:label]; + } + CFRelease(theProperty); + return labels; } - (NSArray *) emailArray {return [self arrayForProperty:kABPersonEmailProperty];} - (NSArray *) emailLabels {return [self labelsForProperty:kABPersonEmailProperty];} + - (NSArray *) phoneArray {return [self arrayForProperty:kABPersonPhoneProperty];} - (NSArray *) phoneLabels {return [self labelsForProperty:kABPersonPhoneProperty];} + - (NSArray *) relatedNameArray {return [self arrayForProperty:kABPersonRelatedNamesProperty];} - (NSArray *) relatedNameLabels {return [self labelsForProperty:kABPersonRelatedNamesProperty];} + - (NSArray *) urlArray {return [self arrayForProperty:kABPersonURLProperty];} - (NSArray *) urlLabels {return [self labelsForProperty:kABPersonURLProperty];} + - (NSArray *) dateArray {return [self arrayForProperty:kABPersonDateProperty];} - (NSArray *) dateLabels {return [self labelsForProperty:kABPersonDateProperty];} + - (NSArray *) addressArray {return [self arrayForProperty:kABPersonAddressProperty];} - (NSArray *) addressLabels {return [self labelsForProperty:kABPersonAddressProperty];} -- (NSArray *) smsArray {return [self arrayForProperty:kABPersonInstantMessageProperty];} -- (NSArray *) smsLabels {return [self labelsForProperty:kABPersonInstantMessageProperty];} +- (NSArray *) imArray {return [self arrayForProperty:kABPersonInstantMessageProperty];} +- (NSArray *) imLabels {return [self labelsForProperty:kABPersonInstantMessageProperty];} + +- (NSArray *) socialArray {return [self arrayForProperty:kABPersonSocialProfileProperty];} +- (NSArray *) socialLabels {return [self labelsForProperty:kABPersonSocialProfileProperty];} + +// Multi-string convenience - (NSString *) phonenumbers {return [self.phoneArray componentsJoinedByString:@" "];} - (NSString *) emailaddresses {return [self.emailArray componentsJoinedByString:@" "];} - (NSString *) urls {return [self.urlArray componentsJoinedByString:@" "];} +// MultiValue convenience - (NSArray *) dictionaryArrayForProperty: (ABPropertyID) aProperty { - NSArray *valueArray = [self arrayForProperty:aProperty]; - NSArray *labelArray = [self labelsForProperty:aProperty]; - - int num = MIN(valueArray.count, labelArray.count); - NSMutableArray *items = [NSMutableArray array]; - for (int i = 0; i < num; i++) - { - NSMutableDictionary *md = [NSMutableDictionary dictionary]; - [md setObject:[valueArray objectAtIndex:i] forKey:@"value"]; - [md setObject:[labelArray objectAtIndex:i] forKey:@"label"]; - [items addObject:md]; - } - return items; + NSArray *valueArray = [self arrayForProperty:aProperty]; + NSArray *labelArray = [self labelsForProperty:aProperty]; + + int num = MIN(valueArray.count, labelArray.count); + NSMutableArray *items = [NSMutableArray array]; + for (int i = 0; i < num; i++) + { + NSMutableDictionary *md = [NSMutableDictionary dictionary]; + [md setObject:[valueArray objectAtIndex:i] forKey:@"value"]; + [md setObject:[labelArray objectAtIndex:i] forKey:@"label"]; + [items addObject:md]; + } + return items; } +#pragma mark MultiValue Dictionary Arrays + - (NSArray *) emailDictionaries { - return [self dictionaryArrayForProperty:kABPersonEmailProperty]; + return [self dictionaryArrayForProperty:kABPersonEmailProperty]; } - (NSArray *) phoneDictionaries { - return [self dictionaryArrayForProperty:kABPersonPhoneProperty]; + return [self dictionaryArrayForProperty:kABPersonPhoneProperty]; } - (NSArray *) relatedNameDictionaries { - return [self dictionaryArrayForProperty:kABPersonRelatedNamesProperty]; + return [self dictionaryArrayForProperty:kABPersonRelatedNamesProperty]; } - (NSArray *) urlDictionaries { - return [self dictionaryArrayForProperty:kABPersonURLProperty]; + return [self dictionaryArrayForProperty:kABPersonURLProperty]; } - (NSArray *) dateDictionaries { - return [self dictionaryArrayForProperty:kABPersonDateProperty]; + return [self dictionaryArrayForProperty:kABPersonDateProperty]; } - (NSArray *) addressDictionaries { - return [self dictionaryArrayForProperty:kABPersonAddressProperty]; + return [self dictionaryArrayForProperty:kABPersonAddressProperty]; } -- (NSArray *) smsDictionaries +- (NSArray *) imDictionaries { - return [self dictionaryArrayForProperty:kABPersonInstantMessageProperty]; + return [self dictionaryArrayForProperty:kABPersonInstantMessageProperty]; } -#pragma mark Setting Strings -- (BOOL) setString: (NSString *) aString forProperty:(ABPropertyID) anID +- (NSArray *) socialDictionaries { - CFErrorRef error; - BOOL success = ABRecordSetValue(record, anID, (CFStringRef) aString, &error); - if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]); - return success; + return [self dictionaryArrayForProperty:kABPersonSocialProfileProperty]; } -- (void) setFirstname: (NSString *) aString {[self setString: aString forProperty: kABPersonFirstNameProperty];} -- (void) setMiddlename: (NSString *) aString {[self setString: aString forProperty: kABPersonMiddleNameProperty];} -- (void) setLastname: (NSString *) aString {[self setString: aString forProperty: kABPersonLastNameProperty];} +#pragma mark Building Addresses, Social, and IM -- (void) setPrefix: (NSString *) aString {[self setString: aString forProperty: kABPersonPrefixProperty];} -- (void) setSuffix: (NSString *) aString {[self setString: aString forProperty: kABPersonSuffixProperty];} -- (void) setNickname: (NSString *) aString {[self setString: aString forProperty: kABPersonNicknameProperty];} +/* +// kABPersonAddressStreetKey, kABPersonAddressCityKey, kABPersonAddressStateKey +// kABPersonAddressZIPKey, kABPersonAddressCountryKey, kABPersonAddressCountryCodeKey +*/ ++ (NSDictionary *) addressWithStreet: (NSString *) street withCity: (NSString *) city + withState:(NSString *) state withZip: (NSString *) zip + withCountry: (NSString *) country withCode: (NSString *) code +{ + NSMutableDictionary *md = [NSMutableDictionary dictionary]; + if (street) [md setObject:street forKey:(__bridge NSString *) kABPersonAddressStreetKey]; + if (city) [md setObject:city forKey:(__bridge NSString *) kABPersonAddressCityKey]; + if (state) [md setObject:state forKey:(__bridge NSString *) kABPersonAddressStateKey]; + if (zip) [md setObject:zip forKey:(__bridge NSString *) kABPersonAddressZIPKey]; + if (country) [md setObject:country forKey:(__bridge NSString *) kABPersonAddressCountryKey]; + if (code) [md setObject:code forKey:(__bridge NSString *) kABPersonAddressCountryCodeKey]; + return md; +} -- (void) setFirstnamephonetic: (NSString *) aString {[self setString: aString forProperty: kABPersonFirstNamePhoneticProperty];} -- (void) setMiddlenamephonetic: (NSString *) aString {[self setString: aString forProperty: kABPersonMiddleNamePhoneticProperty];} -- (void) setLastnamephonetic: (NSString *) aString {[self setString: aString forProperty: kABPersonLastNamePhoneticProperty];} +/* + Service Names: + const CFStringRef kABPersonSocialProfileServiceTwitter; + const CFStringRef kABPersonSocialProfileServiceGameCenter; + const CFStringRef kABPersonSocialProfileServiceFacebook; + const CFStringRef kABPersonSocialProfileServiceMyspace; + const CFStringRef kABPersonSocialProfileServiceLinkedIn; + const CFStringRef kABPersonSocialProfileServiceFlickr; +*/ ++ (NSDictionary *) socialWithURL: (NSString *) url withService: (NSString *) serviceName + withUsername: (NSString *) username withIdentifier: (NSString *) key +{ + NSMutableDictionary *md = [NSMutableDictionary dictionary]; + if (url) [md setObject:url forKey:(__bridge NSString *) kABPersonSocialProfileURLKey]; + if (serviceName) [md setObject:serviceName forKey:(__bridge NSString *) kABPersonSocialProfileServiceKey]; + if (username) [md setObject:username forKey:(__bridge NSString *) kABPersonSocialProfileUsernameKey]; + if (key) [md setObject:key forKey:(__bridge NSString *) kABPersonSocialProfileUserIdentifierKey]; + return md; +} -- (void) setOrganization: (NSString *) aString {[self setString: aString forProperty: kABPersonOrganizationProperty];} -- (void) setJobtitle: (NSString *) aString {[self setString: aString forProperty: kABPersonJobTitleProperty];} -- (void) setDepartment: (NSString *) aString {[self setString: aString forProperty: kABPersonDepartmentProperty];} +/* + // kABWorkLabel, kABHomeLabel, kABOtherLabel, + const CFStringRef kABPersonInstantMessageServiceYahoo; + const CFStringRef kABPersonInstantMessageServiceJabber; + const CFStringRef kABPersonInstantMessageServiceMSN; + const CFStringRef kABPersonInstantMessageServiceICQ; + const CFStringRef kABPersonInstantMessageServiceAIM; + const CFStringRef kABPersonInstantMessageServiceFacebook; + const CFStringRef kABPersonInstantMessageServiceGaduGadu; + const CFStringRef kABPersonInstantMessageServiceGoogleTalk; + const CFStringRef kABPersonInstantMessageServiceQQ; + const CFStringRef kABPersonInstantMessageServiceSkype; +*/ ++ (NSDictionary *) imWithService: (CFStringRef) service andUser: (NSString *) userName +{ + NSMutableDictionary *im = [NSMutableDictionary dictionary]; + if (service) [im setObject:(__bridge NSString *) service forKey:(__bridge NSString *) kABPersonInstantMessageServiceKey]; + if (userName) [im setObject:userName forKey:(__bridge NSString *) kABPersonInstantMessageUsernameKey]; + return im; +} -- (void) setNote: (NSString *) aString {[self setString: aString forProperty: kABPersonNoteProperty];} +#pragma mark MultiValue Addition Utilities -#pragma mark Setting Numbers -- (BOOL) setNumber: (NSNumber *) aNumber forProperty:(ABPropertyID) anID +- (BOOL) addAddress: (NSDictionary *) dictionary { - CFErrorRef error; - BOOL success = ABRecordSetValue(record, anID, (CFNumberRef) aNumber, &error); - if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]); - return success; + if (!dictionary) return NO; + if (![ABContact isMultivalueDictionary:dictionary]) return NO; + + NSArray *current = self.addressDictionaries; + NSMutableArray *mutable = [NSMutableArray array]; + if (current) + [mutable addObjectsFromArray:current]; + [mutable addObject:dictionary]; + self.addressDictionaries = mutable; + + return YES; } -// const CFNumberRef kABPersonKindPerson; -// const CFNumberRef kABPersonKindOrganization; -- (void) setKind: (NSNumber *) aKind {[self setNumber:aKind forProperty: kABPersonKindProperty];} +- (BOOL) addAddressItem:(NSDictionary *)dictionary withLabel: (CFStringRef) label +{ + if (!dictionary) return NO; + if ([ABContact isMultivalueDictionary:dictionary]) + return [self addAddress:dictionary]; + + NSDictionary *multi = [ABContact dictionaryWithValue:dictionary andLabel:label]; + return [self addAddress:multi]; +} -#pragma mark Setting Dates +- (BOOL) addIM: (NSDictionary *) dictionary +{ + if (!dictionary) return NO; + if (![ABContact isMultivalueDictionary:dictionary]) return NO; + + NSArray *current = self.imDictionaries; + NSMutableArray *mutable = [NSMutableArray array]; + if (current) + [mutable addObjectsFromArray:current]; + [mutable addObject:dictionary]; + self.imDictionaries = mutable; + + return YES; +} -- (BOOL) setDate: (NSDate *) aDate forProperty:(ABPropertyID) anID +- (BOOL) addIMItem:(NSDictionary *)dictionary withLabel: (CFStringRef) label { - CFErrorRef error; - BOOL success = ABRecordSetValue(record, anID, (CFDateRef) aDate, &error); - if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]); - return success; + if (!dictionary) return NO; + if ([ABContact isMultivalueDictionary:dictionary]) + return [self addIM:dictionary]; + + NSDictionary *multi = [ABContact dictionaryWithValue:dictionary andLabel:label]; + return [self addIM:multi]; } -- (void) setBirthday: (NSDate *) aDate {[self setDate: aDate forProperty: kABPersonBirthdayProperty];} + +- (BOOL) addEmail: (NSDictionary *) dictionary +{ + if (!dictionary) return NO; + if (![ABContact isMultivalueDictionary:dictionary]) return NO; + + NSArray *current = self.emailDictionaries; + NSMutableArray *mutable = [NSMutableArray array]; + if (current) + [mutable addObjectsFromArray:current]; + [mutable addObject:dictionary]; + self.emailDictionaries = mutable; + + return YES; +} + +- (BOOL) addEmailItem: (NSString *) value withLabel: (CFStringRef) label +{ + if (!value) return NO; + NSDictionary *multi = [ABContact dictionaryWithValue:value andLabel:label]; + return [self addEmail:multi]; +} + +- (BOOL) addPhone: (NSDictionary *) dictionary +{ + if (!dictionary) return NO; + if (![ABContact isMultivalueDictionary:dictionary]) return NO; + + NSArray *current = self.phoneDictionaries; + NSMutableArray *mutable = [NSMutableArray array]; + + if (current) + [mutable addObjectsFromArray:current]; + [mutable addObject:dictionary]; + self.phoneDictionaries = mutable; + + return YES; +} + +- (BOOL) addPhoneItem: (NSString *) value withLabel: (CFStringRef) label +{ + if (!value) return NO; + NSDictionary *multi = [ABContact dictionaryWithValue:value andLabel:label]; + return [self addPhone:multi]; +} + +- (BOOL) addURL: (NSDictionary *) dictionary +{ + if (!dictionary) return NO; + if (![ABContact isMultivalueDictionary:dictionary]) return NO; + + NSArray *current = self.urlDictionaries; + NSMutableArray *mutable = [NSMutableArray array]; + if (current) + [mutable addObjectsFromArray:current]; + [mutable addObject:dictionary]; + self.urlDictionaries = mutable; + + return YES; +} + +- (BOOL) addURLItem: (NSString *) value withLabel: (CFStringRef) label +{ + if (!value) return NO; + NSDictionary *multi = [ABContact dictionaryWithValue:value andLabel:label]; + return [self addURL:multi]; +} + +- (BOOL) addSocial: (NSDictionary *) dictionary +{ + if (!dictionary) return NO; + if (![ABContact isMultivalueDictionary:dictionary]) return NO; + + NSArray *current = self.socialDictionaries; + NSMutableArray *mutable = [NSMutableArray array]; + if (current) + [mutable addObjectsFromArray:current]; + [mutable addObject:dictionary]; + self.socialDictionaries = mutable; + + return YES; +} + +- (BOOL) addSocialItem: (NSDictionary *) dictionary withLabel: (CFStringRef) label +{ + if (!dictionary) return NO; + if ([ABContact isMultivalueDictionary:dictionary]) + return [self addSocial:dictionary]; + + NSDictionary *multi = [ABContact dictionaryWithValue:dictionary andLabel:label]; + return [self addSocial:multi]; +} #pragma mark Setting MultiValue -- (BOOL) setMulti: (ABMutableMultiValueRef) multi forProperty: (ABPropertyID) anID +- (BOOL) setMultiValue: (ABMutableMultiValueRef) multi forProperty: (ABPropertyID) anID { - CFErrorRef error; - BOOL success = ABRecordSetValue(record, anID, multi, &error); - if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]); - return success; + CFErrorRef cfError = NULL; + BOOL success = ABRecordSetValue(record, anID, multi, &cfError); + if (!success) + { + NSError *error = (__bridge_transfer NSError *) cfError; + NSLog(@"Error: %@", error.localizedFailureReason); + } + return success; } -- (ABMutableMultiValueRef) createMultiValueFromArray: (NSArray *) anArray withType: (ABPropertyType) aType +- (ABMutableMultiValueRef) copyMultiValueFromArray: (NSArray *) anArray withType: (ABPropertyType) aType { - ABMutableMultiValueRef multi = ABMultiValueCreateMutable(aType); - for (NSDictionary *dict in anArray) - ABMultiValueAddValueAndLabel(multi, (CFTypeRef) [dict objectForKey:@"value"], (CFTypeRef) [dict objectForKey:@"label"], NULL); - - return CFAutorelease(multi); + ABMutableMultiValueRef multi = ABMultiValueCreateMutable(aType); + for (NSDictionary *dict in anArray) + { + if (![ABContact isMultivalueDictionary:dict]) + continue; + ABMultiValueAddValueAndLabel(multi, (__bridge CFTypeRef) [dict objectForKey:@"value"], (__bridge CFTypeRef) [dict objectForKey:@"label"], NULL); + } + return multi; } - (void) setEmailDictionaries: (NSArray *) dictionaries { - // kABWorkLabel, kABHomeLabel, kABOtherLabel - ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiStringPropertyType]; - [self setMulti:multi forProperty:kABPersonEmailProperty]; - // CFRelease(multi); + // kABWorkLabel, kABHomeLabel, kABOtherLabel + ABMutableMultiValueRef multi = [self copyMultiValueFromArray:dictionaries withType:kABMultiStringPropertyType]; + [self setMultiValue:multi forProperty:kABPersonEmailProperty]; + CFRelease(multi); } - (void) setPhoneDictionaries: (NSArray *) dictionaries { - // kABWorkLabel, kABHomeLabel, kABOtherLabel - // kABPersonPhoneMobileLabel, kABPersonPhoneIPhoneLabel, kABPersonPhoneMainLabel - // kABPersonPhoneHomeFAXLabel, kABPersonPhoneWorkFAXLabel, kABPersonPhonePagerLabel - ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiStringPropertyType]; - [self setMulti:multi forProperty:kABPersonPhoneProperty]; - // CFRelease(multi); + // kABWorkLabel, kABHomeLabel, kABOtherLabel + // kABPersonPhoneMobileLabel, kABPersonPhoneIPhoneLabel, kABPersonPhoneMainLabel + // kABPersonPhoneHomeFAXLabel, kABPersonPhoneWorkFAXLabel, kABPersonPhonePagerLabel + // kABPersonPhoneOtherFAXLabel + + ABMutableMultiValueRef multi = [self copyMultiValueFromArray:dictionaries withType:kABMultiStringPropertyType]; + [self setMultiValue:multi forProperty:kABPersonPhoneProperty]; + CFRelease(multi); } - (void) setUrlDictionaries: (NSArray *) dictionaries { - // kABWorkLabel, kABHomeLabel, kABOtherLabel - // kABPersonHomePageLabel - ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiStringPropertyType]; - [self setMulti:multi forProperty:kABPersonURLProperty]; - // CFRelease(multi); + // kABWorkLabel, kABHomeLabel, kABOtherLabel + // kABPersonHomePageLabel + ABMutableMultiValueRef multi = [self copyMultiValueFromArray:dictionaries withType:kABMultiStringPropertyType]; + [self setMultiValue:multi forProperty:kABPersonURLProperty]; + CFRelease(multi); } // Not used/shown on iPhone - (void) setRelatedNameDictionaries: (NSArray *) dictionaries { - // kABWorkLabel, kABHomeLabel, kABOtherLabel - // kABPersonMotherLabel, kABPersonFatherLabel, kABPersonParentLabel, - // kABPersonSisterLabel, kABPersonBrotherLabel, kABPersonChildLabel, - // kABPersonFriendLabel, kABPersonSpouseLabel, kABPersonPartnerLabel, - // kABPersonManagerLabel, kABPersonAssistantLabel - ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiStringPropertyType]; - [self setMulti:multi forProperty:kABPersonRelatedNamesProperty]; - // CFRelease(multi); + // kABWorkLabel, kABHomeLabel, kABOtherLabel + // kABPersonMotherLabel, kABPersonFatherLabel, kABPersonParentLabel, + // kABPersonSisterLabel, kABPersonBrotherLabel, kABPersonChildLabel, + // kABPersonFriendLabel, kABPersonSpouseLabel, kABPersonPartnerLabel, + // kABPersonManagerLabel, kABPersonAssistantLabel + ABMutableMultiValueRef multi = [self copyMultiValueFromArray:dictionaries withType:kABMultiStringPropertyType]; + [self setMultiValue:multi forProperty:kABPersonRelatedNamesProperty]; + CFRelease(multi); } - (void) setDateDictionaries: (NSArray *) dictionaries { - // kABWorkLabel, kABHomeLabel, kABOtherLabel - // kABPersonAnniversaryLabel - ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiDateTimePropertyType]; - [self setMulti:multi forProperty:kABPersonDateProperty]; - // CFRelease(multi); + // kABWorkLabel, kABHomeLabel, kABOtherLabel + // kABPersonAnniversaryLabel + ABMutableMultiValueRef multi = [self copyMultiValueFromArray:dictionaries withType:kABMultiDateTimePropertyType]; + [self setMultiValue:multi forProperty:kABPersonDateProperty]; + CFRelease(multi); } - (void) setAddressDictionaries: (NSArray *) dictionaries { - // kABPersonAddressStreetKey, kABPersonAddressCityKey, kABPersonAddressStateKey - // kABPersonAddressZIPKey, kABPersonAddressCountryKey, kABPersonAddressCountryCodeKey - ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiDictionaryPropertyType]; - [self setMulti:multi forProperty:kABPersonAddressProperty]; - // CFRelease(multi); + // kABPersonAddressStreetKey, kABPersonAddressCityKey, kABPersonAddressStateKey + // kABPersonAddressZIPKey, kABPersonAddressCountryKey, kABPersonAddressCountryCodeKey + ABMutableMultiValueRef multi = [self copyMultiValueFromArray:dictionaries withType:kABMultiDictionaryPropertyType]; + [self setMultiValue:multi forProperty:kABPersonAddressProperty]; + CFRelease(multi); } -- (void) setSmsDictionaries: (NSArray *) dictionaries +- (void) setImDictionaries: (NSArray *) dictionaries { - // kABWorkLabel, kABHomeLabel, kABOtherLabel, - // kABPersonInstantMessageServiceKey, kABPersonInstantMessageUsernameKey - // kABPersonInstantMessageServiceYahoo, kABPersonInstantMessageServiceJabber - // kABPersonInstantMessageServiceMSN, kABPersonInstantMessageServiceICQ - // kABPersonInstantMessageServiceAIM, - ABMutableMultiValueRef multi = [self createMultiValueFromArray:dictionaries withType:kABMultiDictionaryPropertyType]; - [self setMulti:multi forProperty:kABPersonInstantMessageProperty]; - // CFRelease(multi); + // kABWorkLabel, kABHomeLabel, kABOtherLabel, + // kABPersonInstantMessageServiceKey, kABPersonInstantMessageUsernameKey + // kABPersonInstantMessageServiceYahoo, kABPersonInstantMessageServiceJabber + // kABPersonInstantMessageServiceMSN, kABPersonInstantMessageServiceICQ + // kABPersonInstantMessageServiceAIM, + ABMutableMultiValueRef multi = [self copyMultiValueFromArray:dictionaries withType:kABMultiDictionaryPropertyType]; + [self setMultiValue:multi forProperty:kABPersonInstantMessageProperty]; + CFRelease(multi); } -#pragma mark Images -- (UIImage *) image +- (void) setSocialDictionaries:(NSArray *)dictionaries { - if (!ABPersonHasImageData(record)) return nil; - CFDataRef imageData = ABPersonCopyImageData(record); - UIImage *image = [UIImage imageWithData:(NSData *) imageData]; - CFRelease(imageData); - return image; -} + // kABWorkLabel, kABHomeLabel, kABOtherLabel, + // kABPersonSocialProfileServiceTwitter + // kABPersonSocialProfileServiceGameCenter + // kABPersonSocialProfileServiceFacebook + // kABPersonSocialProfileServiceMyspace + // kABPersonSocialProfileServiceLinkedIn + // kABPersonSocialProfileServiceFlickr -- (void) setImage: (UIImage *) image -{ - CFErrorRef error; - BOOL success; - - if (image == nil) // remove - { - if (!ABPersonHasImageData(record)) return; // no image to remove - success = ABPersonRemoveImageData(record, &error); - if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]); - return; - } - - NSData *data = UIImagePNGRepresentation(image); - success = ABPersonSetImageData(record, (CFDataRef) data, &error); - if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]); + ABMutableMultiValueRef multi = [self copyMultiValueFromArray:dictionaries withType:kABMultiDictionaryPropertyType]; + [self setMultiValue:multi forProperty:kABPersonSocialProfileProperty]; + CFRelease(multi); } #pragma mark Representations @@ -616,131 +854,156 @@ - (void) setImage: (UIImage *) image // No Image - (NSDictionary *) baseDictionaryRepresentation { - NSMutableDictionary *dict = [NSMutableDictionary dictionary]; - if (self.firstname) [dict setObject:self.firstname forKey:FIRST_NAME_STRING]; - if (self.middlename) [dict setObject:self.middlename forKey:MIDDLE_NAME_STRING]; - if (self.lastname) [dict setObject:self.lastname forKey:LAST_NAME_STRING]; - - if (self.prefix) [dict setObject:self.prefix forKey:PREFIX_STRING]; - if (self.suffix) [dict setObject:self.suffix forKey:SUFFIX_STRING]; - if (self.nickname) [dict setObject:self.nickname forKey:NICKNAME_STRING]; - - if (self.firstnamephonetic) [dict setObject:self.firstnamephonetic forKey:PHONETIC_FIRST_STRING]; - if (self.middlenamephonetic) [dict setObject:self.middlenamephonetic forKey:PHONETIC_MIDDLE_STRING]; - if (self.lastnamephonetic) [dict setObject:self.lastnamephonetic forKey:PHONETIC_LAST_STRING]; - - if (self.organization) [dict setObject:self.organization forKey:ORGANIZATION_STRING]; - if (self.jobtitle) [dict setObject:self.jobtitle forKey:JOBTITLE_STRING]; - if (self.department) [dict setObject:self.department forKey:DEPARTMENT_STRING]; - - if (self.note) [dict setObject:self.note forKey:NOTE_STRING]; - - if (self.kind) [dict setObject:self.kind forKey:KIND_STRING]; - - if (self.birthday) [dict setObject:self.birthday forKey:BIRTHDAY_STRING]; - if (self.creationDate) [dict setObject:self.creationDate forKey:CREATION_DATE_STRING]; - if (self.modificationDate) [dict setObject:self.modificationDate forKey:MODIFICATION_DATE_STRING]; - - [dict setObject:self.emailDictionaries forKey:EMAIL_STRING]; - [dict setObject:self.addressDictionaries forKey:ADDRESS_STRING]; - [dict setObject:self.dateDictionaries forKey:DATE_STRING]; - [dict setObject:self.phoneDictionaries forKey:PHONE_STRING]; - [dict setObject:self.smsDictionaries forKey:SMS_STRING]; - [dict setObject:self.urlDictionaries forKey:URL_STRING]; - [dict setObject:self.relatedNameDictionaries forKey:RELATED_STRING]; - - return dict; + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self.firstname) [dict setObject:self.firstname forKey:FIRST_NAME_STRING]; + if (self.middlename) [dict setObject:self.middlename forKey:MIDDLE_NAME_STRING]; + if (self.lastname) [dict setObject:self.lastname forKey:LAST_NAME_STRING]; + + if (self.prefix) [dict setObject:self.prefix forKey:PREFIX_STRING]; + if (self.suffix) [dict setObject:self.suffix forKey:SUFFIX_STRING]; + if (self.nickname) [dict setObject:self.nickname forKey:NICKNAME_STRING]; + + if (self.firstnamephonetic) [dict setObject:self.firstnamephonetic forKey:PHONETIC_FIRST_STRING]; + if (self.middlenamephonetic) [dict setObject:self.middlenamephonetic forKey:PHONETIC_MIDDLE_STRING]; + if (self.lastnamephonetic) [dict setObject:self.lastnamephonetic forKey:PHONETIC_LAST_STRING]; + + if (self.organization) [dict setObject:self.organization forKey:ORGANIZATION_STRING]; + if (self.jobtitle) [dict setObject:self.jobtitle forKey:JOBTITLE_STRING]; + if (self.department) [dict setObject:self.department forKey:DEPARTMENT_STRING]; + + if (self.note) [dict setObject:self.note forKey:NOTE_STRING]; + + if (self.kind) [dict setObject:self.kind forKey:KIND_STRING]; + + if (self.birthday) [dict setObject:self.birthday forKey:BIRTHDAY_STRING]; + if (self.creationDate) [dict setObject:self.creationDate forKey:CREATION_DATE_STRING]; + if (self.modificationDate) [dict setObject:self.modificationDate forKey:MODIFICATION_DATE_STRING]; + + [dict setObject:self.emailDictionaries forKey:EMAIL_STRING]; + [dict setObject:self.addressDictionaries forKey:ADDRESS_STRING]; + [dict setObject:self.dateDictionaries forKey:DATE_STRING]; + [dict setObject:self.phoneDictionaries forKey:PHONE_STRING]; + [dict setObject:self.imDictionaries forKey:IM_STRING]; + [dict setObject:self.urlDictionaries forKey:URL_STRING]; + [dict setObject:self.relatedNameDictionaries forKey:RELATED_STRING]; + + return dict; } // With image where available - (NSDictionary *) dictionaryRepresentation { - NSMutableDictionary *dict = [[[self baseDictionaryRepresentation] mutableCopy] autorelease]; - if (ABPersonHasImageData(record)) - { - CFDataRef imageData = ABPersonCopyImageData(record); - [dict setObject:(NSData *)imageData forKey:IMAGE_STRING]; - CFRelease(imageData); - } - return dict; + NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[self baseDictionaryRepresentation]]; + if (ABPersonHasImageData(record)) + { + CFDataRef imageData = ABPersonCopyImageData(record); + NSData *data = (__bridge_transfer NSData *)imageData; + [dict setObject:data forKey:IMAGE_STRING]; + } + return dict; } // No Image - (NSData *) baseDataRepresentation { - NSString *errorString; - NSDictionary *dict = [self baseDictionaryRepresentation]; - NSData *data = [NSPropertyListSerialization dataFromPropertyList:dict format:NSPropertyListXMLFormat_v1_0 errorDescription:&errorString]; - if (!data) CFShow(errorString); - return data; + NSString *errorString; + NSDictionary *dict = [self baseDictionaryRepresentation]; + NSData *data = [NSPropertyListSerialization dataFromPropertyList:dict format:NSPropertyListXMLFormat_v1_0 errorDescription:&errorString]; + if (!data) + NSLog(@"Error: %@", errorString); + return data; } // With image where available - (NSData *) dataRepresentation { - NSString *errorString; - NSDictionary *dict = [self dictionaryRepresentation]; - NSData *data = [NSPropertyListSerialization dataFromPropertyList:dict format:NSPropertyListXMLFormat_v1_0 errorDescription:&errorString]; - if (!data) CFShow(errorString); - return data; + NSString *errorString; + NSDictionary *dict = [self dictionaryRepresentation]; + NSData *data = [NSPropertyListSerialization dataFromPropertyList:dict format:NSPropertyListXMLFormat_v1_0 errorDescription:&errorString]; + if (!data) + NSLog(@"Error: %@", errorString); + return data; } + (id) contactWithDictionary: (NSDictionary *) dict { - ABContact *contact = [ABContact contact]; - if ([dict objectForKey:FIRST_NAME_STRING]) contact.firstname = [dict objectForKey:FIRST_NAME_STRING]; - if ([dict objectForKey:MIDDLE_NAME_STRING]) contact.middlename = [dict objectForKey:MIDDLE_NAME_STRING]; - if ([dict objectForKey:LAST_NAME_STRING]) contact.lastname = [dict objectForKey:LAST_NAME_STRING]; - - if ([dict objectForKey:PREFIX_STRING]) contact.prefix = [dict objectForKey:PREFIX_STRING]; - if ([dict objectForKey:SUFFIX_STRING]) contact.suffix = [dict objectForKey:SUFFIX_STRING]; - if ([dict objectForKey:NICKNAME_STRING]) contact.nickname = [dict objectForKey:NICKNAME_STRING]; - - if ([dict objectForKey:PHONETIC_FIRST_STRING]) contact.firstnamephonetic = [dict objectForKey:PHONETIC_FIRST_STRING]; - if ([dict objectForKey:PHONETIC_MIDDLE_STRING]) contact.middlenamephonetic = [dict objectForKey:PHONETIC_MIDDLE_STRING]; - if ([dict objectForKey:PHONETIC_LAST_STRING]) contact.lastnamephonetic = [dict objectForKey:PHONETIC_LAST_STRING]; - - if ([dict objectForKey:ORGANIZATION_STRING]) contact.organization = [dict objectForKey:ORGANIZATION_STRING]; - if ([dict objectForKey:JOBTITLE_STRING]) contact.jobtitle = [dict objectForKey:JOBTITLE_STRING]; - if ([dict objectForKey:DEPARTMENT_STRING]) contact.department = [dict objectForKey:DEPARTMENT_STRING]; - - if ([dict objectForKey:NOTE_STRING]) contact.note = [dict objectForKey:NOTE_STRING]; - - if ([dict objectForKey:KIND_STRING]) contact.kind = [dict objectForKey:KIND_STRING]; - - if ([dict objectForKey:EMAIL_STRING]) contact.emailDictionaries = [dict objectForKey:EMAIL_STRING]; - if ([dict objectForKey:ADDRESS_STRING]) contact.addressDictionaries = [dict objectForKey:ADDRESS_STRING]; - if ([dict objectForKey:DATE_STRING]) contact.dateDictionaries = [dict objectForKey:DATE_STRING]; - if ([dict objectForKey:PHONE_STRING]) contact.phoneDictionaries = [dict objectForKey:PHONE_STRING]; - if ([dict objectForKey:SMS_STRING]) contact.smsDictionaries = [dict objectForKey:SMS_STRING]; - if ([dict objectForKey:URL_STRING]) contact.urlDictionaries = [dict objectForKey:URL_STRING]; - if ([dict objectForKey:RELATED_STRING]) contact.relatedNameDictionaries = [dict objectForKey:RELATED_STRING]; - - if ([dict objectForKey:IMAGE_STRING]) - { - CFErrorRef error; - BOOL success = ABPersonSetImageData(contact.record, (CFDataRef) [dict objectForKey:IMAGE_STRING], &error); - if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]); - } - - return contact; + ABContact *contact = [ABContact contact]; + if ([dict objectForKey:FIRST_NAME_STRING]) + contact.firstname = [dict objectForKey:FIRST_NAME_STRING]; + if ([dict objectForKey:MIDDLE_NAME_STRING]) + contact.middlename = [dict objectForKey:MIDDLE_NAME_STRING]; + if ([dict objectForKey:LAST_NAME_STRING]) + contact.lastname = [dict objectForKey:LAST_NAME_STRING]; + + if ([dict objectForKey:PREFIX_STRING]) + contact.prefix = [dict objectForKey:PREFIX_STRING]; + if ([dict objectForKey:SUFFIX_STRING]) + contact.suffix = [dict objectForKey:SUFFIX_STRING]; + if ([dict objectForKey:NICKNAME_STRING]) + contact.nickname = [dict objectForKey:NICKNAME_STRING]; + + if ([dict objectForKey:PHONETIC_FIRST_STRING]) + contact.firstnamephonetic = [dict objectForKey:PHONETIC_FIRST_STRING]; + if ([dict objectForKey:PHONETIC_MIDDLE_STRING]) + contact.middlenamephonetic = [dict objectForKey:PHONETIC_MIDDLE_STRING]; + if ([dict objectForKey:PHONETIC_LAST_STRING]) + contact.lastnamephonetic = [dict objectForKey:PHONETIC_LAST_STRING]; + + if ([dict objectForKey:ORGANIZATION_STRING]) + contact.organization = [dict objectForKey:ORGANIZATION_STRING]; + if ([dict objectForKey:JOBTITLE_STRING]) + contact.jobtitle = [dict objectForKey:JOBTITLE_STRING]; + if ([dict objectForKey:DEPARTMENT_STRING]) + contact.department = [dict objectForKey:DEPARTMENT_STRING]; + + if ([dict objectForKey:NOTE_STRING]) + contact.note = [dict objectForKey:NOTE_STRING]; + + if ([dict objectForKey:KIND_STRING]) + contact.kind = [dict objectForKey:KIND_STRING]; + + if ([dict objectForKey:EMAIL_STRING]) + contact.emailDictionaries = [dict objectForKey:EMAIL_STRING]; + if ([dict objectForKey:ADDRESS_STRING]) + contact.addressDictionaries = [dict objectForKey:ADDRESS_STRING]; + if ([dict objectForKey:DATE_STRING]) + contact.dateDictionaries = [dict objectForKey:DATE_STRING]; + if ([dict objectForKey:PHONE_STRING]) + contact.phoneDictionaries = [dict objectForKey:PHONE_STRING]; + if ([dict objectForKey:IM_STRING]) + contact.imDictionaries = [dict objectForKey:IM_STRING]; + if ([dict objectForKey:URL_STRING]) + contact.urlDictionaries = [dict objectForKey:URL_STRING]; + if ([dict objectForKey:RELATED_STRING]) + contact.relatedNameDictionaries = [dict objectForKey:RELATED_STRING]; + + if ([dict objectForKey:IMAGE_STRING]) + { + CFErrorRef cfError = NULL; + BOOL success = ABPersonSetImageData(contact.record, (__bridge CFDataRef) [dict objectForKey:IMAGE_STRING], &cfError); + if (!success) + { + NSError *error = (__bridge_transfer NSError *) cfError; + NSLog(@"Error: %@", error.localizedFailureReason); + } + } + + return contact; } + (id) contactWithData: (NSData *) data { - // Otherwise handle points - CFStringRef errorString; - CFPropertyListRef plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, (CFDataRef)data, kCFPropertyListMutableContainers, &errorString); - if (!plist) - { - CFShow(errorString); - return nil; - } - - NSDictionary *dict = (NSDictionary *) plist; - [dict autorelease]; - - return [self contactWithDictionary:dict]; + // Otherwise handle points + CFStringRef errorString; + CFPropertyListRef plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, (__bridge CFDataRef)data, kCFPropertyListMutableContainers, &errorString); + if (!plist) + { + CFShow(errorString); + return nil; + } + + NSDictionary *dict = (__bridge_transfer NSDictionary *) plist; + return [self contactWithDictionary:dict]; } @end \ No newline at end of file diff --git a/ABContactsHelper.h b/ABContactsHelper.h old mode 100644 new mode 100755 index 14ee803..2b2ad98 --- a/ABContactsHelper.h +++ b/ABContactsHelper.h @@ -14,6 +14,7 @@ // Address Book + (ABAddressBookRef) addressBook; ++ (void) refresh; // Address Book Contacts and Groups + (NSArray *) contacts; // people @@ -36,6 +37,7 @@ + (NSArray *) contactsMatchingName: (NSString *) fname; + (NSArray *) contactsMatchingName: (NSString *) fname andName: (NSString *) lname; + (NSArray *) contactsMatchingPhone: (NSString *) number; ++ (NSArray *) contactsMatchingOrganization: (NSString *) organization; // Find groups + (NSArray *) groupsMatchingName: (NSString *) fname; diff --git a/ABContactsHelper.m b/ABContactsHelper.m old mode 100644 new mode 100755 index 9ca5b9d..f13e722 --- a/ABContactsHelper.m +++ b/ABContactsHelper.m @@ -5,80 +5,92 @@ */ #import "ABContactsHelper.h" - -#define CFAutorelease(obj) ({CFTypeRef _obj = (obj); (_obj == NULL) ? NULL : [(id)CFMakeCollectable(_obj) autorelease]; }) +#import "ABStandin.h" @implementation ABContactsHelper -/* - Note: You cannot CFRelease the addressbook after CFAutorelease(ABAddressBookCreate()); - */ + +#pragma mark Address Book + + (ABAddressBookRef) addressBook { - return CFAutorelease(ABAddressBookCreate()); + return [ABStandin addressBook]; +} + ++ (void) refresh +{ + [ABStandin currentAddressBook]; } + (NSArray *) contacts { - ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate()); - NSArray *thePeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); - NSMutableArray *array = [NSMutableArray arrayWithCapacity:thePeople.count]; - for (id person in thePeople) - [array addObject:[ABContact contactWithRecord:(ABRecordRef)person]]; - [thePeople release]; - return array; + ABAddressBookRef addressBook = [ABStandin addressBook]; + NSArray *thePeople = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); + NSMutableArray *array = [NSMutableArray arrayWithCapacity:thePeople.count]; + for (id person in thePeople) + [array addObject:[ABContact contactWithRecord:(__bridge ABRecordRef)person]]; + return array; } + (int) contactsCount { - ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate()); - return ABAddressBookGetPersonCount(addressBook); + ABAddressBookRef addressBook = [ABStandin addressBook]; + return ABAddressBookGetPersonCount(addressBook); } + (int) contactsWithImageCount { - ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate()); - NSArray *peopleArray = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); - int ncount = 0; - for (id person in peopleArray) if (ABPersonHasImageData(person)) ncount++; - [peopleArray release]; - return ncount; + ABAddressBookRef addressBook = [ABStandin addressBook]; + NSArray *thePeople = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); + int ncount = 0; + for (id person in thePeople) + { + ABRecordRef abPerson = (__bridge ABRecordRef) person; + if (ABPersonHasImageData(abPerson)) ncount++; + } + return ncount; } + (int) contactsWithoutImageCount { - ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate()); - NSArray *peopleArray = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); - int ncount = 0; - for (id person in peopleArray) if (!ABPersonHasImageData(person)) ncount++; - [peopleArray release]; - return ncount; + ABAddressBookRef addressBook = [ABStandin addressBook]; + NSArray *thePeople = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); + int ncount = 0; + for (id person in thePeople) + { + ABRecordRef abPerson = (__bridge ABRecordRef) person; + if (!ABPersonHasImageData(abPerson)) ncount++; + } + return ncount; } // Groups + (int) numberOfGroups { - ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate()); - NSArray *groups = (NSArray *)ABAddressBookCopyArrayOfAllGroups(addressBook); - int ncount = groups.count; - [groups release]; - return ncount; + ABAddressBookRef addressBook = [ABStandin addressBook]; + NSArray *groups = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllGroups(addressBook); + int ncount = groups.count; + return ncount; } + (NSArray *) groups { - ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate()); - NSArray *groups = (NSArray *)ABAddressBookCopyArrayOfAllGroups(addressBook); - NSMutableArray *array = [NSMutableArray arrayWithCapacity:groups.count]; - for (id group in groups) - [array addObject:[ABGroup groupWithRecord:(ABRecordRef)group]]; - [groups release]; - return array; + ABAddressBookRef addressBook = [ABStandin addressBook]; + NSArray *groups = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllGroups(addressBook); + NSMutableArray *array = [NSMutableArray arrayWithCapacity:groups.count]; + for (id group in groups) + { + ABRecordRef abGroup = (__bridge ABRecordRef) group; + [array addObject:[ABGroup groupWithRecord:abGroup]]; + } + return array; } +#pragma mark Sorting + // Sorting + (BOOL) firstNameSorting { - return (ABPersonGetCompositeNameFormat() == kABPersonCompositeNameFormatFirstNameFirst); + return (ABPersonGetCompositeNameFormat() == kABPersonCompositeNameFormatFirstNameFirst); } #pragma mark Contact Management @@ -86,50 +98,84 @@ + (BOOL) firstNameSorting // Thanks to Eridius for suggestions re: error + (BOOL) addContact: (ABContact *) aContact withError: (NSError **) error { - ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate()); - if (!ABAddressBookAddRecord(addressBook, aContact.record, (CFErrorRef *) error)) return NO; - return ABAddressBookSave(addressBook, (CFErrorRef *) error); + ABAddressBookRef addressBook = [ABStandin addressBook]; + BOOL success; + CFErrorRef cfError = NULL; + + if (!aContact) return NO; + + success = ABAddressBookAddRecord(addressBook, aContact.record, &cfError); + if (!success) + { + if (error) + *error = (__bridge_transfer NSError *)cfError; + return NO; + } + + return YES; } + (BOOL) addGroup: (ABGroup *) aGroup withError: (NSError **) error { - ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate()); - if (!ABAddressBookAddRecord(addressBook, aGroup.record, (CFErrorRef *) error)) return NO; - return ABAddressBookSave(addressBook, (CFErrorRef *) error); + ABAddressBookRef addressBook = [ABStandin addressBook]; + BOOL success; + CFErrorRef cfError = NULL; + + success = ABAddressBookAddRecord(addressBook, aGroup.record, &cfError); + if (!success) + { + if (error) + *error = (__bridge_transfer NSError *)cfError; + return NO; + } + + return NO; } +#pragma mark Searches + + (NSArray *) contactsMatchingName: (NSString *) fname { - NSPredicate *pred; - NSArray *contacts = [ABContactsHelper contacts]; - pred = [NSPredicate predicateWithFormat:@"firstname contains[cd] %@ OR lastname contains[cd] %@ OR nickname contains[cd] %@ OR middlename contains[cd] %@", fname, fname, fname, fname]; - return [contacts filteredArrayUsingPredicate:pred]; + NSPredicate *pred; + NSArray *contacts = [ABContactsHelper contacts]; + pred = [NSPredicate predicateWithFormat:@"firstname contains[cd] %@ OR lastname contains[cd] %@ OR nickname contains[cd] %@ OR middlename contains[cd] %@", fname, fname, fname, fname]; + return [contacts filteredArrayUsingPredicate:pred]; } + (NSArray *) contactsMatchingName: (NSString *) fname andName: (NSString *) lname { - NSPredicate *pred; - NSArray *contacts = [ABContactsHelper contacts]; - pred = [NSPredicate predicateWithFormat:@"firstname contains[cd] %@ OR lastname contains[cd] %@ OR nickname contains[cd] %@ OR middlename contains[cd] %@", fname, fname, fname, fname]; - contacts = [contacts filteredArrayUsingPredicate:pred]; - pred = [NSPredicate predicateWithFormat:@"firstname contains[cd] %@ OR lastname contains[cd] %@ OR nickname contains[cd] %@ OR middlename contains[cd] %@", lname, lname, lname, lname]; - contacts = [contacts filteredArrayUsingPredicate:pred]; - return contacts; + NSPredicate *pred; + NSArray *contacts = [ABContactsHelper contacts]; + pred = [NSPredicate predicateWithFormat:@"firstname contains[cd] %@ OR lastname contains[cd] %@ OR nickname contains[cd] %@ OR middlename contains[cd] %@", fname, fname, fname, fname]; + contacts = [contacts filteredArrayUsingPredicate:pred]; + pred = [NSPredicate predicateWithFormat:@"firstname contains[cd] %@ OR lastname contains[cd] %@ OR nickname contains[cd] %@ OR middlename contains[cd] %@", lname, lname, lname, lname]; + contacts = [contacts filteredArrayUsingPredicate:pred]; + return contacts; } + (NSArray *) contactsMatchingPhone: (NSString *) number +{ + NSPredicate *pred; + NSArray *contacts = [ABContactsHelper contacts]; + pred = [NSPredicate predicateWithFormat:@"phonenumbers contains[cd] %@", number]; + return [contacts filteredArrayUsingPredicate:pred]; +} + +// Thanks Frederic Bronner ++ (NSArray *) contactsMatchingOrganization: (NSString *) organization { NSPredicate *pred; NSArray *contacts = [ABContactsHelper contacts]; - pred = [NSPredicate predicateWithFormat:@"phonenumbers contains[cd] %@", number]; + pred = [NSPredicate predicateWithFormat:@"organization contains[cd] %@", organization]; return [contacts filteredArrayUsingPredicate:pred]; } + + (NSArray *) groupsMatchingName: (NSString *) fname { - NSPredicate *pred; - NSArray *groups = [ABContactsHelper groups]; - pred = [NSPredicate predicateWithFormat:@"name contains[cd] %@ ", fname]; - return [groups filteredArrayUsingPredicate:pred]; + NSPredicate *pred; + NSArray *groups = [ABContactsHelper groups]; + pred = [NSPredicate predicateWithFormat:@"name contains[cd] %@ ", fname]; + return [groups filteredArrayUsingPredicate:pred]; } @end \ No newline at end of file diff --git a/ABGroup.h b/ABGroup.h old mode 100644 new mode 100755 diff --git a/ABGroup.m b/ABGroup.m old mode 100644 new mode 100755 index 766572c..16198ae --- a/ABGroup.m +++ b/ABGroup.m @@ -6,8 +6,7 @@ #import "ABGroup.h" #import "ABContactsHelper.h" - -#define CFAutorelease(obj) ({CFTypeRef _obj = (obj); (_obj == NULL) ? NULL : [(id)CFMakeCollectable(_obj) autorelease]; }) +#import "ABStandin.h" @implementation ABGroup @synthesize record; @@ -15,44 +14,57 @@ @implementation ABGroup // Thanks to Quentarez, Ciaran - (id) initWithRecord: (ABRecordRef) aRecord { - if (self = [super init]) record = CFRetain(aRecord); - return self; + if (self = [super init]) record = CFRetain(aRecord); + return self; +} + +- (void) dealloc +{ + if (record) + CFRelease(record); } + (id) groupWithRecord: (ABRecordRef) grouprec { - return [[[ABGroup alloc] initWithRecord:grouprec] autorelease]; + return [[ABGroup alloc] initWithRecord:grouprec]; } + (id) groupWithRecordID: (ABRecordID) recordID { - ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate()); - ABRecordRef grouprec = ABAddressBookGetGroupWithRecordID(addressBook, recordID); - ABGroup *group = [self groupWithRecord:grouprec]; - CFRelease(grouprec); - return group; + ABAddressBookRef addressBook = [ABStandin addressBook]; + ABRecordRef grouprec = ABAddressBookGetGroupWithRecordID(addressBook, recordID); + ABGroup *group = [self groupWithRecord:grouprec]; + return group; } // Thanks to Ciaran + (id) group { - ABRecordRef grouprec = ABGroupCreate(); - id group = [ABGroup groupWithRecord:grouprec]; - CFRelease(grouprec); - return group; + ABRecordRef grouprec = ABGroupCreate(); + id group = [ABGroup groupWithRecord:grouprec]; + CFRelease(grouprec); + return group; } -- (void) dealloc -{ - if (record) CFRelease(record); - [super dealloc]; -} +// Thanks to Eridius for suggestions re: error +// Thanks Rincewind42 for the *error transfer bridging - (BOOL) removeSelfFromAddressBook: (NSError **) error { - ABAddressBookRef addressBook = CFAutorelease(ABAddressBookCreate()); - if (!ABAddressBookRemoveRecord(addressBook, self.record, (CFErrorRef *) error)) return NO; - return ABAddressBookSave(addressBook, (CFErrorRef *) error); + CFErrorRef cfError = NULL; + BOOL success; + + ABAddressBookRef addressBook = [ABStandin addressBook]; + + success = ABAddressBookRemoveRecord(addressBook, self.record, &cfError); + if (!success) + { + if (error) + *error = (__bridge_transfer NSError *)cfError; + return NO; + } + + return success; } #pragma mark Record ID and Type @@ -63,52 +75,77 @@ - (BOOL) isPerson {return self.recordType == kABPersonType;} #pragma mark management - (NSArray *) members { - NSArray *contacts = (NSArray *)ABGroupCopyArrayOfAllMembers(self.record); - NSMutableArray *array = [NSMutableArray arrayWithCapacity:contacts.count]; - for (id contact in contacts) - [array addObject:[ABContact contactWithRecord:(ABRecordRef)contact]]; - [contacts release]; - return array; + NSArray *contacts = (__bridge_transfer NSArray *)ABGroupCopyArrayOfAllMembers(self.record); + NSMutableArray *array = [NSMutableArray arrayWithCapacity:contacts.count]; + for (id contact in contacts) + [array addObject:[ABContact contactWithRecord:(__bridge ABRecordRef)contact]]; + return array; } // kABPersonSortByFirstName = 0, kABPersonSortByLastName = 1 - (NSArray *) membersWithSorting: (ABPersonSortOrdering) ordering { - NSArray *contacts = (NSArray *)ABGroupCopyArrayOfAllMembersWithSortOrdering(self.record, ordering); - NSMutableArray *array = [NSMutableArray arrayWithCapacity:contacts.count]; - for (id contact in contacts) - [array addObject:[ABContact contactWithRecord:(ABRecordRef)contact]]; - [contacts release]; - return array; + NSArray *contacts = (__bridge_transfer NSArray *)ABGroupCopyArrayOfAllMembersWithSortOrdering(self.record, ordering); + NSMutableArray *array = [NSMutableArray arrayWithCapacity:contacts.count]; + for (id contact in contacts) + [array addObject:[ABContact contactWithRecord:(__bridge ABRecordRef)contact]]; + return array; } - (BOOL) addMember: (ABContact *) contact withError: (NSError **) error { - return ABGroupAddMember(self.record, contact.record, (CFErrorRef *) error); + CFErrorRef cfError = NULL; + BOOL success; + + success = ABGroupAddMember(self.record, contact.record, &cfError); + if (!success) + { + if (error) + *error = (__bridge_transfer NSError *)cfError; + return NO; + } + + return YES; } - (BOOL) removeMember: (ABContact *) contact withError: (NSError **) error { - return ABGroupRemoveMember(self.record, contact.record, (CFErrorRef *) error); + CFErrorRef cfError = NULL; + BOOL success; + + success = ABGroupRemoveMember(self.record, contact.record, &cfError); + if (!success) + { + if (error) + *error = (__bridge_transfer NSError *)cfError; + return NO; + } + + return YES; } #pragma mark name - (NSString *) getRecordString:(ABPropertyID) anID { - return [(NSString *) ABRecordCopyValue(record, anID) autorelease]; + return (__bridge_transfer NSString *) ABRecordCopyValue(record, anID); } - (NSString *) name { - NSString *string = [self getRecordString:kABGroupNameProperty]; - return string; + return [self getRecordString:kABGroupNameProperty]; } - (void) setName: (NSString *) aString { - CFErrorRef error; - BOOL success = ABRecordSetValue(record, kABGroupNameProperty, (CFStringRef) aString, &error); - if (!success) NSLog(@"Error: %@", [(NSError *)error localizedDescription]); + CFErrorRef cfError = NULL; + BOOL success; + + success = ABRecordSetValue(record, kABGroupNameProperty, (__bridge CFStringRef) aString, &cfError); + if (!success) + { + NSError *error = (__bridge_transfer NSError *) cfError; + NSLog(@"Error: %@", error.localizedFailureReason); + } } @end diff --git a/ABStandin.h b/ABStandin.h new file mode 100755 index 0000000..aefb237 --- /dev/null +++ b/ABStandin.h @@ -0,0 +1,17 @@ +// +// AddressBook.h +// HelloWorld +// +// Created by Erica Sadun on 8/24/11. +// Copyright (c) 2011 Up To No Good, Inc. All rights reserved. +// + +#import +#import +#import + +@interface ABStandin : NSObject ++ (ABAddressBookRef) addressBook; ++ (ABAddressBookRef) currentAddressBook; ++ (BOOL) save: (NSError **) error; +@end diff --git a/ABStandin.m b/ABStandin.m new file mode 100755 index 0000000..2ea3aa1 --- /dev/null +++ b/ABStandin.m @@ -0,0 +1,86 @@ +// +// AddressBook.m +// HelloWorld +// +// Created by Erica Sadun on 8/24/11. +// Copyright (c) 2011 Up To No Good, Inc. All rights reserved. +// + +#import "ABStandin.h" + +static ABAddressBookRef shared = NULL; + +@implementation ABStandin +// Return the current shared address book, +// Creating if needed ++ (ABAddressBookRef) addressBook +{ + @synchronized (self) { + if (!shared) { + if (ABAddressBookCreateWithOptions == NULL) { + shared = ABAddressBookCreate(); + } else { + shared = ABAddressBookCreateWithOptions(NULL, NULL); + } + if (![self hasAddressBookAccess:shared]) { + //TODO: show beautiful alert + shared = NULL; + } + } + } + return shared; +} + +// Load the current address book ++ (ABAddressBookRef) currentAddressBook +{ + if (shared) + { + CFRelease(shared); + shared = nil; + } + + return [self addressBook]; +} + +// Thanks Frederic Bronner +// Save the address book out ++ (BOOL) save: (NSError **) error +{ + CFErrorRef cfError; + if (shared) + { + BOOL success = ABAddressBookSave(shared, &cfError); + if (!success) + { + if (error) + *error = (__bridge_transfer NSError *)cfError; + return NO; + } + return YES; + } + return NO; +} + ++ (BOOL)hasAddressBookAccess:(ABAddressBookRef)addressBook { + if (ABAddressBookRequestAccessWithCompletion == NULL) { + // before iOS 6 + return YES; + } + // iOS 6 and more + __block BOOL accessGranted = NO; + + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { + accessGranted = granted; + if(semaphore) { + dispatch_semaphore_signal(semaphore); + } + }); + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + dispatch_release(semaphore); + semaphore = NULL; + + return accessGranted; +} +@end diff --git a/Default-568h@2x.png b/Default-568h@2x.png new file mode 100644 index 0000000..0891b7a Binary files /dev/null and b/Default-568h@2x.png differ diff --git a/Default-Landscape~ipad.png b/Default-Landscape~ipad.png new file mode 100755 index 0000000..cbccbca Binary files /dev/null and b/Default-Landscape~ipad.png differ diff --git a/Default-Portrait~ipad.png b/Default-Portrait~ipad.png new file mode 100755 index 0000000..c6f34c2 Binary files /dev/null and b/Default-Portrait~ipad.png differ diff --git a/Default.png b/Default.png old mode 100644 new mode 100755 index 1891c8f..7c252e8 Binary files a/Default.png and b/Default.png differ diff --git a/Default@2x.png b/Default@2x.png new file mode 100755 index 0000000..bc08b4b Binary files /dev/null and b/Default@2x.png differ diff --git a/Info.plist b/HelloWorld-Info.plist similarity index 54% rename from Info.plist rename to HelloWorld-Info.plist index 99d04a3..7b5efe7 100755 --- a/Info.plist +++ b/HelloWorld-Info.plist @@ -3,15 +3,21 @@ CFBundleDevelopmentRegion - en + English CFBundleDisplayName ${PRODUCT_NAME} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile - + icon.png + CFBundleIconFiles + + icon-iPad.png + icon@2x.png + icon.png + CFBundleIdentifier - com.sadun.${EXECUTABLE_NAME} + com.sadun.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -22,5 +28,14 @@ ???? CFBundleVersion 1.0 + LSRequiresIPhoneOS + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + diff --git a/HelloWorld.xcodeproj/ericasadun.mode1v3 b/HelloWorld.xcodeproj/ericasadun.mode1v3 new file mode 100755 index 0000000..3e2eef2 --- /dev/null +++ b/HelloWorld.xcodeproj/ericasadun.mode1v3 @@ -0,0 +1,1399 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /Developer32/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1v3 + FavBarConfig + + PBXProjectModuleGUID + 8EA3E1E61128601100889321 + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1v3 + MajorVersion + 33 + MinorVersion + 0 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-combo-popup + action + NSToolbarFlexibleSpaceItem + debugger-enable-breakpoints + build-and-go + com.apple.ide.PBXToolbarStopButton + get-info + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 29B97317FDCFA39411CA2CEA + 8E7D47441128F52000B184C5 + 1C37FBAC04509CD000000102 + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 5 + 4 + 2 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 557}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 575}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 311 160 796 616 0 0 1920 1058 + + Module + PBXSmartGroupTreeModule + Proportion + 203pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + main.m + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + main.m + _historyCapacity + 0 + bookmark + 8EE2C169139AA0F6007E4557 + history + + 8EA3E27C112862FC00889321 + 8E312744113440B00096DE87 + 8E25E54B1390143500962DEF + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {588, 0}} + RubberWindowFrame + 311 160 796 616 0 0 1920 1058 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 5}, {588, 570}} + RubberWindowFrame + 311 160 796 616 0 0 1920 1058 + + Module + XCDetailModule + Proportion + 570pt + + + Proportion + 588pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 8EE2C16A139AA0F6007E4557 + 1CE0B1FE06471DED0097A5F4 + 8EE2C16B139AA0F6007E4557 + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.shortV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/Developer32/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 8EA3E1E71128601100889321 + /Users/ericasadun/Desktop/11-New Edition Sample Code/XX-Base Update/HelloWorld.xcodeproj + + WindowString + 311 160 796 616 0 0 1920 1058 + WindowToolsV3 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {500, 218}} + RubberWindowFrame + 528 408 500 500 0 0 1920 1058 + + Module + PBXNavigatorGroup + Proportion + 218pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build Results + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 223}, {500, 236}} + RubberWindowFrame + 528 408 500 500 0 0 1920 1058 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 459pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 8EA3E1E71128601100889321 + 8EE2C16C139AA0F6007E4557 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowContentMinSize + 486 300 + WindowString + 528 408 500 500 0 0 1920 1058 + WindowToolGUID + 8EA3E1E71128601100889321 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {316, 203}} + {{316, 0}, {378, 203}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 203}} + {{0, 203}, {694, 178}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 381}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 120 + Value + 85 + Summary + 148 + + Frame + {{316, 0}, {378, 203}} + RubberWindowFrame + 131 539 694 422 0 0 1920 1058 + + RubberWindowFrame + 131 539 694 422 0 0 1920 1058 + + Module + PBXDebugSessionModule + Proportion + 381pt + + + Proportion + 381pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + 8E6CE885120A029200A88205 + 1C162984064C10D400B95A72 + 8E6CE886120A029200A88205 + 8E6CE887120A029200A88205 + 8E6CE888120A029200A88205 + 8E6CE889120A029200A88205 + 8E6CE88A120A029200A88205 + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 131 539 694 422 0 0 1920 1058 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + Identifier + windowTool.find + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CD0528D0623707200166675 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {781, 167}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 781pt + + + Proportion + 50% + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{8, 0}, {773, 254}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXProjectFindModule + Proportion + 50% + + + Proportion + 428pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C530D57069F1CE1000CFCEE + 1C530D58069F1CE1000CFCEE + 1C530D59069F1CE1000CFCEE + 1CDD528C0622207200134675 + 1C530D5A069F1CE1000CFCEE + 1CE0B1FE06471DED0097A5F4 + 1CD0528E0623707200166675 + + WindowString + 62 385 781 470 0 0 1440 878 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + 0 + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {650, 209}} + RubberWindowFrame + -755 471 650 250 -1680 30 1680 1050 + + Module + PBXDebugCLIModule + Proportion + 209pt + + + Proportion + 209pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 1C78EAAD065D492600B07095 + 8E6CE88B120A029200A88205 + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + -755 471 650 250 -1680 30 1680 1050 + WindowToolGUID + 1C78EAAD065D492600B07095 + WindowToolIsVisible + + + + Identifier + windowTool.snapshots + Layout + + + Dock + + + Module + XCSnapshotModule + Proportion + 100% + + + Proportion + 100% + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + Yes + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 315 824 300 550 0 0 1440 878 + WindowToolIsVisible + Yes + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.0950012207031 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + Layout + + + Dock + + + BecomeActive + 1 + GeometryConfiguration + + Frame + {0, 0}, {500, 335} + RubberWindowFrame + {0, 0}, {500, 335} + + Module + XCRefactoringModule + Proportion + 100% + + + Proportion + 100% + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + WindowString + 200 200 500 356 0 0 1920 1200 + + + + diff --git a/HelloWorld.xcodeproj/ericasadun.pbxuser b/HelloWorld.xcodeproj/ericasadun.pbxuser new file mode 100755 index 0000000..498157d --- /dev/null +++ b/HelloWorld.xcodeproj/ericasadun.pbxuser @@ -0,0 +1,160 @@ +// !$*UTF8*$! +{ + 1D6058900D05DD3D006BFB54 /* HelloWorld */ = { + activeExec = 0; + executables = ( + 8EA3E1DA1128600900889321 /* HelloWorld */, + ); + }; + 29B97313FDCFA39411CA2CEA /* Project object */ = { + activeBuildConfigurationName = Debug; + activeExecutable = 8EA3E1DA1128600900889321 /* HelloWorld */; + activeSDKPreference = iphoneos3.2; + activeTarget = 1D6058900D05DD3D006BFB54 /* HelloWorld */; + addToTargets = ( + 1D6058900D05DD3D006BFB54 /* HelloWorld */, + ); + codeSenseManager = 8EA3E1EA1128601100889321 /* Code sense */; + executables = ( + 8EA3E1DA1128600900889321 /* HelloWorld */, + ); + perUserDictionary = { + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 349, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 309, + 60, + 20, + 48, + 43, + 43, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXTargetDataSource_PrimaryAttribute, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 328900821; + PBXWorkspaceStateSaveDate = 328900821; + }; + perUserProjectItems = { + 8E25E54B1390143500962DEF /* PBXTextBookmark */ = 8E25E54B1390143500962DEF /* PBXTextBookmark */; + 8E312744113440B00096DE87 /* PBXBookmark */ = 8E312744113440B00096DE87 /* PBXBookmark */; + 8EA3E27C112862FC00889321 /* PBXBookmark */ = 8EA3E27C112862FC00889321 /* PBXBookmark */; + 8EE2C169139AA0F6007E4557 /* PBXTextBookmark */ = 8EE2C169139AA0F6007E4557 /* PBXTextBookmark */; + }; + sourceControlManager = 8EA3E1E91128601100889321 /* Source Control */; + userBuildSettings = { + }; + }; + 29B97316FDCFA39411CA2CEA /* main.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {527, 806}}"; + sepNavSelRange = "{531, 0}"; + sepNavVisRange = "{0, 0}"; + sepNavWindowFrame = "{{515, 160}, {864, 828}}"; + }; + }; + 8E25E54B1390143500962DEF /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 29B97316FDCFA39411CA2CEA /* main.m */; + name = "main.m: 17"; + rLen = 0; + rLoc = 531; + rType = 0; + vrLen = 0; + vrLoc = 0; + }; + 8E312744113440B00096DE87 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 8E7D474A1128F56600B184C5 /* Default-Portrait.png */; + }; + 8EA3E1DA1128600900889321 /* HelloWorld */ = { + isa = PBXExecutable; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + breakpointsEnabled = 0; + configStateDict = { + }; + customDataFormattersEnabled = 1; + dataTipCustomDataFormattersEnabled = 1; + dataTipShowTypeColumn = 1; + dataTipSortType = 0; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = HelloWorld; + savedGlobals = { + }; + showTypeColumn = 0; + sourceDirectories = ( + ); + }; + 8EA3E1E91128601100889321 /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + scmConfiguration = { + repositoryNamesForRoots = { + "" = ""; + }; + }; + }; + 8EA3E1EA1128601100889321 /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + 8EA3E27C112862FC00889321 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 8D1107310486CEB800E47090 /* HelloWorld-Info.plist */; + name = "/Users/ericasadun/Desktop/00iPadSampleCode/HelloWorld-iPad/HelloWorld-Info.plist"; + }; + 8EE2C169139AA0F6007E4557 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 29B97316FDCFA39411CA2CEA /* main.m */; + name = "main.m: 17"; + rLen = 0; + rLoc = 531; + rType = 0; + vrLen = 0; + vrLoc = 0; + }; +} diff --git a/HelloWorld.xcodeproj/project.pbxproj b/HelloWorld.xcodeproj/project.pbxproj index 6d9d80e..a13830e 100755 --- a/HelloWorld.xcodeproj/project.pbxproj +++ b/HelloWorld.xcodeproj/project.pbxproj @@ -3,45 +3,59 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ - 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - 8E3A1F090FAA199F009B0518 /* cover320x416.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E3A1F080FAA199F009B0518 /* cover320x416.png */; }; - 8E4156E90FA4EE0E0006D27C /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E4156E70FA4EE0E0006D27C /* Default.png */; }; - 8E4156EA0FA4EE0E0006D27C /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E4156E80FA4EE0E0006D27C /* icon.png */; }; - 8E6DF3F0103F101E00E12A1D /* ABGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E6DF3EF103F101E00E12A1D /* ABGroup.m */; }; - 8E785FCB0FCDB853006EA81F /* TestBedViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8E785FCA0FCDB853006EA81F /* TestBedViewController.xib */; }; - 8EE3297D103C8A9400FBD34F /* ABContactsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EE3297C103C8A9400FBD34F /* ABContactsHelper.m */; }; - 8EE329C7103C928500FBD34F /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8EE329C5103C928500FBD34F /* AddressBook.framework */; }; - 8EE329C8103C928500FBD34F /* AddressBookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8EE329C6103C928500FBD34F /* AddressBookUI.framework */; }; - 8EE32C92103CE3CD00FBD34F /* ABContact.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EE32C91103CE3CD00FBD34F /* ABContact.m */; }; + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; }; + 84F4AD08171404C4005C1954 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 84F4AD07171404C4005C1954 /* Default-568h@2x.png */; }; + 8E3EA0DB13AB9B7800D6C49B /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E3EA0DA13AB9B7800D6C49B /* Default-Portrait~ipad.png */; }; + 8E3EA0DD13AB9B9400D6C49B /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E3EA0DC13AB9B9400D6C49B /* Default-Landscape~ipad.png */; }; + 8E3EA0DF13AB9BA500D6C49B /* icon-iPad.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E3EA0DE13AB9BA500D6C49B /* icon-iPad.png */; }; + 8E3EA0E113AB9BAC00D6C49B /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E3EA0E013AB9BAC00D6C49B /* Default@2x.png */; }; + 8E3EA0E313AB9BB100D6C49B /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E3EA0E213AB9BB100D6C49B /* Default.png */; }; + 8E3EA0E513AB9BB700D6C49B /* icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E3EA0E413AB9BB700D6C49B /* icon@2x.png */; }; + 8E3EA0E713AB9BBC00D6C49B /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E3EA0E613AB9BBC00D6C49B /* icon.png */; }; + 8E7467AC1406E37600B1B2D7 /* ABContact.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E7467A51406E37600B1B2D7 /* ABContact.m */; }; + 8E7467AD1406E37600B1B2D7 /* ABContactsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E7467A71406E37600B1B2D7 /* ABContactsHelper.m */; }; + 8E7467AE1406E37600B1B2D7 /* ABGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E7467A91406E37600B1B2D7 /* ABGroup.m */; }; + 8E7467AF1406E37600B1B2D7 /* ABStandin.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E7467AB1406E37600B1B2D7 /* ABStandin.m */; }; + 8E7467B11406E39C00B1B2D7 /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E7467B01406E39C00B1B2D7 /* AddressBook.framework */; }; + 8E7467B31406E3A000B1B2D7 /* AddressBookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E7467B21406E3A000B1B2D7 /* AddressBookUI.framework */; }; + 8E7467BF1407E73900B1B2D7 /* ModalAlertDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E7467BE1407E73900B1B2D7 /* ModalAlertDelegate.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 1D6058910D05DD3D006BFB54 /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* HelloWorld_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HelloWorld_Prefix.pch; sourceTree = ""; }; - 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 8E3A1F080FAA199F009B0518 /* cover320x416.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cover320x416.png; sourceTree = ""; }; - 8E4156E70FA4EE0E0006D27C /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; - 8E4156E80FA4EE0E0006D27C /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; - 8E6DF3EE103F101E00E12A1D /* ABGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABGroup.h; sourceTree = ""; }; - 8E6DF3EF103F101E00E12A1D /* ABGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABGroup.m; sourceTree = ""; }; - 8E785FCA0FCDB853006EA81F /* TestBedViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TestBedViewController.xib; sourceTree = ""; }; - 8EE3297B103C8A9400FBD34F /* ABContactsHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABContactsHelper.h; sourceTree = ""; }; - 8EE3297C103C8A9400FBD34F /* ABContactsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABContactsHelper.m; sourceTree = ""; }; - 8EE329C5103C928500FBD34F /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = "../Work/SDKStuff/99BOOK/C09 - PeoplePlacesThings/01a - Finding People/iphoneos2.0/System/Library/Frameworks/AddressBook.framework"; sourceTree = SOURCE_ROOT; }; - 8EE329C6103C928500FBD34F /* AddressBookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBookUI.framework; path = "../Work/SDKStuff/99BOOK/C09 - PeoplePlacesThings/01a - Finding People/iphoneos2.0/System/Library/Frameworks/AddressBookUI.framework"; sourceTree = SOURCE_ROOT; }; - 8EE32C90103CE3CD00FBD34F /* ABContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABContact.h; sourceTree = ""; }; - 8EE32C91103CE3CD00FBD34F /* ABContact.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABContact.m; sourceTree = ""; }; + 84F4AD07171404C4005C1954 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* HelloWorld-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "HelloWorld-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + 8E3EA0DA13AB9B7800D6C49B /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = ""; }; + 8E3EA0DC13AB9B9400D6C49B /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = ""; }; + 8E3EA0DE13AB9BA500D6C49B /* icon-iPad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-iPad.png"; sourceTree = ""; }; + 8E3EA0E013AB9BAC00D6C49B /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; + 8E3EA0E213AB9BB100D6C49B /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 8E3EA0E413AB9BB700D6C49B /* icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon@2x.png"; sourceTree = ""; }; + 8E3EA0E613AB9BBC00D6C49B /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; + 8E7467A41406E37600B1B2D7 /* ABContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABContact.h; sourceTree = ""; }; + 8E7467A51406E37600B1B2D7 /* ABContact.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABContact.m; sourceTree = ""; }; + 8E7467A61406E37600B1B2D7 /* ABContactsHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABContactsHelper.h; sourceTree = ""; }; + 8E7467A71406E37600B1B2D7 /* ABContactsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABContactsHelper.m; sourceTree = ""; }; + 8E7467A81406E37600B1B2D7 /* ABGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABGroup.h; sourceTree = ""; }; + 8E7467A91406E37600B1B2D7 /* ABGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABGroup.m; sourceTree = ""; }; + 8E7467AA1406E37600B1B2D7 /* ABStandin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABStandin.h; sourceTree = ""; }; + 8E7467AB1406E37600B1B2D7 /* ABStandin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ABStandin.m; sourceTree = ""; }; + 8E7467B01406E39C00B1B2D7 /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; }; + 8E7467B21406E3A000B1B2D7 /* AddressBookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBookUI.framework; path = System/Library/Frameworks/AddressBookUI.framework; sourceTree = SDKROOT; }; + 8E7467BD1407E73900B1B2D7 /* ModalAlertDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModalAlertDelegate.h; sourceTree = ""; }; + 8E7467BE1407E73900B1B2D7 /* ModalAlertDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ModalAlertDelegate.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -49,11 +63,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 8E7467B31406E3A000B1B2D7 /* AddressBookUI.framework in Frameworks */, + 8E7467B11406E39C00B1B2D7 /* AddressBook.framework in Frameworks */, 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, - 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, - 8EE329C7103C928500FBD34F /* AddressBook.framework in Frameworks */, - 8EE329C8103C928500FBD34F /* AddressBookUI.framework in Frameworks */, + 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -71,43 +85,75 @@ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( - 8E6DF3EE103F101E00E12A1D /* ABGroup.h */, - 8E6DF3EF103F101E00E12A1D /* ABGroup.m */, - 8EE32C90103CE3CD00FBD34F /* ABContact.h */, - 8EE32C91103CE3CD00FBD34F /* ABContact.m */, + 84F4AD07171404C4005C1954 /* Default-568h@2x.png */, 29B97316FDCFA39411CA2CEA /* main.m */, - 8EE3297B103C8A9400FBD34F /* ABContactsHelper.h */, - 8EE3297C103C8A9400FBD34F /* ABContactsHelper.m */, - 8EB688610FA64AD100489E4B /* Support */, + 8E7467A31406E36300B1B2D7 /* Address Book */, + 8E7467C01407E73D00B1B2D7 /* Utility */, + 29B97317FDCFA39411CA2CEA /* Resources */, 29B97323FDCFA39411CA2CEA /* Frameworks */, 19C28FACFE9D520D11CA2CBB /* Products */, ); name = CustomTemplate; sourceTree = ""; }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 8E3EA0EB13AB9BEE00D6C49B /* Art */, + 32CA4F630368D1EE00C91783 /* HelloWorld_Prefix.pch */, + 8D1107310486CEB800E47090 /* HelloWorld-Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( - 8EE329C5103C928500FBD34F /* AddressBook.framework */, - 8EE329C6103C928500FBD34F /* AddressBookUI.framework */, - 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, - 1D30AB110D05D00D00671497 /* Foundation.framework */, + 8E7467B21406E3A000B1B2D7 /* AddressBookUI.framework */, + 8E7467B01406E39C00B1B2D7 /* AddressBook.framework */, 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765A40DF7441C002DB57D /* CoreGraphics.framework */, ); name = Frameworks; sourceTree = ""; }; - 8EB688610FA64AD100489E4B /* Support */ = { + 8E3EA0EB13AB9BEE00D6C49B /* Art */ = { isa = PBXGroup; children = ( - 8E785FCA0FCDB853006EA81F /* TestBedViewController.xib */, - 8E3A1F080FAA199F009B0518 /* cover320x416.png */, - 32CA4F630368D1EE00C91783 /* HelloWorld_Prefix.pch */, - 8D1107310486CEB800E47090 /* Info.plist */, - 8E4156E80FA4EE0E0006D27C /* icon.png */, - 8E4156E70FA4EE0E0006D27C /* Default.png */, + 8E3EA0E613AB9BBC00D6C49B /* icon.png */, + 8E3EA0E413AB9BB700D6C49B /* icon@2x.png */, + 8E3EA0E213AB9BB100D6C49B /* Default.png */, + 8E3EA0E013AB9BAC00D6C49B /* Default@2x.png */, + 8E3EA0DE13AB9BA500D6C49B /* icon-iPad.png */, + 8E3EA0DC13AB9B9400D6C49B /* Default-Landscape~ipad.png */, + 8E3EA0DA13AB9B7800D6C49B /* Default-Portrait~ipad.png */, ); - name = Support; + name = Art; + sourceTree = ""; + }; + 8E7467A31406E36300B1B2D7 /* Address Book */ = { + isa = PBXGroup; + children = ( + 8E7467A41406E37600B1B2D7 /* ABContact.h */, + 8E7467A51406E37600B1B2D7 /* ABContact.m */, + 8E7467A61406E37600B1B2D7 /* ABContactsHelper.h */, + 8E7467A71406E37600B1B2D7 /* ABContactsHelper.m */, + 8E7467A81406E37600B1B2D7 /* ABGroup.h */, + 8E7467A91406E37600B1B2D7 /* ABGroup.m */, + 8E7467AA1406E37600B1B2D7 /* ABStandin.h */, + 8E7467AB1406E37600B1B2D7 /* ABStandin.m */, + ); + name = "Address Book"; + sourceTree = ""; + }; + 8E7467C01407E73D00B1B2D7 /* Utility */ = { + isa = PBXGroup; + children = ( + 8E7467BD1407E73900B1B2D7 /* ModalAlertDelegate.h */, + 8E7467BE1407E73900B1B2D7 /* ModalAlertDelegate.m */, + ); + name = Utility; sourceTree = ""; }; /* End PBXGroup section */ @@ -135,9 +181,19 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0420; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "HelloWorld" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; projectRoot = ""; @@ -152,10 +208,14 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8E4156E90FA4EE0E0006D27C /* Default.png in Resources */, - 8E4156EA0FA4EE0E0006D27C /* icon.png in Resources */, - 8E3A1F090FAA199F009B0518 /* cover320x416.png in Resources */, - 8E785FCB0FCDB853006EA81F /* TestBedViewController.xib in Resources */, + 8E3EA0DB13AB9B7800D6C49B /* Default-Portrait~ipad.png in Resources */, + 8E3EA0DD13AB9B9400D6C49B /* Default-Landscape~ipad.png in Resources */, + 8E3EA0DF13AB9BA500D6C49B /* icon-iPad.png in Resources */, + 8E3EA0E113AB9BAC00D6C49B /* Default@2x.png in Resources */, + 8E3EA0E313AB9BB100D6C49B /* Default.png in Resources */, + 8E3EA0E513AB9BB700D6C49B /* icon@2x.png in Resources */, + 8E3EA0E713AB9BBC00D6C49B /* icon.png in Resources */, + 84F4AD08171404C4005C1954 /* Default-568h@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -167,9 +227,11 @@ buildActionMask = 2147483647; files = ( 1D60589B0D05DD56006BFB54 /* main.m in Sources */, - 8EE3297D103C8A9400FBD34F /* ABContactsHelper.m in Sources */, - 8EE32C92103CE3CD00FBD34F /* ABContact.m in Sources */, - 8E6DF3F0103F101E00E12A1D /* ABGroup.m in Sources */, + 8E7467AC1406E37600B1B2D7 /* ABContact.m in Sources */, + 8E7467AD1406E37600B1B2D7 /* ABContactsHelper.m in Sources */, + 8E7467AE1406E37600B1B2D7 /* ABGroup.m in Sources */, + 8E7467AF1406E37600B1B2D7 /* ABStandin.m in Sources */, + 8E7467BF1407E73900B1B2D7 /* ModalAlertDelegate.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -179,69 +241,39 @@ 1D6058940D05DD3E006BFB54 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Erica Sadun"; + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_ARC = YES; COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../Work/SDKStuff/99BOOK/C09 - PeoplePlacesThings/01a - Finding People/iphoneos2.0/System/Library/Frameworks\"", - ); GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = HelloWorld_Prefix.pch; - INFOPLIST_FILE = Info.plist; - PREBINDING = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = "HelloWorld-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + LIBRARY_SEARCH_PATHS = "$(inherited)"; + OTHER_CFLAGS = ""; + OTHER_TEST_FLAGS = ""; PRODUCT_NAME = HelloWorld; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 1D6058950D05DD3E006BFB54 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/../Work/SDKStuff/99BOOK/C09 - PeoplePlacesThings/01a - Finding People/iphoneos2.0/System/Library/Frameworks\"", - ); - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = HelloWorld_Prefix.pch; - INFOPLIST_FILE = Info.plist; - PREBINDING = NO; - PRODUCT_NAME = HelloWorld; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - CODE_SIGN_IDENTITY = "Erica Sadun"; - "CODE_SIGN_IDENTITY[sdk=iphonesimulator*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; - PREBINDING = NO; - PRODUCT_NAME = "Oh Hello"; - SDKROOT = iphoneos2.0; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - C01FCF5008A954540054247B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - PREBINDING = NO; - SDKROOT = iphoneos2.0; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -249,19 +281,17 @@ isa = XCConfigurationList; buildConfigurations = ( 1D6058940D05DD3E006BFB54 /* Debug */, - 1D6058950D05DD3E006BFB54 /* Release */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = Debug; }; C01FCF4E08A954540054247B /* Build configuration list for PBXProject "HelloWorld" */ = { isa = XCConfigurationList; buildConfigurations = ( C01FCF4F08A954540054247B /* Debug */, - C01FCF5008A954540054247B /* Release */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ }; diff --git a/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100755 index 0000000..239c826 --- /dev/null +++ b/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,6 @@ + + + + + diff --git a/HelloWorld.xcodeproj/project.xcworkspace/xcuserdata/ericasadun.xcuserdatad/WorkspaceSettings.xcsettings b/HelloWorld.xcodeproj/project.xcworkspace/xcuserdata/ericasadun.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100755 index 0000000..6ff33e6 --- /dev/null +++ b/HelloWorld.xcodeproj/project.xcworkspace/xcuserdata/ericasadun.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,10 @@ + + + + + IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges + + IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges + + + diff --git a/HelloWorld.xcodeproj/project.xcworkspace/xcuserdata/ericasadun.xcuserdatad/WorkspaceState.xcuserstate b/HelloWorld.xcodeproj/project.xcworkspace/xcuserdata/ericasadun.xcuserdatad/WorkspaceState.xcuserstate new file mode 100755 index 0000000..84e9c14 --- /dev/null +++ b/HelloWorld.xcodeproj/project.xcworkspace/xcuserdata/ericasadun.xcuserdatad/WorkspaceState.xcuserstate @@ -0,0 +1,2367 @@ + + + + + $archiver + NSKeyedArchiver + $objects + + $null + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 2 + + + CF$UID + 3 + + + NS.objects + + + CF$UID + 4 + + + CF$UID + 143 + + + + IDEWorkspaceWindowController_0 + IDEWorkspaceDocument + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 5 + + + CF$UID + 6 + + + CF$UID + 7 + + + CF$UID + 8 + + + CF$UID + 9 + + + NS.objects + + + CF$UID + 10 + + + CF$UID + 12 + + + CF$UID + 9 + + + CF$UID + 13 + + + CF$UID + 14 + + + + IDEOrderedWorkspaceTabControllers + IDEUserWantsMiniDebuggingConsole + IDEActiveWorkspaceTabController + IDEWindowFrame + IDEWorkspaceTabController_0 + + $class + + CF$UID + 11 + + NS.objects + + + CF$UID + 9 + + + + + $classes + + NSArray + NSObject + + $classname + NSArray + + 0 + {{-1538, 55}, {1400, 971}} + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 15 + + + CF$UID + 16 + + + CF$UID + 17 + + + CF$UID + 18 + + + CF$UID + 19 + + + CF$UID + 20 + + + CF$UID + 21 + + + NS.objects + + + CF$UID + 22 + + + CF$UID + 93 + + + CF$UID + 94 + + + CF$UID + 100 + + + CF$UID + 133 + + + CF$UID + 93 + + + CF$UID + 142 + + + + IDEEditorArea + IDEShowNavigator + IDEWorkspaceTabControllerUtilityAreaSplitView + IDENavigatorArea + IDEWorkspaceTabControllerDesignAreaSplitView + IDEShowUtilities + IDETabLabel + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 23 + + + CF$UID + 24 + + + CF$UID + 25 + + + CF$UID + 26 + + + CF$UID + 27 + + + NS.objects + + + CF$UID + 28 + + + CF$UID + 78 + + + CF$UID + 83 + + + CF$UID + 12 + + + CF$UID + 12 + + + + IDEEditorMode_Standard + IDEEditorMode_Version + IDEEditorMode_Genius + ShowDebuggerArea + EditorMode + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 29 + + + NS.objects + + + CF$UID + 30 + + + + EditorStates + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 29 + + + CF$UID + 31 + + + NS.objects + + + CF$UID + 32 + + + CF$UID + 12 + + + + SelectedEditorState + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 33 + + + + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 34 + + + CF$UID + 35 + + + CF$UID + 36 + + + CF$UID + 37 + + + CF$UID + 38 + + + CF$UID + 39 + + + NS.objects + + + CF$UID + 40 + + + CF$UID + 66 + + + CF$UID + 72 + + + CF$UID + 75 + + + CF$UID + 76 + + + CF$UID + 77 + + + + EditorState + ArchivableRepresentation + DocumentURL + FileDataType + DocumentExtensionIdentifier + HistoryMenuDescription + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 41 + + + CF$UID + 42 + + + NS.objects + + + CF$UID + 43 + + + CF$UID + 54 + + + + SelectedDocumentLocations + Xcode3ProjectEditor.sourceList.splitview + + $class + + CF$UID + 11 + + NS.objects + + + CF$UID + 44 + + + + + $class + + CF$UID + 53 + + documentURL + + CF$UID + 45 + + selection + + CF$UID + 47 + + timestamp + + CF$UID + 46 + + + file://localhost/Users/ericasadun/Desktop/11-New%20Edition%20Sample%20Code/XX-Base%20Update/HelloWorld.xcodeproj/ + 299698066.86137003 + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 48 + + + CF$UID + 49 + + + NS.objects + + + CF$UID + 50 + + + CF$UID + 51 + + + + Project + Editor + HelloWorld + Xcode3ProjectInfoEditor + + $classes + + NSMutableDictionary + NSDictionary + NSObject + + $classname + NSMutableDictionary + + + $classes + + Xcode3ProjectDocumentLocation + DVTDocumentLocation + NSObject + + $classname + Xcode3ProjectDocumentLocation + + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 55 + + + NS.objects + + + CF$UID + 56 + + + + DVTSplitViewItems + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 57 + + + CF$UID + 63 + + + + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 58 + + + CF$UID + 59 + + + NS.objects + + + CF$UID + 60 + + + CF$UID + 61 + + + + DVTIdentifier + DVTViewMagnitude + + 170 + + $classes + + NSDictionary + NSObject + + $classname + NSDictionary + + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 58 + + + CF$UID + 59 + + + NS.objects + + + CF$UID + 60 + + + CF$UID + 64 + + + + 710 + + $classes + + NSMutableArray + NSArray + NSObject + + $classname + NSMutableArray + + + $class + + CF$UID + 71 + + DocumentLocation + + CF$UID + 70 + + DomainIdentifier + + CF$UID + 67 + + IdentifierPath + + CF$UID + 68 + + + Xcode.IDENavigableItemDomain.WorkspaceStructure + + $class + + CF$UID + 11 + + NS.objects + + + CF$UID + 69 + + + + HelloWorld + $null + + $classes + + IDENavigableItemArchivableRepresentation + NSObject + + $classname + IDENavigableItemArchivableRepresentation + + + $class + + CF$UID + 74 + + NS.base + + CF$UID + 0 + + NS.relative + + CF$UID + 73 + + + file://localhost/Users/ericasadun/Desktop/11-New%20Edition%20Sample%20Code/XX-Base%20Update/HelloWorld.xcodeproj/ + + $classes + + NSURL + NSObject + + $classname + NSURL + + com.apple.xcode.project + Xcode.Xcode3ProjectSupport.EditorDocument.Xcode3Project + HelloWorld + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 29 + + + CF$UID + 79 + + + NS.objects + + + CF$UID + 80 + + + CF$UID + 12 + + + + VersionsEditorSubmode + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 29 + + + CF$UID + 31 + + + NS.objects + + + CF$UID + 81 + + + CF$UID + 12 + + + + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 82 + + + + + $class + + CF$UID + 52 + + NS.keys + + NS.objects + + + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 84 + + + CF$UID + 85 + + + CF$UID + 29 + + + NS.objects + + + CF$UID + 12 + + + CF$UID + 86 + + + CF$UID + 90 + + + + ManualMode + GeniusLayout + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 29 + + + NS.objects + + + CF$UID + 87 + + + + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 29 + + + CF$UID + 31 + + + NS.objects + + + CF$UID + 88 + + + CF$UID + 12 + + + + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 89 + + + + + $class + + CF$UID + 52 + + NS.keys + + NS.objects + + + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 29 + + + CF$UID + 31 + + + NS.objects + + + CF$UID + 91 + + + CF$UID + 12 + + + + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 92 + + + + + $class + + CF$UID + 52 + + NS.keys + + NS.objects + + + 1 + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 55 + + + NS.objects + + + CF$UID + 95 + + + + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 96 + + + CF$UID + 98 + + + + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 58 + + + CF$UID + 59 + + + NS.objects + + + CF$UID + 60 + + + CF$UID + 97 + + + + 661 + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 58 + + + CF$UID + 59 + + + NS.objects + + + CF$UID + 60 + + + CF$UID + 99 + + + + 215 + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 101 + + + CF$UID + 102 + + + CF$UID + 103 + + + NS.objects + + + CF$UID + 104 + + + CF$UID + 103 + + + CF$UID + 120 + + + + Xcode.IDEKit.Navigator.Issues + SelectedNavigator + Xcode.IDEKit.Navigator.Structure + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 105 + + + CF$UID + 106 + + + CF$UID + 107 + + + CF$UID + 108 + + + CF$UID + 109 + + + CF$UID + 110 + + + CF$UID + 111 + + + CF$UID + 112 + + + NS.objects + + + CF$UID + 12 + + + CF$UID + 113 + + + CF$UID + 114 + + + CF$UID + 116 + + + CF$UID + 12 + + + CF$UID + 117 + + + CF$UID + 118 + + + CF$UID + 119 + + + + IDEErrorFilteringEnabled + IDEVisibleRect + IDECollapsedFiles + IDEExpandedIssues + IDEShowsByType + IDESelectedNavigables + IDECollapsedTypes + IDECollapsedGroups + {{0, 0}, {259, 810}} + + $class + + CF$UID + 115 + + NS.objects + + + + $classes + + NSMutableSet + NSSet + NSObject + + $classname + NSMutableSet + + + $class + + CF$UID + 115 + + NS.objects + + + + $class + + CF$UID + 115 + + NS.objects + + + + $class + + CF$UID + 115 + + NS.objects + + + + $class + + CF$UID + 115 + + NS.objects + + + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 121 + + + CF$UID + 122 + + + CF$UID + 123 + + + CF$UID + 124 + + + CF$UID + 125 + + + CF$UID + 126 + + + NS.objects + + + CF$UID + 12 + + + CF$UID + 127 + + + CF$UID + 130 + + + CF$UID + 12 + + + CF$UID + 132 + + + CF$UID + 12 + + + + IDEUnsavedDocumentFilteringEnabled + IDESelectedObjects + IDEExpandedItems + IDESCMStatusFilteringEnabled + IDEVisibleRect + IDERecentDocumentFilteringEnabled + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 128 + + + + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 129 + + + + HelloWorld + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 131 + + + + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 129 + + + + {{0, 0}, {259, 832}} + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 55 + + + NS.objects + + + CF$UID + 134 + + + + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 135 + + + CF$UID + 137 + + + CF$UID + 139 + + + + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 58 + + + CF$UID + 59 + + + NS.objects + + + CF$UID + 18 + + + CF$UID + 136 + + + + 260 + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 58 + + + CF$UID + 59 + + + NS.objects + + + CF$UID + 15 + + + CF$UID + 138 + + + + 880 + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 58 + + + CF$UID + 59 + + + NS.objects + + + CF$UID + 140 + + + CF$UID + 141 + + + + IDEUtilitiesArea + 260 + HelloWorld.xcodeproj + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 144 + + + CF$UID + 145 + + + CF$UID + 146 + + + CF$UID + 147 + + + CF$UID + 148 + + + CF$UID + 149 + + + CF$UID + 150 + + + CF$UID + 151 + + + NS.objects + + + CF$UID + 12 + + + CF$UID + 152 + + + CF$UID + 201 + + + CF$UID + 204 + + + CF$UID + 209 + + + CF$UID + 210 + + + CF$UID + 12 + + + CF$UID + 12 + + + + BreakpointsActivated + DefaultEditorStatesForURLs + ActiveScheme + ActiveRunDestination + DocumentWindows + RecentEditorDocumentURLs + AppFocusInMiniDebugging + DebuggingWindowsLayerMode + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 153 + + + CF$UID + 154 + + + CF$UID + 76 + + + NS.objects + + + CF$UID + 155 + + + CF$UID + 161 + + + CF$UID + 172 + + + + Xcode.IDEKit.CocoaTouchIntegration.EditorDocument.CocoaTouch + Xcode.IDEKit.EditorDocument.SourceCode + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 156 + + + NS.objects + + + CF$UID + 159 + + + + + $class + + CF$UID + 74 + + NS.base + + CF$UID + 0 + + NS.relative + + CF$UID + 157 + + + + $class + + CF$UID + 158 + + NS.string + file://localhost/Users/ericasadun/Desktop/11-New%20Edition%20Sample%20Code/XX-Base%20Update/TestBed%20Support/TestBedViewController.xib + + + $classes + + NSMutableString + NSString + NSObject + + $classname + NSMutableString + + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 41 + + + NS.objects + + + CF$UID + 160 + + + + + $class + + CF$UID + 65 + + NS.objects + + + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 162 + + + NS.objects + + + CF$UID + 164 + + + + + $class + + CF$UID + 74 + + NS.base + + CF$UID + 0 + + NS.relative + + CF$UID + 163 + + + + $class + + CF$UID + 158 + + NS.string + file://localhost/Users/ericasadun/Desktop/11-New%20Edition%20Sample%20Code/XX-Base%20Update/main.m + + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 41 + + + CF$UID + 165 + + + NS.objects + + + CF$UID + 166 + + + CF$UID + 171 + + + + VisibleCharacterRange + + $class + + CF$UID + 11 + + NS.objects + + + CF$UID + 167 + + + + + $class + + CF$UID + 170 + + characterRangeLen + 0 + characterRangeLoc + 0 + documentURL + + CF$UID + 168 + + endingColumnNumber + -1 + endingLineNumber + -1 + startingColumnNumber + -1 + startingLineNumber + -1 + timestamp + + CF$UID + 169 + + + file://localhost/Users/ericasadun/Desktop/11-New%20Edition%20Sample%20Code/XX-Base%20Update/main.m + 299697687.83317697 + + $classes + + DVTTextDocumentLocation + DVTDocumentLocation + NSObject + + $classname + DVTTextDocumentLocation + + {0, 1680} + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 173 + + + NS.objects + + + CF$UID + 175 + + + + + $class + + CF$UID + 74 + + NS.base + + CF$UID + 0 + + NS.relative + + CF$UID + 174 + + + + $class + + CF$UID + 158 + + NS.string + file://localhost/Users/ericasadun/Desktop/11-New%20Edition%20Sample%20Code/XX-Base%20Update/HelloWorld.xcodeproj/ + + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 41 + + + CF$UID + 42 + + + NS.objects + + + CF$UID + 176 + + + CF$UID + 195 + + + + + $class + + CF$UID + 11 + + NS.objects + + + CF$UID + 177 + + + + + $class + + CF$UID + 53 + + documentURL + + CF$UID + 178 + + selection + + CF$UID + 180 + + timestamp + + CF$UID + 179 + + + file://localhost/Users/ericasadun/Desktop/11-New%20Edition%20Sample%20Code/XX-Base%20Update/HelloWorld.xcodeproj/ + 299697731.45488501 + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 48 + + + CF$UID + 49 + + + CF$UID + 181 + + + NS.objects + + + CF$UID + 182 + + + CF$UID + 183 + + + CF$UID + 184 + + + + Xcode3BuildSettingsEditorLocations + HelloWorld + Xcode3BuildSettingsEditor + + $class + + CF$UID + 11 + + NS.objects + + + CF$UID + 185 + + + + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 186 + + + CF$UID + 187 + + + CF$UID + 188 + + + CF$UID + 189 + + + CF$UID + 190 + + + CF$UID + 191 + + + NS.objects + + + CF$UID + 192 + + + CF$UID + 193 + + + CF$UID + 93 + + + CF$UID + 12 + + + CF$UID + 93 + + + CF$UID + 93 + + + + Collapsed Build Property Categories + Selected Build Properties + Xcode3BuildSettingsEditorDisplayMode + Xcode3BuildPropertyValueDisplayMode + Xcode3BuildSettingsEditorMode + Xcode3BuildPropertyNameDisplayMode + + $class + + CF$UID + 65 + + NS.objects + + + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 194 + + + + + $class + + CF$UID + 158 + + NS.string + Deployment||TARGETED_DEVICE_FAMILY + + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 55 + + + NS.objects + + + CF$UID + 196 + + + + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 197 + + + CF$UID + 199 + + + + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 58 + + + CF$UID + 59 + + + NS.objects + + + CF$UID + 60 + + + CF$UID + 198 + + + + 162 + + $class + + CF$UID + 62 + + NS.keys + + + CF$UID + 58 + + + CF$UID + 59 + + + NS.objects + + + CF$UID + 60 + + + CF$UID + 200 + + + + 978 + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 202 + + + NS.objects + + + CF$UID + 203 + + + + IDENameString + HelloWorld + + $class + + CF$UID + 52 + + NS.keys + + + CF$UID + 205 + + + CF$UID + 206 + + + NS.objects + + + CF$UID + 207 + + + CF$UID + 208 + + + + IDEDeviceLocation + IDEDeviceArchitecture + dvtdevice-iphonesimulator:/Xcode4/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.2.sdk-iPad + i386 + + $class + + CF$UID + 65 + + NS.objects + + + + $class + + CF$UID + 65 + + NS.objects + + + CF$UID + 211 + + + CF$UID + 212 + + + CF$UID + 214 + + + + + $class + + CF$UID + 74 + + NS.base + + CF$UID + 0 + + NS.relative + + CF$UID + 45 + + + + $class + + CF$UID + 74 + + NS.base + + CF$UID + 0 + + NS.relative + + CF$UID + 213 + + + file://localhost/Users/ericasadun/Desktop/11-New%20Edition%20Sample%20Code/XX-Base%20Update/TestBed%20Support/TestBedViewController.xib + + $class + + CF$UID + 74 + + NS.base + + CF$UID + 0 + + NS.relative + + CF$UID + 168 + + + + $top + + State + + CF$UID + 1 + + + $version + 100000 + + diff --git a/HelloWorld.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/HelloWorld.xcscheme b/HelloWorld.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/HelloWorld.xcscheme new file mode 100644 index 0000000..4fa5aa9 --- /dev/null +++ b/HelloWorld.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/HelloWorld.xcscheme @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/HelloWorld.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/xcschememanagement.plist b/HelloWorld.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..02a22b4 --- /dev/null +++ b/HelloWorld.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + HelloWorld.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 1D6058900D05DD3D006BFB54 + + primary + + + + + diff --git a/HelloWorld.xcodeproj/xcuserdata/ericasadun.xcuserdatad/xcschemes/HelloWorld.xcscheme b/HelloWorld.xcodeproj/xcuserdata/ericasadun.xcuserdatad/xcschemes/HelloWorld.xcscheme new file mode 100755 index 0000000..f2fbe3d --- /dev/null +++ b/HelloWorld.xcodeproj/xcuserdata/ericasadun.xcuserdatad/xcschemes/HelloWorld.xcscheme @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/HelloWorld.xcodeproj/xcuserdata/ericasadun.xcuserdatad/xcschemes/xcschememanagement.plist b/HelloWorld.xcodeproj/xcuserdata/ericasadun.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100755 index 0000000..ce06a4c --- /dev/null +++ b/HelloWorld.xcodeproj/xcuserdata/ericasadun.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,19 @@ + + + + + SchemeUserState + + HelloWorld.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + HelloWorld.app + + + + diff --git a/ModalAlertDelegate.h b/ModalAlertDelegate.h new file mode 100755 index 0000000..45ce6d8 --- /dev/null +++ b/ModalAlertDelegate.h @@ -0,0 +1,16 @@ +/* + Erica Sadun, http://ericasadun.com + iPhone Developer's Cookbook, 5.x Edition + BSD License, Use at your own risk + */ + +#import + +@interface ModalAlertDelegate : NSObject +{ + UIAlertView *alertView; + int index; +} ++ (id) delegateWithAlert: (UIAlertView *) anAlert; +- (int) show; +@end diff --git a/ModalAlertDelegate.m b/ModalAlertDelegate.m new file mode 100755 index 0000000..e1aa680 --- /dev/null +++ b/ModalAlertDelegate.m @@ -0,0 +1,40 @@ +/* + Erica Sadun, http://ericasadun.com + iPhone Developer's Cookbook, 5.x Edition + BSD License, Use at your own risk + */ + +#import "ModalAlertDelegate.h" + +@implementation ModalAlertDelegate + +- (id)initWithAlert: (UIAlertView *) anAlert +{ + if (!(self = [super init])) return self; + alertView = anAlert; + return self; +} + +-(void)alertView:(UIAlertView*)aView clickedButtonAtIndex:(NSInteger)anIndex +{ + index = anIndex; + alertView = nil; + CFRunLoopStop(CFRunLoopGetCurrent()); +} + +- (int) show +{ + [alertView setDelegate:self]; + [alertView show]; + + CFRunLoopRun(); + + return index; +} + ++ (id) delegateWithAlert: (UIAlertView *) anAlert +{ + ModalAlertDelegate *mad = [[self alloc] initWithAlert:anAlert]; + return mad; +} +@end diff --git a/TestBedViewController.xib b/TestBedViewController.xib deleted file mode 100644 index 79a82ff..0000000 --- a/TestBedViewController.xib +++ /dev/null @@ -1,223 +0,0 @@ - - - - 768 - 9J61 - 680 - 949.46 - 353.00 - - YES - - - - YES - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - YES - - YES - - - YES - - - - YES - - IBFilesOwner - - - IBFirstResponder - - - - 292 - - YES - - - 256 - {320, 416} - - NO - YES - 4 - YES - - NSImage - cover320x416.png - - - - - 292 - {320, 279} - - NO - YES - YES - NO - NO - NO - NO - NO - - - 2 - - - - {320, 416} - - - 3 - MQA - - 2 - - - NO - - - NO - - - - - - YES - - - view - - - - 33 - - - - textView - - - - 36 - - - - - YES - - 0 - - YES - - - - - - -1 - - - RmlsZSdzIE93bmVyA - - - -2 - - - - - 32 - - - YES - - - - - - - 34 - - - - - 35 - - - - - - - YES - - YES - -1.CustomClassName - -2.CustomClassName - 32.IBEditorWindowLastContentRect - 32.IBPluginDependency - 35.IBPluginDependency - - - YES - TestBedViewController - UIResponder - {{21, 492}, {320, 480}} - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - YES - - YES - - - YES - - - - - YES - - YES - - - YES - - - - 36 - - - - YES - - TestBedViewController - - YES - - YES - textView - view - - - YES - UITextView - UIView - - - - IBUserSource - - - - - - 0 - HelloWorld.xcodeproj - 3 - 3.1 - - diff --git a/cover320x416.png b/cover320x416.png deleted file mode 100644 index 8683b68..0000000 Binary files a/cover320x416.png and /dev/null differ diff --git a/icon-iPad.png b/icon-iPad.png new file mode 100755 index 0000000..a60bbc6 Binary files /dev/null and b/icon-iPad.png differ diff --git a/icon.png b/icon.png old mode 100644 new mode 100755 diff --git a/icon@2x.png b/icon@2x.png new file mode 100755 index 0000000..1e27976 Binary files /dev/null and b/icon@2x.png differ diff --git a/main.m b/main.m index 4c4ca55..9e4b890 100755 --- a/main.m +++ b/main.m @@ -1,237 +1,166 @@ /* Erica Sadun, http://ericasadun.com - iPhone Developer's Cookbook, 3.0 Edition + iPhone Developer's Cookbook, 5.x Edition BSD License, Use at your own risk */ #import +#import +#import +#import "ABContact.h" #import "ABContactsHelper.h" +#import "ABStandin.h" +#import "ModalAlertDelegate.h" -#define COOKBOOK_PURPLE_COLOR [UIColor colorWithRed:0.20392f green:0.19607f blue:0.61176f alpha:1.0f] -#define BARBUTTON(TITLE, SELECTOR) [[[UIBarButtonItem alloc] initWithTitle:TITLE style:UIBarButtonItemStylePlain target:self action:SELECTOR] autorelease] +#define COOKBOOK_PURPLE_COLOR [UIColor colorWithRed:0.20392f green:0.19607f blue:0.61176f alpha:1.0f] +#define BARBUTTON(TITLE, SELECTOR) [[UIBarButtonItem alloc] initWithTitle:TITLE style:UIBarButtonItemStylePlain target:self action:SELECTOR] +#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) -@interface TestBedViewController : UIViewController -{ - NSMutableString *log; - IBOutlet UITextView *textView; -} -@property (retain) NSMutableString *log; +@interface TestBedViewController : UITableViewController +@property (strong, nonatomic) NSArray *contacts; @end @implementation TestBedViewController -@synthesize log; -- (void) doLog: (NSString *) formatstring, ... +- (void)viewDidLoad { + [super viewDidLoad]; + _contacts = [ABContactsHelper contacts]; +} + +#pragma mark - UITableViewDataSource +- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return _contacts.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ABContactCell"]; + cell.textLabel.text = [_contacts[indexPath.row] compositeName]; + return cell; +} + +- (BOOL) ask: (NSString *) aQuestion { - va_list arglist; - if (!formatstring) return; - va_start(arglist, formatstring); - NSString *outstring = [[[NSString alloc] initWithFormat:formatstring arguments:arglist] autorelease]; - va_end(arglist); - [self.log appendString:outstring]; - [self.log appendString:@"\n"]; - textView.text = self.log; + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:aQuestion message:nil delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"Okay", nil]; + ModalAlertDelegate *delegate = [ModalAlertDelegate delegateWithAlert:alertView]; + int response = [delegate show]; + return response; } -- (void) addGW + +#pragma mark NEW PERSON DELEGATE METHODS +- (void)newPersonViewController:(ABNewPersonViewController *)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person { - // Search for a contact, creating a new one if one is not found - NSArray *contacts = [ABContactsHelper contactsMatchingName:@"Washington" andName:@"George"]; - printf("%d matching contacts found\n", contacts.count); - ABContact *peep = contacts.count ? [contacts lastObject] : [ABContact contact]; - - if (contacts.count) + if (person) { - NSError *error; - if (![peep removeSelfFromAddressBook:&error]) // remove in preparation to update contact - { - NSLog(@"Error: %@", [error localizedDescription]); - return; + ABContact *contact = [ABContact contactWithRecord:person]; + self.title = [NSString stringWithFormat:@"Added %@", contact.compositeName]; + + NSError *error; + BOOL success = [ABContactsHelper addContact:contact withError:&error]; + if (!success) + { + NSLog(@"Could not add contact. %@", error.localizedFailureReason); + self.title = @"Error."; } - + + [ABStandin save:nil]; } - - printf("Record %d\n", peep.recordID); - - // Person basic string information (see full list in ABContact) - peep.firstname = @"George"; - peep.lastname = @"Washington"; - peep.nickname = @"Prez"; - peep.firstnamephonetic = @"Horhay"; - peep.lastnamephonetic = @"Warsh-ing-town"; - peep.jobtitle = @"President of the United States of America"; - - // Emails - NSMutableArray *emailarray = [NSMutableArray array]; - [emailarray addObject:[ABContact dictionaryWithValue:@"george@home.com" andLabel:kABHomeLabel]]; - [emailarray addObject:[ABContact dictionaryWithValue:@"george@work.com" andLabel:kABWorkLabel]]; - [emailarray addObject:[ABContact dictionaryWithValue:@"george@gmail.com" andLabel:(CFStringRef) @"Google"]]; - peep.emailDictionaries = emailarray; - - // Phones - NSMutableArray *phonearray = [NSMutableArray array]; - [phonearray addObject:[ABContact dictionaryWithValue:@"202-555-1212" andLabel:kABPersonPhoneMainLabel]]; - [phonearray addObject:[ABContact dictionaryWithValue:@"202-555-1313" andLabel:(CFStringRef) @"Google"]]; - [phonearray addObject:[ABContact dictionaryWithValue:@"202-555-1414" andLabel:kABPersonPhoneMobileLabel]]; - peep.phoneDictionaries = phonearray; - - // URLS - NSMutableArray *urls = [NSMutableArray array]; - [urls addObject:[ABContact dictionaryWithValue:@"http://whitehouse.org" andLabel:kABPersonHomePageLabel]]; - [urls addObject:[ABContact dictionaryWithValue:@"http://en.wikipedia.org/wiki/Washington" andLabel:kABOtherLabel]]; - peep.urlDictionaries = urls; - - // Dates - NSMutableArray *dates = [NSMutableArray array]; - [dates addObject:[ABContact dictionaryWithValue:[NSDate dateWithTimeIntervalSinceNow:0] andLabel:(CFStringRef) @"Anniversary"]]; - peep.dateDictionaries = dates; - - // Addresses - NSMutableArray *addies = [NSMutableArray array]; - NSDictionary *whaddy = [ABContact addressWithStreet:@"1600 Pennsylvania Avenue" withCity:@"Arlington" withState:@"Virginia" withZip:@"20202" withCountry:nil withCode:nil]; - [addies addObject:[ABContact dictionaryWithValue:whaddy andLabel:kABWorkLabel]]; - NSDictionary *bpaddy = [ABContact addressWithStreet:@"1 Main Street" withCity:@"Westmoreland" withState:@"Virginia" withZip:@"20333" withCountry:nil withCode:nil]; - [addies addObject:[ABContact dictionaryWithValue:bpaddy andLabel:kABHomeLabel]]; - peep.addressDictionaries = addies; - - // SMSes - NSDictionary *sms = [ABContact smsWithService:kABPersonInstantMessageServiceAIM andUser:@"geow1735"]; - NSMutableArray *smses = [NSMutableArray array]; - [smses addObject:[ABContact dictionaryWithValue:sms andLabel:kABWorkLabel]]; - peep.smsDictionaries = smses; - - // Relationships (Not actually used on the iPhone, but here for the sake of example) - NSMutableArray *relatedarray = [NSMutableArray array]; - [relatedarray addObject:[ABContact dictionaryWithValue:@"Mary Ball Washington" andLabel:kABPersonMotherLabel]]; - [relatedarray addObject:[ABContact dictionaryWithValue:@"Augustine Washington" andLabel:kABPersonFatherLabel]]; - peep.relatedNameDictionaries = relatedarray; - - NSError *error; - if (![ABContactsHelper addContact:peep withError:&error]) // save to address book - NSLog(@"Error: %@", [error localizedDescription]); + else + self.title = @"Cancelled"; + + [self.navigationController popViewControllerAnimated:YES]; } -- (void) scan +#pragma mark PEOPLE PICKER DELEGATE METHODS +- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person { - // Regular data dump - for (ABContact *person in [ABContactsHelper contacts]) - { - printf("******\n"); - printf("Name: %s\n", person.compositeName.UTF8String); - printf("Organization: %s\n", person.organization.UTF8String); - printf("Title: %s\n", person.jobtitle.UTF8String); - printf("Department: %s\n", person.department.UTF8String); - printf("Note: %s\n", person.note.UTF8String); - printf("Creation Date: %s\n", [person.creationDate description].UTF8String); - printf("Modification Date: %s\n", [person.modificationDate description].UTF8String); - printf("Emails: %s\n", [person.emailDictionaries description].UTF8String); - printf("Phones: %s\n", [person.phoneDictionaries description].UTF8String); - printf("URLs: %s\n", [person.urlDictionaries description].UTF8String); - printf("Addresses: %s\n\n", [person.addressDictionaries description].UTF8String); - } - - // Example for matching phone numbers - for (ABContact *person in [ABContactsHelper contactsMatchingPhone:@"303"]) - { - printf("******\n"); - printf("Name: %s\n", person.compositeName.UTF8String); - printf("Phones: %s\n", person.phonenumbers.UTF8String); - } - - // Example for matching names - for (ABContact *person in [ABContactsHelper contactsMatchingName:@"Jo"]) + [self dismissModalViewControllerAnimated:YES]; + ABContact *contact = [ABContact contactWithRecord:person]; + + NSString *query = [NSString stringWithFormat:@"Really delete %@?", contact.compositeName]; + if ([self ask:query]) { - printf("******\n"); - printf("Name: %s\n", person.contactName.UTF8String); + self.title = [NSString stringWithFormat:@"Deleted %@", contact.compositeName]; + [contact removeSelfFromAddressBook:nil]; + [ABStandin save:nil]; } + + return NO; } -- (void) viewgroups +- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier { - printf("There are %d groups\n", [ABContactsHelper numberOfGroups]); - for (ABGroup *group in [ABContactsHelper groups]) - { - printf("Name: %s\n", group.name.UTF8String); - NSArray *members = group.members; - printf("Members: %d\n", members.count); - - int n = 1; - for (ABContact *contact in members) - printf("%d: %s\n", n++, contact.compositeName.UTF8String); - } + // required method that is never called in the people-only-picking + [self dismissModalViewControllerAnimated:YES]; + return NO; } -- (void) addGroup +- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker { - NSArray *groups = [ABContactsHelper groupsMatchingName:@"Everyone"]; - printf("%d matching groups found\n", groups.count); - ABGroup *group = groups.count ? [groups lastObject] : [ABGroup group]; - - // Remove existing group to allow modification - if (groups.count) [group removeSelfFromAddressBook:nil]; - - // set name - group.name = @"Everyone"; - - // add members - NSArray *contacts = [ABContactsHelper contacts]; - for (ABContact *contact in contacts) - [group addMember:contact withError:nil]; - - // Save the new or modified group - [ABContactsHelper addGroup:group withError:nil]; + [self dismissModalViewControllerAnimated:YES]; } -- (void) serialize +- (void) add { - NSArray *contacts = [ABContactsHelper contactsMatchingName:@"Washington" andName:@"George"]; - printf("%d matching contacts found\n", contacts.count); - ABContact *peep = contacts.count ? [contacts lastObject] : [ABContact contact]; - if (!peep) return; + // create a new view controller + ABNewPersonViewController *npvc = [[ABNewPersonViewController alloc] init]; - NSDictionary *dict = [peep dictionaryRepresentation]; - CFShow(dict); + // Create a new contact + ABContact *contact = [ABContact contact]; + npvc.displayedPerson = contact.record; - NSData *data = [peep dataRepresentation]; - printf("%d bytes\n", data.length); + // Set delegate + npvc.newPersonViewDelegate = self; - ABContact *contact = [ABContact contactWithData:data]; - CFShow([contact dictionaryRepresentation]); + [self.navigationController pushViewController:npvc animated:YES]; } -- (void) viewDidLoad +- (void) remove { - self.navigationController.navigationBar.tintColor = COOKBOOK_PURPLE_COLOR; - - // BASIC TEST - // self.navigationItem.rightBarButtonItem = BARBUTTON(@"Add GW", @selector(addGW)); - // self.navigationItem.leftBarButtonItem = BARBUTTON(@"Scan", @selector(scan)); + ABPeoplePickerNavigationController *ppnc = [[ABPeoplePickerNavigationController alloc] init]; + ppnc.peoplePickerDelegate = self; + [self presentModalViewController:ppnc animated:YES]; +} - // GROUPS TEST - // self.navigationItem.rightBarButtonItem = BARBUTTON(@"Groups", @selector(viewgroups)); - // self.navigationItem.leftBarButtonItem = BARBUTTON(@"Add", @selector(addGroup)); - - // SERIALIZATION TEST - self.navigationItem.rightBarButtonItem = BARBUTTON(@"Serialize", @selector(serialize)); +- (void) loadView +{ + [super loadView]; + self.view.backgroundColor = [UIColor whiteColor]; + self.navigationItem.rightBarButtonItem = BARBUTTON(@"Add", @selector(add)); + self.navigationItem.leftBarButtonItem = BARBUTTON(@"Remove", @selector(remove)); +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return YES; } @end +#pragma mark - + +#pragma mark Application Setup @interface TestBedAppDelegate : NSObject +{ + UIWindow *window; +} @end - @implementation TestBedAppDelegate -- (void)applicationDidFinishLaunching:(UIApplication *)application { - UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[TestBedViewController alloc] init]]; - [window addSubview:nav.view]; - [window makeKeyAndVisible]; +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + [application setStatusBarHidden:YES]; + [[UINavigationBar appearance] setTintColor:COOKBOOK_PURPLE_COLOR]; + + window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + TestBedViewController *tbvc = [[TestBedViewController alloc] init]; + UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:tbvc]; + window.rootViewController = nav; + [window makeKeyAndVisible]; + return YES; } @end - -int main(int argc, char *argv[]) -{ - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - int retVal = UIApplicationMain(argc, argv, nil, @"TestBedAppDelegate"); - [pool release]; - return retVal; -} +int main(int argc, char *argv[]) { + @autoreleasepool { + int retVal = UIApplicationMain(argc, argv, nil, @"TestBedAppDelegate"); + return retVal; + } +} \ No newline at end of file