【问题标题】:iOS, create JSON object with ABAddressBookCreate's elementiOS,使用 ABAddressBookCreate 的元素创建 JSON 对象
【发布时间】:2014-04-10 01:23:47
【问题描述】:

我正在使用 ABAddressBookCreateWithOptionsABAddressBookCopyArrayOfAllPeople 来获取所有联系人的信息。

我可以得到这样的人的全名、电子邮件和电话号码:

addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
people = ABAddressBookCopyArrayOfAllPeople(addressBook);

for (CFIndex i = 0; i < CFArrayGetCount(people); i++)
{
  ABRecordRef person = CFArrayGetValueAtIndex(people, i);


  ////get full name////
  NSString *fullname = @"";
  if (ABRecordCopyValue(person, kABPersonFirstNameProperty)!=NULL){
      fullname = [NSString stringWithFormat:@"%@ ", ABRecordCopyValue(person, kABPersonFirstNameProperty)];
  }
  if (ABRecordCopyValue(person, kABPersonMiddleNameProperty)!=NULL){
      fullname = [NSString stringWithFormat:@"%@%@ ", fullname,ABRecordCopyValue(person, kABPersonMiddleNameProperty)];
  }
  if (ABRecordCopyValue(person, kABPersonLastNameProperty)!=NULL){
      fullname = [NSString stringWithFormat:@"%@%@", fullname,ABRecordCopyValue(person, kABPersonLastNameProperty)];
  }
  fullname = [fullname stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
  NSLog(@"fullname: %@",fullname);



  ////get phone numbers////
  ABMultiValueRef phonenumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
  if (ABMultiValueGetCount(phonenumbers)>0)
  {
      for (CFIndex j=0; j < ABMultiValueGetCount(phonenumbers); j++)
      {
          NSString *phonenumber = (NSString*)CFBridgingRelease(ABMultiValueCopyValueAtIndex(phonenumbers, j));
          NSLog(@"phone number: %@",phonenumber);
      }
  }
  CFRelease(phonenumbers);



  ////get emails////
  ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
  if (ABMultiValueGetCount(emails)>0)
  {
      for (CFIndex j=0; j < ABMultiValueGetCount(emails); j++)
      {
          NSString *email = (NSString*)CFBridgingRelease(ABMultiValueCopyValueAtIndex(emails, j));
          NSLog(@"email: %@",email);
      }
  }
  CFRelease(emails);
}     

CFRelease(addressBook);
CFRelease(people);         

一切都很完美。但我需要使用以下信息创建一个 JSON 对象:

[{"name":"Christine Work","phone_numbers":["+99023424234"]},{"name":"Alex Bla","phone_numbers":["+135352125262","+13433452347"],"email_addresses":["bla@bla.com","bla2@bla2.com"]}]

场景:如果人有email地址,则将其添加到json对象中,如果没有,则不包含在json中。

如果一个人有多个电话号码或多个电子邮件地址,则将它们全部添加到 json。

我被困在这里了。我知道如何使用 NSDictionary 创建一个 json 对象:

NSError *error;
NSDictionary* info = [NSDictionary dictionaryWithObjectsAndKeys:
                                  @"alex", @"name",
                                  @"+90225252", @"phones",
                                  nil];

NSData* jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:info encoding:NSUTF8StringEncoding];

但是如何在循环中将此代码集成到我的场景中。

【问题讨论】:

  • 接收 JSON 的是什么?即使对象为零,您是否需要包含键,还是可以一起跳过它们?
  • JSON 的最外层是一个数组,因此您应该将其输入序列化程序。该数组包含多个字典,包括“name”、“phone_numbers”、“email_addresses”。 “phone_numbers”和“email_addresses”值又是数组。应该很容易构建该结构。

标签: ios objective-c json nsdictionary nsjsonserialization


【解决方案1】:

试一试。添加了必要的代码以在您的代码之上创建 JSON。如果没有联系人的电话号码或电子邮件,则为该键添加 NSNull。当您从 JSON 中提取数据时,请务必检查它。没有构建代码,所以如果您遇到任何错误,请告诉我。

NSMutableArray *usersArray = [[NSMutableArray alloc] init];
NSMutableDictionary *singleUserDictionary = [[NSMutableDictionary alloc] init];
NSMutableArray *phoneNumbersArray = [[NSMutableArray alloc] init];
NSMutableArray *emailArray = [[NSMutableArray alloc] init];

