I have a custom Parse class that represents an event. The event has 3 PFRelation columns that represent users that have been invited to the event, users that have accepted the event and users that have declined the event.
Is there any way to count the total number of people in each PFRelation without querying the class again?
You would need to query each relation to get the count (which you can do without pulling all of the objects back and counting them).
A better idea is to use cloud code, either to update a variable whenever a relationship is changed (a save hook) to store the count or so that you can query all of the counts for one object in a single request.
Related
With the impending death of Parse, I'm re-writing an app using CloudKit. Suppose I'm making a recipe scheduling app. I want a given schedule to contain an ordered list of recipes, and recipes can be in multiple schedules. So I have:
a Schedule object, which has a one-to-many relationship to ScheduleItem objects called "scheduleItems"
a ScheduleItem object has a dayOfWeek field and a one-to-one relationship with a Recipe object called "recipe"
a Recipe object has some information, including its name and ingredients (more relationships)
Assume I have the Schedule object, and I want to get all of its ScheduleItems AND their associated Recipes in one single query. In Parse, I could set up this query:
PFQuery *query = [PFQuery queryWithClassName:#"Schedule"];
[query includeKey:#"scheduleItems.recipe"];
And that query would fetch all the scheduleItems along with all their recipes, allowing me to avoid having to perform multiple network requests.
Is there a way to do this in CloudKit? I see that I can use a CKFetchRecordsOperation to fetch multiple records at once given their recordIDs, but I wouldn't know the record IDs of the recipes until I had already fetched the scheduleItems, thus still necessitating a second network request.
CloudKit is not a relational database. It's a key-value store. There is no functionality to query multiple recordType's in one query. There is also no functionality for aggregation queries. In your case since it's a one to one relationship you could limit it to 2 queries by adding a CKReference in your Recipe to the Schedule. So then if you have a schedule, you could do one query to get all related ScheduleItem's and an other query to get all related Recipe's
There is a way in the coming version ('16): you can define parent relations and then fetching the parent records will result in the children being fetched as well. This is covered in the WWDC session 'What's New in CloudKit' (2016): https://developer.apple.com/videos/play/wwdc2016/226/
Correction, the parent reference introduced in '16 is not to make it possible to do a single fetch, but rather to automatically share all descendants, when using the new Sharing part of the API. So the answer is no there is still no way but when sharing records, it is a bit less onerous.
I am building an iOS in Swift using Parse.com as my backend.
I have a table of objects: car, and each car can be owned by multiple users, so I have a Car table with the column owners which is a PRRelation of the _User table.
I am displaying all the cars in a TableView and want to determine (for each object) whether the PFUser.currentUser() is in the Relation of _User objects for each car.
Is there a way of doing this without creating a query which then makes a request to the Parse server? Doing that seems very inefficient to have to check again for each object, and would make a large number of Parse database calls which would make me hit the call limit quite quickly if multiple people are using the app...
So is there a way to simply do something like:
if carObject["owners].contains(PFUser.currentUser()) {
println("the current user is an owner of this car")
}
Might it be possible to run a query of all cars, and then another query of all the cars with a whereKey restriction on the students column and then comparing queries? How could I compare the queries?
Have you created your car class in your app? You can download all your car objects from parse at once, put them in an [Car] and then you'll have all the relational data as well.
I'm not 100% sure but you may need to use parsequery.includeKey("users") when you query parse so it also includes the parse user. User's being an attribute of Car.
In my CloudKit setup I have a Person record type and each person has a Friend attribute which is a CKReference to another Person object.
I fetch all Person CKRecords. I list these people in a table and list their friends with them. Currently I just take the CKReference and individually fetch each friend using the recordID.
This is the only way I can see to do it, but what would be best practice? Particularly as I am fetching potentially a very large number of friends. It seems counterintuitive to fetch all these objects individually.
I was wondering if there was a method much like CoreData, where you can choose to fetch related objects in the main fetch? So for example, when I fetch a Person it automatically fetched the friends too.
You could use an 'in' predicate query to fetch multiple id's. You can define a predicate like this:
NSPredicate(format: "To_ID in %#", [recordIdMe, recordIdOther])!
In your case where you see the recordIdMe and recordIdOther you should have an array of valid CKReference objects.
In CloudKit there is no functionality to automatically fetch related records.
Actually you should collect all the RecordIDs and add a CKFetchRecordsOperation to the relevant database object.
You get a back a dictionary to help you match the results with the original list.
I have found this post querying random PFObjects in the Parse forums to be quite helpful, but am having trouble implementing it as query for random PFUsers in my database. As a concrete example, suppose there are 10 users in the database, how would I be able to pull two users at random, and after showing to current_user in my app (by "showing" I mean that it will display some attributes of the two users, such as their hometowns), make sure they are not shown again?
My current thoughts are to add an array property to each PFUser called seen_by_current_user, of which contains a list of user ids which are those seen by the current_user, and when querying for random users using PFQuery, it would only query those !seen_by the current_user. Where I am having difficulty is understanding whether this is doable thorough PFQuery, and if so how I could implement it.
Thanks!
The PFQuery whereKey:notContainedIn: method is what you would want to use, the second parameter would be the array of user ids the current user has already seen.
I have an entity model like ...
[Event]<--->>[Invite]<<--->[Person]
I'd like to create a NSSortDescriptor on this so that if an Event has any Invite where the Person is equal to a given person then they will come first.
i.e. If there are 5 events and one of them has an invite to the current user (which I pass in) then the one with the invite will be first followed by the remaining four.
At the moment I'm just displaying them in date order but I'd like to create an NSSortDescriptor for this.
I'm thinking it should use sortDescriptorWithKey:ascending:comparator: where I specify the comparator but what key should I use? invites?
You can't use sortDescriptorWithKey:ascending:comparator: with an FRC because the sort will be performed in SQL on the store itself and there's no way to convert the block into SQL. You also can't use transient variables.
I'd think about having 2 sections to the results (and therefore 2 different fetch requests with different predicates) and sort each individually. The predicate then deals with the user information and the sort is simple (by date as you currently have it).