L'accès iOS Carnet d'Adresses avec Swift: array nombre de zéro
Je suis en train d'écrire une méthode simple de demander à un utilisateur pour l'accès à leur carnet d'adresse et ensuite, imprimez le nom de chaque personne dans le carnet d'adresses. J'ai vu un certain nombre de tutoriels expliquant comment faire en objective-C, mais vais avoir du mal à les convertir à swift.
Voici ce que j'ai fait jusqu'à présent. Le bloc ci-dessous coule dans mon viewDidLoad() la méthode et vérifie si l'utilisateur a l'autorisation d'accéder au carnet d'adresses ou pas, si ils n'ont pas autorisé l'accès encore, le premier si-déclaration de demander l'accès. Cette section fonctionne comme prévu.
var emptyDictionary: CFDictionaryRef?
var addressBook: ABAddressBookRef?
if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.NotDetermined)
{
println("requesting access...")
addressBook = !ABAddressBookCreateWithOptions(emptyDictionary,nil)
ABAddressBookRequestAccessWithCompletion(addressBook,{success, error in
if success {
self.getContactNames();
}
else
{
println("error")
}
})
}
}
else if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Denied || ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Restricted)
{
println("access denied")
}
else if (ABAddressBookGetAuthorizationStatus() == ABAuthorizationStatus.Authorized)
{
println("access granted")
getContactNames()
}
Une fois, je sais que l'utilisateur a accès, je lance le getContactNames() méthode qui est ci-dessous. Après beaucoup de va-et-vient, j'ai enfin réussi à obtenir ce pour compiler en ajoutant le takeRetainedValue() méthode pour convertir le tableau retourné par ABAddressBookCopyArrayOfAllPeople non géré à partir d'un tableau à une matrice, ensuite, cela me permet de convertir le CFArrayRef à un NSArray.
La question, je suis en cours d'exécution, c'est que le contactList tableau finit par avoir un nombre de 0 et la boucle donc a sauté. Dans mon simulateur, le carnet d'adresses a 6 ou 7, les enregistrements, donc je m'attends à ce que la matrice soit de cette longueur. Des idées?
func getContactNames()
{
addressBook = !ABAddressBookCreateWithOptions(emptyDictionary,nil)
var contactList: NSArray = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
println("records in the array \(contactList.count)") //returns 0
for record:ABRecordRef in contactList {
var contactPerson: ABRecordRef = record
var contactName: String = ABRecordCopyCompositeName(contactPerson).takeRetainedValue()
println ("contactName \(contactName)")
}
}
Un point supplémentaire - si j'utilise le ABAddressBookGetPersonCount méthode, il renvoie -1.
var count: CFIndex = ABAddressBookGetPersonCount(addressBook);
println("records in the array \(count)") // returns -1
Basée sur ce lien ABAddressBookGetPersonCount retourne -1 en iOS, il semble que cette fonction renvoyant -1 pourraient être liés à accorder, mais je doute avoir demandé la permission dans le code ci-dessus (et accordé quand je lance l'application dans le simulateur)
- Avez-vous essayé cette stackoverflow.com/a/12603213/2429147 ?
- Merci, j'ai effectivement trouver que plus tôt, mais n'a pas résolu mon problème. Ci-dessus vous permet de réinitialiser l'autorisation que vous avez accordé l'application, afin de tester la partie de l'application.
- avez-vous un peu d'avance avec le carnet d'adresses?
- Est
addressBook
obtenir une quelconque valeur? Je devineABAddressBookCreateWithOptions()
est défectueux en quelque sorte. - John, je pense que vous avez probablement raison. La recherche dans le débogueur après le "ABAddressBookCreateWithOptions()" la méthode est exécutée dans getContactNames() la méthode affiche "carnet d'adresses = (Swift.bool)faux, valeur = (Builtin.int1)0"
- Pour ceux qui ont encore de le regarder, j'ai juste ajouté de la solution de travail, vous pouvez copier & utiliser.
Vous devez vous connecter pour publier un commentaire.
C'est maintenant beaucoup plus simple. Le chef de la chose à surveiller est que si vous créez un ABAddressBook sans autorisation, vous obtenez un mauvais carnet d'adresse - il n'est pas nul mais il n'est pas bon pour rien non plus. Voici comment j'ai actuellement recommande que vous avez défini l'état d'autorisation et demande d'autorisation si nécessaire:
Et voici comment pour faire défiler toutes les personnes et imprimer leurs noms:
Il semble y avoir un bug, soit avec le compilateur ou le cadre où
ABAddressBookRef
est déclaré typealias deAnyObject
, mais il doit êtreNSObject
pour déballer de laUnmanaged<ABAddressBookRef>!
retourné parABAddressBookCreateWithOptions
. Une solution de contournement consiste à convertir et de l'opaque C pointeur. Le code suivant fonctionne, mais il devrait probablement être beaucoup plus de la vérification des erreurs (et il y a aussi sans doute une meilleure façon de travailler autour de cette question):ABAddressBookCreateWithOptions
retourne désormais unUnmanaged<ABAddressBook>!
qui vous pouvez simplementtakeRetainedValue()
directement.Pour ceux qui recherchent la complète solution de travail, ici, est de savoir comment imprimer seulement les noms des contacts, modifiant le code ci-dessus. Invoquer
getAddressBookNames()
pour accéder au carnet d'adresses, par exemple dans leviewDidLoad()
méthode.Et voici le code complet pour accéder à la les noms des contacts et e-mails - ce qui est fait à l'aide de l'aide de méthodes définies dans les autres réponses.
!
. Ainsi, dans la fonctionprocessEmail(...)
changementNSLog("email: \(myString)")
àNSLog("email: \(myString!)")
Si quelqu'un cherche également à obtenir les adresses e-mail des contacts, j'ai constaté que j'avais besoin de créer deux autres méthodes similaires pour le nouveau Wes a montré.
Voici la version mise à jour de la getContactNames() fonction:
Et voici les deux fonctions supplémentaires que j'ai créé:
Merci encore à Wes pour son aide sur ma question de départ qui m'a aidé à la figure ci-dessus sur.
Si vous avez besoin d' e-mail en outre à matt réponse:
C'est une vieille question, mais une autre réponse peut toujours être utile: j'ai fait une approche pour résoudre les problèmes avec le carnet d'adresses en swift ici: https://github.com/SocialbitGmbH/SwiftAddressBook
Je dois mentionner qu'il existe de nombreux gestionnaires de ABAddressBook là-bas qui peut vous aider à éviter des problèmes comme celui que vous m'avez demandé tout à fait. Ainsi, je considère le lien "une réponse" à la le problème (si ce n'est pas de répondre à comment corriger votre code)
Pour ajouter de l'info ici, c'est ma solution reconstitué à partir de divers endroits (est-il un bon site d'Apple qui décrit réellement ce, les docs que j'ai trouvé en fait fournissent presque rien de plus que ce que les noms de args/membres):
Curieusement, vous devez assurez-vous que il ya une image si vous souhaitez y avoir accès; et vous devez vérifier qu'il y a au moins un e-mail à un contact avant d'essayer de les extraire (pourquoi ne pas simplement renvoyer une liste vide à la place???).
Le "EmailContact" la classe est quelque chose que j'ai fait pour capturer les résultats, il n'est pas démontré, mais l'extrait de code montre comment extraire les informations de la version actuelle de swift/ios.
Aussi, je remarque que les paramètres de site web semblent venir dans le EmailArray pour les contacts ainsi que les e-mails. Pour l'instant, je viens de vérifier pour un signe "@" pour déterminer si ses vraiment un email, mais est-il mieux ou "officielle" façon de le faire?
Enfin, j'espère que c'est la mémoire de la fuite en sécurité.
Oh, bien sûr, cela se fait après l'obtention de l'autorisation, si vous n'êtes pas sûr de savoir comment faire cela, alors ce site est bon: http://www.raywenderlich.com/63885/address-book-tutorial-in-ios
D'autres réponses fournies ici ont été utiles, et guidé cette réponse, mais des erreurs et/ou n'ont pas été mis à jour pour Swift 3. La classe suivante fournit un certain nombre de simplifications et améliorations de la sécurité.
Utilisation est tout simplement d'appeler
AddressBookService.getContactNames
Il y a de bonnes raisons à encore besoin d'utiliser la
ABAddressBook
cadre, commeCNContact
ne pas fournir certaines données clés, y compris la création et la modification des dates par exemple. La méthode dépréciée avertissements sont un peu gênants lorsque l'on travaille avec le code, et ce code supprime les avertissements que le ABAddressBook méthodes ont été dépréciées à partir d'iOS 9 à partir, au lieu de fournir simplement un simple avertissement à cet effet, où que vous appelez la classe ci-dessous.Pas la meilleure solution, mais jusqu'à ce que je trouve ce travail