2017-12-13 1 views
2

私はデバイス上のすべての連絡先の名前を表示するテーブルビューを持っています。これらの名前はcontactsArrayという配列から来ています。 contactオブジェクトごとにphoneNumbersオブジェクトを取得し、数字をphoneNumberArrayという別の配列にプルします。私はそれらを私のテーブルビューに入れると、それに対応する番号の各連絡先を表示します...しかし、長い間だけです。私が数ダースの行を降りると、いくつかのcontactオブジェクトに複数の電話番号を持つphoneNumbersオブジェクトが含まれているため、数字は正しい連絡先とは一致しません。コンタクトと電話番号が同じになるように、各オブジェクトの最初の電話番号だけを取得するにはどうすればよいですか?デバイスのすべての連絡先から最初の電話番号のみを取得するにはどうすればよいですか?

@property (nonatomic, strong) NSMutableArray *contactsArray; 
    @property (nonatomic, strong) NSMutableArray *phoneNumberArray; 

    @end 

    @implementation Contacts 

    - (void)viewDidLoad 
    { 

     [super viewDidLoad]; 

     self.phoneNumberArray = [[NSMutableArray alloc]init]; 
     self.contactsArray = [[NSMutableArray alloc]init]; 
     [self fetchContactsandAuthorization]; 
    } 

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    { 
     return 1; 
    } 

    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    { 
     return self.contactsArray.count; 
    } 

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
     static NSString *cellId = @"contactCell"; 
     ContactCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; 

     CNContact *contact = self.contactsArray[indexPath.row]; 
     NSString *phone = self.phoneNumberArray[indexPath.row]; 

     NSString *contactName = [NSString stringWithFormat:@"%@ %@",contact.givenName,contact.familyName]; 
     NSString *contactNumber = phone; 

     cell.name.text = contactName; 
     cell.number.text = contactNumber; 
     [cell.inviteBtn addTarget:self action:@selector(openMessagesForContact:) forControlEvents:UIControlEventTouchUpInside]; 

     return cell; 
    } 

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
     return 72; 
    } 

    -(void)fetchContactsandAuthorization 
    { 
     // Request authorization to Contacts 
     CNContactStore *store = [[CNContactStore alloc] init]; 
     [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) { 
      if (granted == YES) 
      { 
       CNContactStore *addressBook = [[CNContactStore alloc]init]; 

       NSArray *keysToFetch [email protected][CNContactFamilyNameKey, 
             CNContactGivenNameKey, 
             CNContactPhoneNumbersKey]; 

       CNContactFetchRequest *fetchRequest = [[CNContactFetchRequest alloc]initWithKeysToFetch:keysToFetch]; 

       [addressBook enumerateContactsWithFetchRequest:fetchRequest error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) { 

        [self.contactsArray addObject:contact]; 

        NSString *phone; 

        for (CNLabeledValue *label in contact.phoneNumbers) { 
         phone = [label.value stringValue]; 
         if ([phone length] > 0) { 
          [self.phoneNumberArray addObject:phone]; 
         } 
        } 
       }]; 

       dispatch_async(dispatch_get_main_queue(), ^{ 
        [self.contactsTableView reloadData]; 
       }); 

      } 
     }]; 
    } 

@end 
+0

答えが答えを –

+0

@simon_smileyありがとうと受け入れるためにあなたの質問を解決したかどうか忘れないでください、Simon。私は今週決勝を終えているので、まだ試してはいけません。私の質問に対する大きな答えのようです。 –

答えて

2

あなたのアプローチの問題は、あなたが電話番号のグローバル配列を作成し、これにすべての電話番号を追加しているということです。

は、ここに私のコードです。代わりに、最初の電話番号を追加するだけです。我々は、我々は唯一の彼らの対応を追加し、電話番号配列の配列

  • に各ユーザーを追加

    1. for (CNLabeledValue *label in contact.phoneNumbers) { 
          phone = [label.value stringValue]; 
          if ([phone length] > 0) { 
           [self.phoneNumberArray addObject:phone]; 
           break; 
          } 
      } 
      
      if (contact.phoneNumbers.count == 0) { 
          [self.phoneNumberArray addObject: @""]; 
      } 
      

      はロジックが今変更されました:

      私は、次のコードを変更します最初の番号

    2. ここでは、2つの配列が直接リンクされています。ブレークがこの新機能により

    を終了するには、電話番号の配列は常に

  • は、我々が呼ぶユーザー配列と同じ数を持って最後にチェックする価値がある - そして私たちは、追加する必要が3に触れもう少し調べる。たとえば、ユーザーが電話番号を持っていない場合はどうなりますか?この場合、番号が連絡先にふさわしいように空白の電話番号を追加する必要があります。

    if ([label isEqualTo: contact.phoneNumbers.lastValue]) { 
        [self.phoneNumberArray addObject: @""]; 
    } 
    

    また、上のすべての電話番号をループし、番号を追加しない場合は、空白の番号を追加します。あなたはあなたのデータを見て、あなたが遭遇するかもしれないさまざまなシナリオを見る必要があります。

    代替ソリューション:

    上記の解決策は、あなたのコードの作業を取得するための簡単な修正である - 個人的に私はそのアプローチの大ファンではないけれども - あなたはそれぞれに複数の番号を使用したい場合はどのような?すべての数字を表示するためにユーザーをクリックしたい場合はどうすればよいですか?コードを設計するときには、後で簡単にリファクタリングできるようにする方法を検討する価値があります。

    他にはありません(Coredataやオブジェクトなど)私は連絡先ごとに辞書の配列を持つことをお勧めします。この配列はその詳細(名前、電話番号など)を保存し、各セルで簡単にアクセスできます。

    [addressBook enumerateContactsWithFetchRequest:fetchRequest error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) { 
    
        NSMutableArray * phoneNumbersTemp = [NSMutableArray new]; 
    
        for (CNLabeledValue *label in contact.phoneNumbers) { 
         phone = [label.value stringValue]; 
         if ([phone length] > 0) { 
          [phoneNumbersTemp addObject:phone]; 
         } 
        } 
    
        NSDictionary * contactDict = @{name: contact.name, 
                phoneNumbers: phoneNumbersTemp} 
    
        [self.contactsArray addObject:contactDict]; 
    }]; 
    

    注:これはsudoのコードで、テストされていない - それは、あなたは、各セル内の最初の電話番号にアクセスできるようになります方法に

    この種のコードを強調することです(ただ各ユーザーの連絡先電話辞書を取得し、最初のエントリを取得する)だけでなく、高度な機能のための連絡先オブジェクトを構築することができます。

  • 関連する問題