Reputation: 58097
It's been a while since I've touched Core Data, and I'm now trying to move app on to it. The data is downloaded as JSON from a server and is stored as a few flat files.
When a user interacts with the app, I load the entire data set for a particular screen (hundreds of entries) into memory at once. The user can then filter the records (in my case, they're venues) by distance to them. (Location is provided by Core Data.)
The user can also filter by several other properties of the Venue managed objects, as well as enter a search term.
I'm looking to combine all of these filters to allow the user to search, sort, and browse the data. I've written code to do all of these things using an NSArray in memory, but performance is poor.
Do I want to use NSPredicate here? I know I can use it for filtering by properties of the NSManagedObject
s, but for more transient attributes, such as venue's distance from the user, I'm not sure how this would work.
What are the general steps to achieve this with Core Data?
Upvotes: 0
Views: 68
Reputation: 58097
It turns out that I do want NSPredicate for most of my filtering criteria, but any way I slice it, Core Data can't sort by location.
Filtering alphabetically can be done with NSFetchedResultsController
, and I can also filter by a "type
" property and search term.
As noted elsewhere on the internet, a block based NSSortDescriptor
won't do what I want, because Core Data requires sort descriptors that can compile down to SQL statements. Further, Core Data doesn't know how to do SQL location calculations.
Upvotes: 0
Reputation: 4339
I use a quadtree for geographic queries. It is much faster than scanning an array. My code is derived from the Wikipedia entry on Quadtrees. There are several blog posts about using quadtrees on a MKMapView
. NSPredicate is not a Core Data specific filter. It can be applied to any NSArray
. If your data set is large, several hundred points, it will likely run faster than your loop.
Upvotes: 0
Reputation: 427
As far as distance and core data:
Store lat and long independently, query everything in the "square" that has a center at the user, and a inner radius of the search radius (aka, the square that the circle fits inside)
Throw out results in the corners manually in memory
As far as the total query: some and rules in your predicate will do wonders
Upvotes: 1