2010-09-17 8 views
20

Je ne reçois aucun rappel de localisation sur sim ou sur un périphérique. J'ai ce code appelé:Pourquoi mon délégué CLLocationmanager n'est-il pas appelé?

- (void)startLocationCallbacks: (NSObject*) ignore 
{ 
    locationManager.delegate = self; 
    locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; 
    locationManager.distanceFilter = MINIMUM_METERS; 

    [locationManager startUpdatingLocation]; 
    NSLog(@"[DEBUG] [locationManager startUpdatingLocation] (%@, %@)", locationManager, locationManager.delegate); 
} 

et Consignation des instructions au sommet des deux

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error 

et

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 

mais ni déclaration de log est jamais appelé. Les notifications de lieu sont activées pour mon application (comme indiqué dans Paramètres, plus j'ai dit "Autoriser".)

Quelles sont les raisons possibles pour lesquelles je ne reçois pas de mises à jour de localisation?

Config/autres informations:

  • J'ai alloué LocationManager, et enregistré dans une propriété de retenir.
  • J'ai appelé startUpdatingLocation
  • J'utilise 4.1 SDK
  • Le problème est à la fois iPod-touch Sim & (2ème génération) & iPhone-3, tous en cours d'exécution 4.1
  • notifications d'emplacement sont autorisés dans mon application (à la fois comme indiqué dans Paramètres et parce que j'ai cliqué sur "autoriser" dans l'alerte.)
  • J'ai utilisé CLLocationManager avec succès avant (dans de nombreuses applications d'expédition!) Ceci est un vrai coup de poing pour moi.

Merci!

+0

NOTE: Je l'ai vu plusieurs autres questions SO similaires, ils n'ont pas aidé. L'ensemble "allume ton wifi", "n'utilise pas sim", etc., chose ne s'applique pas, ici. Pas que je puisse dire, de toute façon. J'espère trouver une liste de toutes les raisons pour lesquelles je ne pourrais pas obtenir les rappels, donc je peux les vérifier. Merci! – Olie

+0

Avez-vous essayé de tester si le délégué est notifié? Exécutez '[locationManager.delegate locationManager: locationManager didUpdateToLocation: newLocation fromLocation: oldLocation];' Si vous exécutez cette opération, votre délégué est notifié comme prévu, cela signifie que vos appareils ne peuvent pas obtenir d'emplacement du tout. Si le délégué ne reçoit pas de notification, cela peut signifier un bug sur votre code avec l'objet délégué ou un bug sur le SDK (très très improbable). – vfn

+2

Un autre indice: J'ai désactivé les notifications d'emplacement dans les paramètres, en essayant de l'obtenir pour me demander à nouveau. Pas de demande En outre, aucune erreur "utilisateur refusé" (didFailWithError: ...) C'est vraiment comme si mon gestionnaire de localisation ne faisait pas d'étincelles. Ou ne pas me reconnaître en tant que délégué. Lorsque j'inspecte locationManager.delegate, c'est la bonne chose. Grr, marmonner, grommeler! – Olie

Répondre

46

Ouf! Ok, je l'ai trouvé.

Il s'avère que l'une des façons de faire un CLLocationManager ne déclenche pas les rappels de localisation est de faire toute la configuration dans le pas-le-main-thread. Lorsque j'ai déplacé ma routine d'installation à performSelectorOnMainThread, tout a fonctionné exactement comme prévu.

Quel cauchemar!

espoir cette réponse aide les autres ...

Modifier/clarification:

A l'origine, j'avais quelque chose comme ceci:

- (BOOL) appDidFinishLaunchingWithOptions: (NSDictionary*) options 
{ 
    // ...[app setup, snip] 
    [NSThread detachNewThreadSelector: @selector(postLaunchSetupThread) toTarget: self withObject: nil]; 
} 

- (void)postLaunchSetupThread 
{ 
    NSAutoreleasePool *pool = [NSAutoreleasePool new]; 
    // ...[other setup, snip] 
    [self setupLocationManager]; 
    [pool release]; 
} 

- (void)setupLocationManager 
{ 
    self.myLocationManager = [[[CLLocationManager alloc] init] autorelease]; 
    [myLocationManager startLocationUpdates]; 
} 

Mais appeler setupLocationManager dans un fil empêché les callbacks . Donc, ma solution était de déplacer la ligne

[self setupLocationManager]; 

sur le fil et de nouveau dans appDidFinishLaunchingWithOptions

+4

Merci pour cela - juste sauvé moi des heures de folie en essayant de le comprendre. CLLocationManager n'aime vraiment pas être créé à partir du thread principal. – lxt

+3

Je devenais fou en essayant de comprendre cela! Merci beaucoup! – Motasim

+1

Vous êtes un épargnant de vie! J'ai passé toute la journée à tirer mes cheveux sur celui-ci ... Merci! –

15

En fait, vous pouvez l'exécuter à partir d'un autre thread ainsi. De la documentation d'Apple:

Configuration of your location manager object must always occur on a thread with an active run loop, such as your application’s main thread.

Assurez-vous que votre boucle d'exécution est en cours d'exécution sur ce thread, et les événements CLLocationManager sont expédiés. En savoir plus sur boucle courir: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

+0

Vrai (+1), j'aurais dû le mentionner dans ma réponse - mais le point est: vous ne pouvez pas configurer le gestionnaire de position est un thread qui ne fonctionne pas et attendez-vous à effectuer des rappels. Les solutions incluent (a) ne pas l'installer dans un thread séparé et (b) assurez-vous que le thread de votre thread séparé est en cours d'exécution. – Olie

+3

J'ai essayé de faire en sorte que cela fonctionne sur un thread avec une boucle d'exécution en cours d'exécution et les méthodes déléguées n'ont toujours pas été appelées. Pouvez-vous fournir un exemple de mise en œuvre? –

1

Pour iOS 8

1) J'ai placé ces lignes juste après que j'ai initié le gestionnaire de localisation.

if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { 
    [self.locationManager requestAlwaysAuthorization]; 
} 

2) J'ajouté NSLocationAlwaysUsageDescription au plist et le mettre à une chaîne et a ajouté un message. 3) Dans mon objectif, je cliqué sur l'onglet Capabilities, puis allumé Modes d'arrière-plan et vérifié « L'emplacement des mises à jour » et « utilise des accessoires Bluetooth LE »

Cela a fonctionné pour moi

0

Dans mon cas, ce fut parce que de mon appareil n'a pas pu déterminer l'emplacement - tout en restant à l'intérieur le signal GPS n'était pas disponible et le wi-fi était également déconnecté afin que le gestionnaire de localisation ne puisse recevoir aucune donnée de localisation et le délégué n'était jamais appelé.

Une fois que je l'ai connecté wi-fi, il a travaillé (je suppose mouvement à l'extérieur devrait également faire l'affaire dans ce cas, mais il est parfois pas moyen très pratique :))

Questions connexes