24

So I'm stumped on this one.

In Mac OS X there is an easy way to get the "Me" card (the owner of the Mac/account) from the built-in address book API.

Has anyone found a way to find out which contact (if it exists) belongs to the owner of the iPhone?

Jesse Rusak
  • 56,530
  • 12
  • 101
  • 102
amattn
  • 10,045
  • 1
  • 36
  • 33

5 Answers5

5

You could use the undocumented user default:

[[NSUserDefaults standardUserDefaults] objectForKey:@"SBFormattedPhoneNumber"];

and then search the address book for the card with that phone number.

Keep in mind that since the User Default is undocumented, Apple could change at any time and you may have trouble getting into the App Store.

Another approach you could take, although it is much more fragile, is to look at the device name. If the user hasn't changed it from the default "User Name's iPhone" AND they are using their real name as an iPhone, you could grab the user name from that. Again, not the best solution by any means, but it does give you something else to try.

The generally accepted answer to this question is to file a Radar with Apple for this feature and to prompt users to choose their card.

Martin Gordon
  • 36,329
  • 7
  • 58
  • 54
  • Apps have been rejected from the store for doing this. Anyway it's not reliable-- if the user ported their phone number from another cell phone carrier, this call almost certainly gives an incorrect result. – Tom Harrington May 08 '09 at 16:54
  • Thanks for the help. After posting this questions, I though about the SBFormattedPhoneNumber approach. It could easily be implemented in a a "safe" future proof way, but it sounds like Apple may be discouraging this for a variety of reasons. Also, Tom, thanks for the heads up. – amattn May 08 '09 at 18:31
  • This no longer returns a value – Brian Aug 07 '14 at 23:55
4

Contacts container have a me identifier property on iOS that can be accessed using container.value(forKey: "meIdentifier")

if let containers = try? CNContactStore().containers(matching: nil) {
  containers.forEach { container in
  if let meIdentifier = container.value(forKey: "meIdentifier") as? String {
    print("Contacts:", "meIdentifier", meIdentifier)
  }
}

The identifier is a legacy identifier used in the old AddressBook framework. You can still access it in CNContact:

let iOSLegacyIdentifier = contact.value(forKey: "iOSLegacyIdentifier")
Kugutsumen
  • 878
  • 8
  • 18
2

There is no such API in the iPhone SDK 2.2.1 and earlier. Please file a request for it at: http://bugreport.apple.com

Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75
2

Edit: [Obsolete answer]

There's no API for getting the "me" card because there is no "me" card. The iPhone's contacts app has no way of marking a card as being "me", and the API reflects this.

Chetan
  • 46,743
  • 31
  • 106
  • 145
Tom Harrington
  • 69,312
  • 10
  • 146
  • 170
  • This isn't exactly true. Sure, the Contacts app has no way of doing this, but you CAN set your "me" card in Settings > Mail, Contacts, Calendar > My Info. – CIFilter Mar 15 '12 at 21:43
  • @LucasTizma: The answer above was written nearly three years before you responded to it. It was correct at the time but of course things change. – Tom Harrington Apr 04 '12 at 20:36
  • Ah, I didn't even notice the date you answered that. Sorry about that! – CIFilter Apr 05 '12 at 00:48
-3

I came up with a partial solution to this

you can get the device name as follows

NSString *ownerName = [[UIDevice currentDevice] name];

in English a device is originally called, for example, 'Joe Blogg's iPhone'

the break out the name

 NSRange t = [ownerName rangeOfString:@"’s"];
    if (t.location != NSNotFound) {
        ownerName = [ownerName substringToIndex:t.location];
    }

you can then take that name and search the contacts

CNContactStore *contactStore = [CNContactStore new];

 NSPredicate *usersNamePredicate = [CNContact predicateForContactsMatchingName:usersName];

    NSArray * keysToFetch = @[[CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName],CNContactPhoneNumbersKey,CNContactEmailAddressesKey,CNContactSocialProfilesKey, ];

 NSArray * matchingContacts = [contactStore unifiedContactsMatchingPredicate:usersNamePredicate keysToFetch:keysToFetch error:nil];

Of course other languages differ in the device name string e.g. 'iPhone Von Johann Schmidt' so more parsing needs to be done for other languages and it only works if the user hasn't changed the name of the device in iTunes to something like "Joes phone' but it gives you a starting point

well... it gives you an array of matching items :) So if there is more than one contact with that array you just have to use pot luck and go with the first one or work thru multiple cards and take what you need from each.

I did say its a partial solution and even though it won't work for all user cases you might find it works for many of your users and reduces a little friction

SimonTheDiver
  • 1,158
  • 1
  • 11
  • 24