2009-09-30 1 views
12

Ho un'app per iPhone basata su coredata e ho un'entità che ha latitudine e longitudine come proprietà. Come posso restituire tutte le mie entità ordinate per distanza dalla posizione corrente? L'ho fatto in precedenza senza che Coredata scrivesse una query sql, ma sono nuovo in Coredata e non riesco a capirlo. Vorrei usare NSFetchedResultsController per passare direttamente al mio tableview.come utilizzare il coredata per recuperare un elenco di posti ordinati per distanza

Qualsiasi aiuto per favore?

risposta

2

Ho una situazione simile - e sebbene quanto sopra sia vero per quanto riguarda il fatto di non essere in grado di utilizzare NSFetchedResultsController, è comunque possibile utilizzare i dati di base per recuperare i dati.

Ho usato anche sqlite3 in precedenza e il mio recupero è stato eseguito come una serie di recuperi di dimensioni di riquadri di delimitazione crescenti, fino a quando non viene raggiunta una dimensione in cui ho ottenuto risultati "sufficienti". Nel mio caso raddoppio lo span di latitudine e longitudine per ogni iterazione - dando ca. un quadruplo dell'area per ogni iterazione.

Questo metodo funziona anche in Core Data, ma come detto sopra è necessario copiare gli oggetti in un nuovo array e ordinarli utilizzando il proprio metodo dopo che è stato effettuato il recupero.

+0

penso che finirò per fare qualcosa del genere. Credo che dovrò fare un po 'di lavoro invece di ottenere tutto gratis :-) usare sql direttamente con coredata mi sta facendo sentire male. –

1

Bene, ecco il problema: quando si esegue un NSFetchRequest, è possibile basare il predicato solo su proprietà persistenti. Sembra estremamente improbabile che tu abbia una proprietà persistente che tiene traccia della distanza dalla posizione corrente.

È possibile aggiungere una proprietà temporanea all'entità che fornisce la distanza da una posizione definita globalmente. Dovresti eseguire una richiesta di recupero che ottiene tutti gli oggetti e quindi ordinarli in base a questa proprietà temporanea.

Se si dispone di molti oggetti, si rischia di riempire la memoria abbastanza rapidamente. E anche se non lo fai, finirai per perdere tempo a recuperare oggetti che non userete mai.

Suppongo che abbiate probabilmente un'affinità SQL SELECT SQL che ha calcolato la distanza corrente nella versione precedente. Non sarai in grado di replicarlo con Core Data.

+0

ho pensato che sarebbe il caso, anche se i se forse ho potuto passare in una funzione di ordinamento che calcolate sul lat e lungo, ma sembra che tu non possa. Sembrava troppo bello per essere vero :-) Se sto usando SQLLite, suppongo di poter bypassare i coredata e attaccare alla mia query sql. Grazie. –

8

Nella mia esperienza il modo migliore per farlo è calcolare la distanza di ogni singola voce al primo carico (o cambio di posizione) e salvare quella proprietà su CoreData, in questo modo è possibile recuperare facilmente le voci usando la proprietà distanza.

Ecco un frammento di codice che calcola la distanza tra i 2 set di coordinate:

for(SWShow *show in shows) { 
    CLLocation *showLocation = [[CLLocation alloc] initWithLatitude:show.latitude longitude:show.longitude]; 
    double distance = [currentLocation distanceFromLocation:showLocation]/1000 // in km 
    show.distance = @(distance); 
} 

[managedObjectContext save]; 
+0

Questo combinato con un'attività in background da aggiornare dopo modifiche di posizione significative è un'ottima soluzione. – Dane