Swift - erreur en créant un contact avec numéro de téléphone

les_innommables66

Membre expert
Club iGen
26 Février 2006
1 314
162
Bonjour,

J'essaye d'ajouter des contacts avec Xcode et swift.

Les lignes suivantes, piochées sur internet, fonctionnent parfaitement :

Bloc de code:
import Contacts

let newContact = CNMutableContact()

let store = CNContactStore()


  newContact.givenName = "John"

  newContact.familyName = "Appleseed"

  newContact.middleName = "M"

let email = CNLabeledValue(label: CNLabelWork, value:"[EMAIL][email protected][/EMAIL]")

  newContact.emailAddresses = [email]


let homeAddress = CNMutablePostalAddress()

  homeAddress.street = "1 Infinite Loop"

  homeAddress.city = "Cupertino"

  homeAddress.state = "CA"

  homeAddress.postalCode = "95014"

  newContact.postalAddresses = [CNLabeledValue(label:CNLabelHome, value:homeAddress)]


let birthday = NSDateComponents()

  birthday.day = 1

  birthday.month = 4

  birthday.year = 1988// You can omit the year value for a yearless birthday

  newContact.birthday = birthday



let saveRequest = CNSaveRequest()

  saveRequest.addContact(newContact, toContainerWithIdentifier:nil)

try! store.executeSaveRequest(saveRequest)

En revanche, si j'ajoute le code suivant avant "let saveRequest..." :

Bloc de code:
newContact.phoneNumbers = [CNLabeledValue(

  label: CNLabelWork,

  value: CNPhoneNumber(stringValue: "(33) 6 11111111"))]

J'obtiens une erreur qui commence par :

An uncaught exception was raised

2015-11-15 17:05:58.600 test carnet d'adresses[3065:298144] Unacceptable type of value for attribute: property = "fullNumber"; desired type = NSString; given type = CNPhoneNumber; value = <CNPhoneNumber: 0x60800002c620: countryCode=fr, digits=33611111111>.

Si quelqu'un a une idée ???
Merci,
Nicolas
 
Quand tu fais CNLabeledValue(label:value:), et que tu mets CNLabelWork, value doit être de type NSString. C'est ce que te dit le message d'erreur, te disant qu'il attend un NSString mais que tu lui donnes un CNPhoneNumber.

Donc un moyen de corriger:
newContact.phoneNumbers = [CNLabeledValue(
label: CNLabelWork,
value: "(33) 6 11111111")]
 
Bonjour,

Bloc de code:
newContact.phoneNumbers = [CNLabeledValue(
    label: CNLabelWork,
    value: CNPhoneNumber("(33) 6 11111111").stringValue
)]
 
Merci à tous les deux...

Quand tu fais CNLabeledValue(label:value:), et que tu mets CNLabelWork, value doit être de type NSString. C'est ce que te dit le message d'erreur, te disant qu'il attend un NSString mais que tu lui donnes un CNPhoneNumber.

Donc un moyen de corriger:
newContact.phoneNumbers = [CNLabeledValue(
label: CNLabelWork,
value: "(33) 6 11111111")]

Dans ce cas, j'obtiens l'erreur suivante :

Labeled value <CNLabeledValue: 0x60000004c1e0: identifier=B08EF0CF-EB19-4406-8FAF-2F68F0DBA600, label=_$!<Work>!$_, value=(33) 6 11111111> value (33) 6 11111111 has incorrect type Swift._NSContiguousString. It should be CNPhoneNumber.





Bonjour,

Bloc de code:
newContact.phoneNumbers = [CNLabeledValue(
    label: CNLabelWork,
    value: CNPhoneNumber("(33) 6 11111111").stringValue
)]

Et dans ce cas, Xcode me dit de mettre
value: CNPhoneNumber(stringValue: "(33) 6 11111111").stringValue

puis m'indique l'erreur suivante :

Labeled value <CNLabeledValue: 0x60000004ba00: identifier=2964C7EF-9580-4C4F-94E3-49AD0F5DA317, label=_$!<Work>!$_, value=(33) 6 11111111> value (33) 6 11111111 has incorrect type Swift._NSContiguousString. It should be CNPhoneNumber.

J'en perds mon latin et le peu de swift que je cherche à apprendre !

Le code original que je testais venait du site Apple...

Je suis preneur de toute idée ou explication,
Nicolas
 
Et quand j'essaye :

