2012-09-02 11 views
23

So che se un'app utilizza "Il servizio di cambio di posizione significativo", iOS lo riattiverà se è disponibile un aggiornamento di posizione, anche se l'app viene interrotta.iOS risveglierà l'app terminata se è registrata con la posizione di UIBackgroundModes?

Non sono riuscito a trovare una risposta chiara sul caso se l'app utilizza i servizi di localizzazione standard e specifica la posizione come chiave per UIBackgroundModes: Sarà anche iOS a riattivarlo per consegnare l'aggiornamento anche se è stato terminato? O l'app deve essere in esecuzione in background per ottenere il callback dell'aggiornamento della posizione?

UPDATE: Al momento in cui lo stavo chiedendo, non avevo il tempo di testarlo. Ma dopo aver ottenuto una risposta qui, ho scritto questo pezzo di codice nel delegato della mia applicazione per vedere se la mia app terminata verrà rilanciata quando riceverà un aggiornamento di posizione. Sto visualizzando una UILocalNotification quando ricevo la notifica dell'aggiornamento. Tuttavia, quando ho interrotto la mia app e poi cambiato la mia posizione in città, l'app non è stata riavviata e non ho ricevuto alcun aggiornamento. Puoi dirmi che cosa sto facendo di sbagliato?

UPDATE # 2: Secondo i risultati finali in questo Q & A, non c'è niente di sbagliato in questo codice ed è il comportamento previsto per un'applicazione che utilizza i servizi di localizzazione standard, non deve essere rilanciato dopo la risoluzione.

Ho aggiunto il percorso come uno dei UIBackgroundMode nel file Info.plist.

E questa è la parte correlata localizzazione di mia app delegato:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  

    [UIApplication sharedApplication].applicationIconBadgeNumber = 0; 

    m_locManager = [[CLLocationManager alloc] init]; 
    m_locManager.delegate = self; 
    [m_locManager startUpdatingLocation]; 
    return YES; 
} 

- (void)applicationDidEnterBackground:(UIApplication *)application { 
    [m_locManager startUpdatingLocation]; 
} 

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error 
{ 
    NSLog("%@", [NSString stringWithFormat:@"Background Fail %@", [error localizedDescription]]); 
} 

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
      fromLocation:(CLLocation *)oldLocation 
{ 
    UILocalNotification * theNotification = [[UILocalNotification alloc] init]; 
    theNotification.alertBody = [NSString stringWithFormat:@"Background location %.06f %.06f %@" , newLocation.coordinate.latitude, newLocation.coordinate.longitude, newLocation.timestamp]; 
    theNotification.alertAction = @"Ok"; 

    theNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1]; 

    [[UIApplication sharedApplication] scheduleLocalNotification:theNotification]; 
} 
+2

Non sapevo che fosse possibile svegliando un'app, con il valore di upvoted –

+0

Anche in questo caso, NON può essere utilizzato come un trucco per riattivare periodicamente l'app! Apple rifiuterà immediatamente la tua app se utilizzi UIBackgroundModes per nessun altro uso rispetto al suo scopo: * Tracciamento della posizione di un utente *. – runmad

+0

@runmad Sì, so che questo dovrebbe essere usato per lo scopo giusto. Il mio è tracciare la posizione dell'utente al fine di inviarlo al server, in modo che il server gli invierà una notifica push se è più vicino a un'area. Considerando il rifiuto dell'app, sarò più sicuro se utilizzo un servizio di cambio di posizione significativo anziché quello standard? – aslisabanci

risposta

4

Sì, si comporterà allo stesso modo, tranne che riceverà gli aggiornamenti più spesso (e quindi consumano più batteria).

Fonte: App States and Multitasking nella sezione Tracciamento della posizione dell'utente.

EDIT Dopo rilettura, sembra che il programma sarà svegliato da uno stato sospeso ma non un terminato uno. Non penso che tu abbia davvero bisogno di questa modalità in background, però. È progettato per le app che necessitano di informazioni dettagliate sulla posizione (come la navigazione turn-by-turn). Consulta la sezione nella guida alla programmazione della posizione sulla programmazione "region based". L'esempio nei tuoi commenti è elencato tra gli usi di questa app.

