0

So I needed to add a twitter account into an ABRecordRef. However, it seems like the fastest way to do it is to get the multivalue ref of the social profile property, create a mutable version of it, find if it has a twitter entry, and if it already does, create a mutable copy of the dictionary and replace it with a new one. Otherwise, create a new dictionary entry with the twitter key and the user name.

And it actually turns out quite verbose:

   ABRecordRef person;

   ABMultiValueRef oldsocials = ABRecordCopyValue(abperson, kABPersonSocialProfileProperty);
   ABMutableMultiValueRef newsocials;
   if(oldsocials){
      newsocials = ABMultiValueCreateMutableCopy(oldsocials);
   } else {
      newsocials = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
   }

   CFIndex socialsCount = ABMultiValueGetCount(socials);

   bool foundtwitter = false;

   for (int k=0 ; k<socialsCount ; k++) {
      CFDictionaryRef socialValue = (CFDictionaryRef)ABMultiValueCopyValueAtIndex(socials, k);
      if(socialValue){
         if(CFStringCompare( (CFStringRef)CFDictionaryGetValue(socialValue, kABPersonSocialProfileServiceKey), kABPersonSocialProfileServiceTwitter, 0)==kCFCompareEqualTo) {

            CFMutableDictionaryRef tomutate = CFDictionaryCreateMutableCopy(socialValue);

            CFDictionarySetValue(tomutate, kABPersonSocialProfileUsernameKey, toNS(thetwitter));

            ABMultiValueReplaceValueAtIndex(socials, tomutate, k);

            CFRelease(tomutate);

            foundtwitter = true;
         }

         CFRelease(socialValue);
      }

      if(foundtwitter)
         break;

   }


   if(!foundtwitter){
    ABMultiValueAddValueAndLabel(newsocials, [NSDictionary dictionaryWithObjectsAndKeys:
                                          (NSString *)kABPersonSocialProfileServiceTwitter, kABPersonSocialProfileServiceKey,
                                          @"justinbieber", kABPersonSocialProfileUsernameKey,
                                          nil], kABPersonSocialProfileServiceTwitter, NULL);
   }


    ABRecordSetValue(abperson, kABPersonSocialProfileProperty, newsocials, NULL);

   if(oldsocials)
      CFRelease(oldsocials);

   CFRelease(newsocials);

It is actually quite long just for adding twitter, and it feels like that I'm doing something wrong. I mean, ideally adding something like that would be close to this, on another language:

person["socialServices"]["twitter"] = "@SomeUserName";
person.save();

So am I missing something?

kamziro
  • 7,882
  • 9
  • 55
  • 78

1 Answers1

6

Look below my friend, for facebook and twitter - it will work:

 //adding social
ABMultiValueRef social = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
ABMultiValueAddValueAndLabel(social, (__bridge CFTypeRef)([NSDictionary dictionaryWithObjectsAndKeys:
                                                           (NSString *)kABPersonSocialProfileServiceTwitter, kABPersonSocialProfileServiceKey,
                                                           [tempVCard objectForKey:@"twitterUserName"], kABPersonSocialProfileUsernameKey,
                                                           nil]), kABPersonSocialProfileServiceTwitter, NULL);
ABMultiValueAddValueAndLabel(social, (__bridge CFTypeRef)([NSDictionary dictionaryWithObjectsAndKeys:
                                                           (NSString *)kABPersonSocialProfileServiceFacebook, kABPersonSocialProfileServiceKey,
                                                           [tempVCard objectForKey:@"facebookUserName"], kABPersonSocialProfileUsernameKey,
                                                           nil]), kABPersonSocialProfileServiceFacebook, NULL);

ABRecordSetValue(person, kABPersonSocialProfileProperty, social, NULL);
CFRelease(social);

my private array "tempVCard" will be your array for the dynamic data of user.

kurtanamo
  • 1,808
  • 22
  • 27