Bloc de code:
let myCNPhoneNumber = CNPhoneNumber.init(stringValue: "33 111111111")

                        print("\(myCNPhoneNumber.stringValue)")

                       

                        newContact.phoneNumbers = [CNLabeledValue(

                            label: CNLabelWork,

                            value: myCNPhoneNumber

                            )]

Le n° de téléphone s'affiche bien avec l'instruction "print", mais j'obtiens juste après le message d'erreur :

Unacceptable type of value for attribute: property = "fullNumber"; desired type = NSString; given type = CNPhoneNumber; value = <CNPhoneNumber: 0x618000024f80: countryCode=fr, digits=33111111111>.
 
Bonjour,

en regardant la documentation plus en avant, cela semble être un bug "d'implicit cast", de toutes les façons swift est un language marketing profondément immature et qui somme toute n'est qu'une mauvaise copy de C++ ou Mozilla Rust ; c'est ni fait ni à faire, c'est la multiplication des bugs assurée ; je ne sais pas comment des gens responsables et matures se sont laissés convaincre et berner par un arriviste dont les compétences sont over-rated, en quelque sorte ce qu'est Balmer à Microsoft avec un Phd, une catastrophe avec deux bras et deux jambes. Essayer donc as NString pour forcer sans let mais var ; puisque vous ne modifier rien par la suite.
 
Dernière édition:
Bonjour,

let s = "hello" as NSString
var c = "hello" as NSString

je comprend,

let CNLabelPhoneNumberiPhone: String
let CNLabelPhoneNumberMobile: String
let CNLabelPhoneNumberMain: String
let CNLabelPhoneNumberHomeFax: String
let CNLabelPhoneNumberWorkFax: String
let CNLabelPhoneNumberOtherFax: String
let CNLabelPhoneNumberPager: String

c'est le label qui est foireux, mais cela ne change rien: swift c'est de la merde.
 
Dernière édition:
Bonjour,

Je ne comprends pas ce qu'il faudrait changer avec NSString dans
Bloc de code:
newContact.phoneNumbers = [CNLabeledValue(
label: CNLabelWork,
value: CNPhoneNumber("(33) 6 11111111").stringValue
)]
 
Bonjour,

d'après la documentation ;

Bloc de code:
// These constants are predefined labels that can be used in a CNLabeledValue object having a CNPhoneNumbervalue.
let CNLabelPhoneNumberiPhone: String
let CNLabelPhoneNumberMobile: String
let CNLabelPhoneNumberMain: String
let CNLabelPhoneNumberHomeFax: String
let CNLabelPhoneNumberWorkFax: String
let CNLabelPhoneNumberOtherFax: String
let CNLabelPhoneNumberPager: String

vous passez un label générique qui effectivement demande une String pour la valeur passée : "CNLabelWork"

Bloc de code:
// These constants are predefined labels that can be used in a CNLabeledValue object having any value.

let CNLabelHome: String
let CNLabelWork: String
let CNLabelOther: String

- CNLabelWork
// Work label. This label takes a string value.

d'ailleurs la documentation est assez contradictoire... dans ses affirmations ; alors ce qui semble arriver même quand vous passer la valeur String ; le parseur semble voir ceci "(33) 6 11111111" comme un téléphone et appelle de facto le constructeur CNPhoneNumber("(33) 6 11111111") oh! c'est un téléphone ! implicit constructor call to CNPhoneNumber ;

le compilateur doit faire ceci:
Bloc de code:
CNPhoneNumber(CNPhoneNumber("(33) 6 11111111").stringValue)

oh ! he meant CNPhoneNumber let's build it for him!
but as this extension has been written by a dumb asshole ; I don't care about
the context call! let's roll (balls in the wall).
c'est évidemment un bug monumental ; (c'est leur pseudo extension Literals to Objects qui est complètement foireuse, vous en êtes la victime, ils avaient déjà fait le coup en obj-c ; les gens s'étaient énervés, en effet, cela vous forçait de renommer des fonctions dans vos classes...)

si vous passez "CNLabelPhoneNumberiPhone" ou autre CNPhoneNumbervalue labels je pense que cela réglera le problème mais je ne sais pas si c'est ce que vous voulez faire ;

de toutes les façons, je ne connais pas bien cette API ; mais je pense (étant un utilisateur address book depuis la première version en beta) que pour chaque valeur ; cela peut être multiple ; on peut attacher par exemple plusieurs emails ; il faudrait s'intéresser au concept et comment on construit les arbres avant de copier coller les exemples d'Apple qui ont toujours été foireux ;