modificare nuovamente Come per la discussione nei commenti, la soluzione finale sembra essere l'impostazione cambiamento significativo posizione finché l'utente non è abbastanza vicino, e poi passaggio a bel cambiamento posizione (e sperando che l'applicazione non ottiene terminato durante tale periodo ^^)

+0

Per estendere questa risposta, non è possibile utilizzare questa modalità in background per far sì che l'app venga avviata per altri motivi che, se di fatto, ha bisogno della posizione degli utenti per eseguire un aggiornamento di qualche tipo. – runmad

+0

Abbastanza corretto @runmad Apple rifiuterà le app che si comportano in questo modo. – borrrden

+0

OK, grazie ragazzi. Ho postato il mio commento sotto la mia domanda. – aslisabanci

3

Sembra che tu abbia trovato una soluzione praticabile e sembra che l'utilizzo del quadro di modifiche significative ti farà risparmiare un po 'di autonomia, purché sia ​​sufficientemente preciso per i tuoi scopi. La soluzione è anche utile perché consente di destreggiarsi potenzialmente oltre il limite per-app di 20 regioni che possono essere monitorate simultaneamente, monitorando solo le regioni a cui si è più vicini.

Ho bisogno di funzionalità simili, ma non credo che il cambiamento significativo sarebbe abbastanza accurato per la mia app, quindi ho scavato un po 'di più e ho trovato quanto segue.

Per il Location Awareness Programming Guide, in "Monitoraggio Regioni shape-based":

In iOS, regioni associate alla tua app sono monitorati in ogni momento, anche quando l'applicazione non è in esecuzione. Se un confine di una regione viene attraversato mentre un'app non è in esecuzione, l'app viene rilanciata in background per gestire l'evento. Allo stesso modo, se l'app viene sospesa quando si verifica l'evento, viene riattivata e viene data una breve quantità di tempo per gestire l'evento.

E anche in "Gestione Boundary-Crossing Eventi per una Regione":

Ogni volta posizione corrente dell'utente attraversa una regione di confine, il sistema genera un evento regione appropriata per la vostra app. Se la tua app è già in esecuzione, questi eventi vanno direttamente ai delegati di tutti gli oggetti di gestione posizione correnti. Se la tua app non è in esecuzione, il sistema la avvia in background in modo che possa rispondere. Apps possono implementare i seguenti metodi per gestire attraversamenti di confine:

locationManager: didEnterRegion:

locationManager: didExitRegion:

Nel mio caso, ho solo bisogno di sparare una notifica quando il confine è stato attraversato, così ho impostato il mio AppDelegate di conformarsi alle CLLocationManagerDelegate, creato una proprietà locationManager, e mettere questo nel mio file di implementazione:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    self.locationManager.delegate = self; 
    return YES; 
} 

- (CLLocationManager *)locationManager 
{ 
    if (!_locationManager) { 
     _locationManager = [[CLLocationManager alloc] init]; 
     _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; 
    } 
    return _locationManager; 
} 

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region 
{ 
    UILocalNotification *notification = [[UILocalNotification alloc] init]; 
    notification.alertBody = NSLocalizedString(@"You crossed a boundary!", @"user crossed a boundary"); 
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 
} 

Testing s questo funziona senza che sia necessario impostare la chiave di posizione UIBackgroundModes. In questo caso d'uso, il sistema operativo gestisce il monitoraggio dei confini per te e quindi invia l'evento alla tua app il tempo sufficiente per elaborare l'evento. Questo non fa lanciare l'app, lo esegue solo in background per alcuni secondi per elaborare l'evento di confine, durante il quale è possibile solo svolgere attività pertinenti. Spero che questo aiuti anche qualcun altro!

+0

Ciao Daniel, nel mio caso devo eseguire più chiamate API. Penso che quando l'utente attraversa una regione, l'app si sveglia per alcuni secondi, non sufficiente per eseguire le mie attività. Ho controllato questo con una notifica locale sulla regione di attraversamento. È possibile prolungare il tempo di attivazione delle app in che modo? Grazie in anticipo. – Yogendra

2

Una volta che si uccide l'applicazione, gli aggiornamenti della posizione vengono inviati all'applicazione

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

È necessario raccogliere gli aggiornamenti sulla posizione all'interno di questo metodo delegato, cercando la chiave di lancio come sotto,

if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) 
{ 
//Code to handle the location update 
} 

Spero che questo sia quello che stai cercando. Sì, è necessario impostare la chiave "Modalità backround richieste" con il valore "Registri app per aggiornamenti posizione" in Plist.

Problemi correlati