AdressBook : ajouter un numéro de téléphone à  un contact

oBooBo Membre
17:59 modifié dans API UIKit #1
Bonjour,

Je souhaiterais parcourir la liste des personnes du carnet d'adresse et ajouter un numéro par défaut.

Voici le code que j'utilise et qui ne fonctionne pas :

<br />	//Create an instance of address book<br />	ABAddressBookRef allPeople = ABAddressBookCreate();<br />	//Get the number of people<br />	CFIndex len = ABAddressBookGetPersonCount(allPeople);<br />	//For each people<br />	for(int i = 0; i &lt; len; i++)<br />	{<br />		ABRecordID rid = i + 1;<br />		//Get an instance of a person with its index<br />		ABRecordRef person = ABAddressBookGetPersonWithRecordID(allPeople, rid);<br />		//Get the list of phone numbers<br />		ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);<br />		//Create a mutable list of phone numbers<br />		ABMutableMultiValueRef mutablePhoneNumbersList = ABMultiValueCreateMutableCopy(phoneNumbers);<br />		//Add a new entry in the list of phone numbers<br />		ABMultiValueAddValueAndLabel(mutablePhoneNumbersList, @&quot;0000000000&quot;, (CFStringRef)@&quot;default&quot;, NULL);<br />		//Set the new list to the person<br />		ABRecordSetValue(person, kABPersonPhoneProperty, mutablePhoneNumbersList, nil);		<br />	}<br />


Quelque chose ne fonctionne pas car le "0000000000" n'apparait jamais dans le carnet d'adresse après excution de mon programme. Cependant, la compilation se fait sans erreur ni warning et l'exécution également.

Quelqu'un aurait une idée ?
Merci d'avance,

oBo.

Réponses

  • oBooBo Membre
    17:59 modifié #2
    Apparemment il faudrait appeler la méthode ABAdressBookSave pour enregistrer les modifications apportées au carnet d'adresse. Je l'ai fais et l'application part en erreur. J'ai donc rajouté le test suivant avant d'appeler cette méthode :
    <br />if(ABAddressBookHasUnsavedChanges(allPeople)) {<br />&nbsp; &nbsp; NSLog(@&quot;Des changements à  sauvegarder&quot;);<br />&nbsp; &nbsp; ABAdressBookSave(allPeople, NULL);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />}<br />else {<br />&nbsp; &nbsp; NSLog(@&quot;Pas de changements à  sauvegarder&quot;);<br />}<br />
    

    Mon code passe toujours dans la partie "Pas de changements". Ce qui veut dire que lorsque je modifie mon instance de
    <br />ABRecordRef person = ABAddressBookGetPersonWithRecordID(allPeople, rid);<br />
    


    Elle n'est pas modifiée dans le ABAdressBookRef allPeople.

    En parcourant le Address Book Programming Guide for iPhone OS on peut voir dans la partie "Working with Person Records" que l'on peut ajouter et supprimer un contact. Cependant il n'est pas mentionné que l'on puisse mettre à  jour un contact.

    Quelqu'un aurait des infos à  ce sujet ?
  • NseaProtectorNseaProtector Membre
    17:59 modifié #3
    Bonjour, peut-être que cela se passe avec la synchronisation. Il me semble qu'il y'a une API pour ça. Maintenant je ne suis sur de rien...
  • laudemalaudema Membre
    17:59 modifié #4
    dans 1243933736:

    Bonjour,

    Quelqu'un aurait une idée ?
    Merci d'avance,

    oBo.

    Ce n'est qu'une idée parce que je cantonne mon activité à  Cocoa et à  l'objective-C mais il n'y a pas de raisons que tu puisses accéder à  ta liste de numéros de téléphone sans passer par son index et je n'ai pas vu ça dans ton code. D'après le peu que je sais de C ...
    En objet tu commence par chercher l'index de ton identifiant et en l'occurence je ne connais pas de "default"
    extern CFStringRef const kABPhoneProperty;                  // Generic phone number - kABMultiStringProperty
            extern CFStringRef const kABPhoneWorkLabel;          // Work phone
            extern CFStringRef const kABPhoneHomeLabel;          // Home phone
            extern CFStringRef const kABPhoneMobileLabel;        // Cell phone
            extern CFStringRef const kABPhoneMainLabel;          // Main phone
            extern CFStringRef const kABPhoneHomeFAXLabel;      // FAX number
            extern CFStringRef const kABPhoneWorkFAXLabel;      // FAX number
            extern CFStringRef const kABPhonePagerLabel; 

    Et si tu as créé la tienne alors tu dois commencer par chercher son index ..
    hth
  • oBooBo Membre
    17:59 modifié #5
    dans 1243948851:

    dans 1243933736:

    Bonjour,

    Quelqu'un aurait une idée ?
    Merci d'avance,

    oBo.

    Ce n'est qu'une idée parce que je cantonne mon activité à  Cocoa et à  l'objective-C mais il n'y a pas de raisons que tu puisses accéder à  ta liste de numéros de téléphone sans passer par son index et je n'ai pas vu ça dans ton code. D'après le peu que je sais de C ...
    En objet tu commence par chercher l'index de ton identifiant et en l'occurence je ne connais pas de "default"
    extern CFStringRef const kABPhoneProperty;                  // Generic phone number - kABMultiStringProperty
            extern CFStringRef const kABPhoneWorkLabel;          // Work phone
            extern CFStringRef const kABPhoneHomeLabel;          // Home phone
            extern CFStringRef const kABPhoneMobileLabel;        // Cell phone
            extern CFStringRef const kABPhoneMainLabel;          // Main phone
            extern CFStringRef const kABPhoneHomeFAXLabel;      // FAX number
            extern CFStringRef const kABPhoneWorkFAXLabel;      // FAX number
            extern CFStringRef const kABPhonePagerLabel; 

    Et si tu as créé la tienne alors tu dois commencer par chercher son index ..
    hth


    La doc spécifie bien que l'utilisateur peut créer ses propres labels de numéros de téléphone.

    Quoiqu'il en soit j'ai trouvé la solution à  mon problème ; il faut :
    1: garder une copie de l'entrée du carnet d'adresse à  modifier
    2: modifier la copie
    3: supprimer l'originale
    4: ajouter la copie modifier

    Voici le code fonctionnel :
    <br />//Create an instance of address book<br />ABAddressBookRef allPeople = ABAddressBookCreate();<br />//Get an instance of a personn with its index<br />ABRecordRef person = ABAddressBookGetPersonWithRecordID(allPeople, rid);<br />//Copy the personn<br />ABRecordRef personCopy = person;<br />//Create a mutable list of phone numbers<br />ABMutableMultiValueRef mutablePhoneNumbersList = ABMultiValueCreateMutableCopy(phoneNumbers);<br />//Add a new entry in the list of phone numbers<br />ABMultiValueAddValueAndLabel(mutablePhoneNumbersList, @&quot;0000000000&quot;, (CFStringRef)@&quot;default&quot;, NULL);<br />	<br />//Set the new list to the person<br />ABRecordSetValue(personCopy, kABPersonPhoneProperty, mutablePhoneNumbersList, nil); <br />		<br />CFRelease(mutablePhoneNumbersList);<br />CFErrorRef error;<br />BOOL remove = ABAddressBookRemoveRecord (<br />						&nbsp;  allPeople,<br />						&nbsp;  person,<br />						&nbsp;  &amp;error);<br />if(remove) {<br />	BOOL add = ABAddressBookAddRecord (<br />								 allPeople,<br />								 personCopy,<br />								 &amp;error);<br />	BOOL save = ABAddressBookSave(allPeople, &amp;error);<br />}<br />
    


    Ma seule inquiétude est la suivante :
    <br />//Copy the personn<br />ABRecordRef personCopy = person;<br />
    

    Est-ce que ça me garantit de bien conserver une copie de l'entrée du carnet d'adresse et que celle-ci ne sera pas effacée par mégarde au moment du
    <br />BOOL remove = ABAddressBookRemoveRecord (<br />						&nbsp;  allPeople,<br />						&nbsp;  person,<br />						&nbsp;  &amp;error);<br />
    


    Voilà , je n'ai testé qu'une fois et tout a marché parfaitement : j'ai bien eu un nouveau numéro 0000000000 labellisé "Default" dans mon contact.
  • laudemalaudema Membre
    17:59 modifié #6

    La doc spécifie bien que l'utilisateur peut créer ses propres labels de numéros de téléphone.

    Je n'ai jamais dit le contraire !



    Quoiqu'il en soit j'ai trouvé la solution à  mon problème ; il faut :
    1: garder une copie de l'entrée du carnet d'adresse à  modifier
    2: modifier la copie
    3: supprimer l'originale
    4: ajouter la copie modifier

    Je n'ai pas regardé la doc mais es tu sûr de garder le même identifiant ?
    Dans le cas contraire si ton utilisateur synchronise avec Carnet d'Adresses sur sa machine de bureau tu vas avoir des doublons.
    Me semble t-il ...

  • AliGatorAliGator Membre, Modérateur
    17:59 modifié #7
    Et tu as essayé en appellant ABAddressBookSave... sans vérifier l'état de ABAddressBookHasUnsavedChanges ?
  • oBooBo Membre
    17:59 modifié #8
    Oui en faisant cela, l'application partait en erreur (parce que je passais NULL au NSErrorRef). Cela veut dire qu'il n'y a pas de modifications à  sauvegarder je pense.
  • laudemalaudema Membre
    17:59 modifié #9
    dans 1244017400:

    Oui en faisant cela, l'application partait en erreur (parce que je passais NULL au NSErrorRef). Cela veut dire qu'il n'y a pas de modifications à  sauvegarder je pense.

    hasUnsavedChanges veut dire que certains changements n'ont pu être sauvegardés sur le disque, pas qu'il y a eu des modifications dans la mémoire vive. Enfin c'est comme ça que j'ai lu la doc. En fait c'est le problème d'une base de données qui peut être modifiée par plusieurs applications/utilisateurs en même temps.

    Et en ce qui concerne ta méthode un peu sauvage à  mes yeux de dupliquer/modifier la copie/supprimer l'original j'avais tout faux: effectivement tu gardes l'identifiant, de cette manière tu n'auras pas de doublons. Par contre tu te fatigues peut être pour rien car il ne semble pas copier mais juste ajouter un retain à  l'objet en mémoire:
    <br />&nbsp; &nbsp; &nbsp; &nbsp; ABPerson *fakePerson = [[ABPerson alloc] init];<br />	ABPerson *lAvatar = [fakePerson copy];<br />	NSLog(@&quot;fakePerson: %x lAvatar: %x&quot;, fakePerson,lAvatar);<br />
    

    => fakePerson: 1ba410 lAvatar: 1ba410
    Remarque dupliquer/modifier/remplacer l'original c'est comme ça qu'il faut faire avec les propriété multivalues: les copier dans un MutableMultivalues, y faire les modifs, recopier le MutableMulti dans la propriété..
    Mais ça ne concerne qu'une petite collection, pas tout l'enregistrement.

    Enfin, en ce qui concerne un numéro de téléphone "par défaut" Le Carnet d'Adresses a le "primaryIdentifier" qui permet d'indiquer pour chaque personne quel numéro de téléphone est celui par défaut !
    C'est vrai aussi pour les autres "MultiValues" comme l'adresse ou l'email ..

    hth
Connectez-vous ou Inscrivez-vous pour répondre.