le problème c'est que les gens copient bêtement parce qu'ils sont estampillés Apple ; non, ils ne sont jamais, pas à prendre comme parole "d'évangile" (plutôt le contraire, ils sont écrits par des blasés de la vie) et à mon avis les "copier coller d'exemples d'Apple" qui pullulent dans les apps sont la première source de bugs.

Conclusion: on n'en sort pas "c'est de la merde" depuis que cette nouvelle équipe d'arrivistes a pris le pouvoir chez Apple ; et les imbeciles qui les ont applaudis à la WWDC alors que la raison commandait de leur jeter des cailloux!

Cordialement.
 
Dernière édition:
Bonsoir,

Avec les emails, j'y arrive parfaitement (y compris à mettre plusieurs emails pour un nouveau contact).
Idem pour les adresses, noms, prénoms, commentaire, société...

J'ai juste ce problème avec les numéros de téléphone.

Toujours le même message d'erreur,
Cordialement,
Nicolas
 
Bonsoir,

J'avance... doucement

J'ai testé le même code initial avec un projet pour iOs.

En testant sur mon téléphone, ça fonctionne parfaitement ! Et le programme ajoute bien un contact John Appleseed avec le n° de téléphone associé.

Mais toujours pas avec un projet pour OSX.
 
Bonjour,

oui qu'est-ce que vous voulez y faire ; ils nous avaient déjà fait le coup avec l'obj-c, il y a une dichotomie entre les APIs (la doc aussi) et les comportements du compilateur / analyzer entre les deux plateformes ; il n' y a plus de développeur chez Apple que du QA avec de jolies diplômes brillants et aucunes compétences réelles

(ils ont viré les grandes gueules compétentes au titre qu'ils n'étaient pas politiquement correcte et apportaient un mauvais état d'esprit (boubhouhouhou) ? et oui, mais au moins ca marche ce qu'ils font, il n'y a pas un bug toutes les 5 lignes de code qu'ils écrivent et 10000 meg par app ) ; que des fautes/bugs d'inattentions ; mais a qui la faute qui chasse le "diplôme brillant"... et qui paient ces gens... ? à un moment donné qui est le plus coupable ? celui qui paie l'incompétent ou l'incompétent ?

ils ont ce qu'ils veulent après tout, une armée de crétins bien polies , incompétents et tout lisses, du totor bien zentil, bien comme il faut, prêt à s'engager dans une ONG a tout moment (enfin sur le papier, ils sont faux-culs en plus), du Hipster quoi, cela a été le putsch des frustrés quand Steve a claqué (et malgré le cinéma larmoyant certains hypocrites étaient bien content) ; ils se sont vengés.

Cordialement.
 
Dernière édition:
Bonjour,

Si quelqu'un a une idée pour traiter ou pour contourner le problème ? Je suis toujours bloqué sur OS X,
Cela ne fonctionne pas plus en Objective-C, c'est un bogue du framework contact (dans OS X)

Ceci fonctionne, mais si j'enlève le commentaire dans la ligne //[contact setPhoneNumbers:arrNumbers]; j'obtient les mêmes erreurs que votre code en swift
Bloc de code:
#import "AppDelegate.h"
@import Contacts;

@implementation AppDelegate

-(void)newContact:(id)sender { //clic sur un bouton
    CNContactStore *store = [CNContactStore new];
    CNSaveRequest *request = [CNSaveRequest new];
    CNMutableContact *contact = [CNMutableContact new];
    [contact setGivenName:@"Jean"];
    [contact setFamilyName:@"Sans-Nom2"];
    CNPhoneNumber *xxxx = [CNPhoneNumber phoneNumberWithStringValue:@"408-974-0000"];
    NSMutableArray * arrNumbers = [[contact phoneNumbers] mutableCopy];
    CNLabeledValue * homePhone = [CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberMobile value:xxxx];
    [arrNumbers addObject:homePhone];
    //[contact setPhoneNumbers:arrNumbers];
    //NSLog(@"téléphones du contact = %@",[contact phoneNumbers]); // ceci me donne bien le bon numéro dans un object CNPhoneNumber
    [request addContact:contact toContainerWithIdentifier:[store defaultContainerIdentifier]];
    NSError *error;
    if (![store executeSaveRequest:request error:&error]) {
        NSLog(@"%s %@",__func__, error);
    }
}
@end