for (CFIndex i = 0; i < CFArrayGetCount(people); i++) {
        ABRecordRef person = CFArrayGetValueAtIndex(people, i);

    ////get full name////
    NSString *fullname = @"";
    if (ABRecordCopyValue(person, kABPersonFirstNameProperty)!=NULL){
        fullname = [NSString stringWithFormat:@"%@ ", ABRecordCopyValue(person, kABPersonFirstNameProperty)];
    }
    if (ABRecordCopyValue(person, kABPersonMiddleNameProperty)!=NULL){
        fullname = [NSString stringWithFormat:@"%@%@ ", fullname,ABRecordCopyValue(person, kABPersonMiddleNameProperty)];
    }
    if (ABRecordCopyValue(person, kABPersonLastNameProperty)!=NULL){
        fullname = [NSString stringWithFormat:@"%@%@", fullname,ABRecordCopyValue(person, kABPersonLastNameProperty)];
    }
    fullname = [fullname stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    NSLog(@"fullname: %@",fullname);
    [singleUserDictionary setObject:fullname forKey:@"name"];


    ////get phone numbers////
    ABMultiValueRef phonenumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
    if (ABMultiValueGetCount(phonenumbers)>0)
    {
        for (CFIndex j=0; j < ABMultiValueGetCount(phonenumbers); j++)
        {
            NSString *phonenumber = (NSString*)CFBridgingRelease(ABMultiValueCopyValueAtIndex(phonenumbers, j));
            NSLog(@"phone number: %@",phonenumber);
            [phoneNumbersArray addObject:phonenumber];
        }
    }
    else
        [phoneNumbersArray addObject:[NSNull null]];
    [singleUserDictionary setObject:phoneNumbersArray forKey:@"phone_numbers"];

    CFRelease(phonenumbers);


    ////get emails////
    ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
    if (ABMultiValueGetCount(emails)>0)
    {
        for (CFIndex j=0; j < ABMultiValueGetCount(emails); j++)
        {
            NSString *email = (NSString*)CFBridgingRelease(ABMultiValueCopyValueAtIndex(emails, j));
            NSLog(@"email: %@",email);
            [emailArray addObject:email];
        }
    }
    else
        [emailArray addObject:[NSNull null]];
    [singleUserDictionary setObject:emailArray forKey:@"email_addresses"];
    CFRelease(emails);

    [usersArray addObject:[NSDictionary dictionaryWithDictionary:singleUserDictionary]];
    [singleUserDictionary removeAllObjects];
    [phoneNumbersArray removeAllObjects];
    [emailArray removeAllObjects];
}

NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:usersArray options:0 error:&error];

if (error) {
    //json success
}

CFRelease(addressBook);
CFRelease(people);

【讨论】:

  • 我被一件奇怪的事情困住了好几个小时。我整合了你所说的一切,但是,当我使用: NSLog(@"singleUserDictionary: %@",singleUserDictionary); [usersArray addObject:[NSDictionary dictionaryWithDictionary:singleUserDictionary]];控制台说:singleUserDictionary:{“email_addresses”=(“blabla@blabla.com”); name = "姓名姓氏"; "phone_numbersss" = ( "+4643643643" ); }
  • 没关系。但是当我最后记录用户数组时:它为电话号码和电子邮件地址提供空白{“email_addresses”=(); name = "blabla@blabla.com""; "phone_numbersss" = ( ); }
  • @woheras 您的第一条评论对我来说看起来不错。电子邮件和电话号码被保存在一个数组中以占多个。在向 usersArray 添加一个之前插入 singleUserDictionary 的 NSLog。然后还添加了 singleUserDictionary 前后 usersArray 的 NSLogs。
  • 我正在使用 ARC,当我将它们复制到循环中时: NSMutableDictionary *singleUserDictionary = [[NSMutableDictionary alloc] init]; NSMutableArray *phoneNumbersArray = [[NSMutableArray alloc] init]; NSMutableArray *emailArray = [[NSMutableArray alloc] init];它有效,但是为什么当它们位于循环顶部时它不起作用?我现在必须在循环结束时释放这些,但我使用的是 ARC。
  • 您不能使用 ARC 调用 release,ARC 会为您插入版本。它应该在循环之外工作没问题,我正在开发的应用程序有类似的结构。
【解决方案2】:

伪代码:

创建外部 NSMutableArray。

对于每个人--

  • 创建 NSMutableDictionary
  • 插入名称
  • 创建 NSMutableArray 并将电话号码插入其中
  • 将数组作为“phone_numbers”插入字典
  • 重复电子邮件地址(如果存在)
  • 将字典插入数组

通过NSJSONSerialization运行外层数组序列化成NSData对象

【讨论】:

    猜你喜欢
    • 2020-10-10
    • 2021-04-20
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 2019-07-17
    相关资源
    最近更新 更多