--
La solution est d'utiliser le framework "AddressBook" (en attendant que Apple corrige ce bogue), il est deprecated, mais fonctionne toujours sur El Capitan :
Voici un exemple en Objective-C (je ne connais pas assez le swift pour le convertir) :
Bloc de code:
#import "AppDelegate.h"
@import AddressBook;

@implementation AppDelegate

-(void)newContact:(id)sender { //clic sur un bouton
    ABAddressBook *addressBook = [ABAddressBook sharedAddressBook];
    ABPerson *newPerson = [[ABPerson alloc] init];
    [newPerson setValue:@"Jean" forProperty:kABFirstNameProperty];
    [newPerson setValue:@"Sans-Nom" forProperty:kABLastNameProperty];
 
    // adresse à domicile
    NSMutableDictionary *homeAddress = [NSMutableDictionary new];
    [homeAddress setObject:@"10300 Torre Ave" forKey:kABAddressStreetKey];
    [homeAddress setObject:@"Cupertino" forKey:kABAddressCityKey];
    [homeAddress setObject:@"CA" forKey:kABAddressStateKey];
    [homeAddress setObject:@"95014" forKey:kABAddressZIPKey];
    [homeAddress setObject:@"États-Unis" forKey:kABAddressCountryKey];
 
    // adresse au travail
    NSMutableDictionary *workAddress = [NSMutableDictionary new];
    [workAddress setObject:@"8591 Mulholland Drive" forKey:kABAddressStreetKey];
    [workAddress setObject:@"Los Angeles" forKey:kABAddressCityKey];
    [workAddress setObject:@"CA" forKey:kABAddressStateKey];
    [workAddress setObject:@"90046" forKey:kABAddressZIPKey];
    [workAddress setObject:@"États-Unis" forKey:kABAddressCountryKey];
 
    ABMutableMultiValue *addressList = [ABMutableMultiValue new]; // creation d'une liste d'adresse vide
    [addressList addValue:homeAddress withLabel:kABAddressHomeLabel];// ajoute l'adresse à domicile dans la liste
    [addressList addValue:workAddress withLabel:kABAddressWorkLabel];// ajoute l'adresse au travail dans la liste
    [newPerson setValue:addressList forProperty:kABAddressProperty]; // ajoute la liste des adresses pour ce contact
 
    // numéros de téléphone
    ABMutableMultiValue *phoneList = [ABMutableMultiValue new];// creation d'une liste vide
    [phoneList addValue:@"408-974-0000" withLabel:kABPhoneWorkLabel];// ajoute le numéro de téléphone au travail dans la liste
    [phoneList addValue:@"408-974-1111" withLabel:kABPhoneHomeLabel];// ajoute le numéro de téléphone à domicile dans la liste
    [newPerson setValue:phoneList forProperty:kABPhoneProperty];// ajoute la liste des téléphones pour ce contact

    // email
     ABMutableMultiValue *emailList = [ABMutableMultiValue new];// creation d'une liste vide
    [emailList addValue:@"[email protected]" withLabel:kABEmailWorkLabel];// ajoute l'email au travail dans la liste
    [emailList addValue:@"[email protected]" withLabel:kABEmailHomeLabel];// ajoute l'email à domicile dans la liste
    [newPerson setValue:emailList forProperty:kABEmailProperty];// ajoute la liste des emails pour ce contact

    [addressBook addRecord:newPerson];
    if ([addressBook save]){ NSLog(@"Contact was successfully saved");} // save
}
@end
 
S'il s'agit effectivement d'un bug, il faudrait le rappeler a Apple via le Bug reporter.
J'ai quant a moi rapporte récemment deux bugs d'Xcode 7 et un bug d'El Capitan, et j'en découvre encore par mon travail de développeur. C'est la merde. Je me retrouve en train de re-coder avec Xcode 6 sous Yosemite pour que tout fonctionne nickel.

Jamais vu cela auparavant, sauf avec Xcode 4 ou ils avaient "oublie" le paramètre Priority dans le framework EventKit (EKReminder). J'ai du retourner au framework CalendarStore jusqu'a la sortie d'Xcode 5, bien qu'il soit renseigne comme deprecated. Lui aussi existe toujours. Situation similaire a notre ami ici.

Mboum a raison. Comme toujours.Faut que les Frenchies reviennent: Hullot, Serlet.
 
Dernière édition: