Check if pointer object created is less than today Parse.com - ios

hey guys i have a table A which has a pointer to Table B. I am trying to query Table A where Table B created At is less than today
Table A (columns)
objectId, Name, Table B pointer, ....
Table B
objectId, EndDate
So far I have this
let query = PFQuery(className:Globals.ParseObjects.ProLeagueWinnings)
query.fromLocalDatastore()
query.fromPinWithName("XXX")
query.includeKey("TableB")
query.whereKeyExists("TableB")
query.whereKey("TableB.EndDate", lessThanOrEqualTo: NSDate())
query.findObjectsInBackground().continueWithSuccessBlock {
(task: BFTask!) -> AnyObject! in
let leagues = task.result as? [ProLeagueWinnings]
if (completion != nil){
if leagues != nil{
completion!(leagues!)
}else{
completion!([])
}
}
return task
}
But it returns everything.

Instead of using EndDate, you could always use the createdAt attribute that is automatically created for you by Parse.
It is also important to remember that NSDate() will return the current absolute time including the hours, minutes and so on. So you will be getting all objects in the relationship (being pointed to) that were created before the exact instant of execution.
See: How to get current date at midnight

Related

Powering Master-Detail with CloudKit

I have a UISearchResultsController that searches locally while typing, and remotely (CloudKit) when the search button is pressed. The number of results returned needs to be 10-30 (I'm currently testing my app with 25 and it's always enough)
The search results list is populated with RecordType1, while it's detail is populated by RecordType1 and RecordType2. My question is how to go about fetching the second reference type while minimizing my requests/sec. I was looking at Apple's CloudCaptions sample, and they solve the problem by fetching the second record type when each of RecordType1 is fetched. It seems that this needlessly creates fetch requests (1[RecordType1] + 25[RecordType2] = 26 requests). How can I reduce this? It seems like it should be possible in two requests (one for RecordType1 and then one to fetch all the RecordType2 associated with it).
UPDATE: RecordType2 has a back reference to RecordType1
Unless I am misunderstanding your problem, I think you can just execute a query on your CloudKit database:
let searchKey = ... // value for recordType1
let z = CKRecordZone.default()
let predicate = NSPredicate(format: "recordType1 == %#", searchKey)
let query = CKQuery(recordType: "recordType2", predicate: predicate)
db.perform(query, inZoneWith: z.zoneID) { (records, error) in
if error != nil {
// `records` contains recordType2
} else {
// check for errors
}
}
You can also search for a multiple keys using the IN comparison in the predicate:
let searchKeys = ... // [value1, value2, value3, etc.]
let predicate = NSPredicate(format: "recordType1 IN %#", searchKeys)
References
CloudKit CKQueryOperation (Apple)
CloudKit CKQuery (Apple)

NSSet filtered objects are removed from previous fetched object from Core Data

I have a one to many relationship setup in my Core Data:
Day <----->> Transactions
A day object will contain an NSSet of transactions and a Date.
At some point I want to fetch the latest Day and get its Transactions filtered by a period (monthly and yearly) and add them to another Day object and save this.
Here is my code:
// get latest day from core data
let lastDay = fetchDays(context: context) { request in
request.sortDescriptors = Day.defaultSortDescriptors
request.fetchLimit = 1
}.first
This will get me the correct Day object. After this I want to get the filtered transactions:
let filteredTransactions = lastDay?.transactions?.filtered(using: NSPredicate(format: "period IN %#", [.monthly, .yearly]))
After I have the filtered transactions I want to add them to a new Day object and save that in Core Data:
context.performChanges {
let day = Day(context: self.context)
day.date = NSDate.today()
day.transactions = filteredTransactions as NSSet?
}
This will also correctly save inside Core Data, but after this point, the transactions that I filtered out (monthly and yearly) have been removed from the lastDay object.
If I fetch that object again, the transactions are gone.
And I have no idea what is going on. It seems that any type of transactions that are filtered are also removed.
I tried all day long to figure out what is going on, but I can't seem to figure out the problem.
Any feedback would be appreciated.
Create a full new list of transactions and set the day object of each transaction to the new Day record:
context.performChanges {
let day = Day(context: self.context)
day.date = NSDate.today()
if let transactions = filteredTransactions {
for t in Array(transactions) {
let transaction = Transactions(context: self.context)
transaction.clone(from: t) // write extension method to Transactions
transaction.day = day
}
}
}

How to structure data inside Core Data for the following scenario

I have the a Person object store in Core Data which contains two attributes:
name
payment
Now I decided I want to also store the average of payments for a day/month/year.
How should I store this inside Core Data ? Inside the Person object ? Create new objects ?
The solution is not to store summary data. You can add convenience methods to your managed object subclass to deliver the desired value. Something along these lines:
func averageForPeriod(startDate: NSDate, endDate: NSDate) -> Double {
guard self.payments != nil else { return 0 }
let periodPayments = (self.payments as Set<Payment>).filter {
$0.date >= startDate && $0.date <= endDate
}
return periodPayments.valueForKeyPath("#avg.amount").doubleValue
}
NB: for comparing dates like this you need to define your own comparison function as shown here, or you can use NSTimeInterval.

Parse backend: key won't increment?

I'm trying to increment a number in my parse table under the column "votes". Here's my code:
func upVote() {
var reviewQuery: PFQuery = PFQuery(className: "reviews")
reviewQuery.whereKey("content", equalTo: reviewTextView.text)
reviewQuery.findObjectsInBackgroundWithBlock{
(objects:[AnyObject]!, error:NSError!)->Void in
if error == nil{
for object in objects{
println(object)
let review:PFObject = object as! PFObject
review.incrementKey("votes", byAmount: 1)
}
}
}
}
When I print the object in the console I can see that it is the correct object that I'm looking for. It looks like this:
<reviews:ZqgSVL1Tsd:(null)> {
content = "njk\n";
reviewer = "<PFUser:6387CJtYI1>";
votes = 1;}
But when I look at my parse end, the number of votes has not changed. What am I doing wrong?
Save the object with
review.saveInBackground()
after incrementing the key.
After you modify an object, however small the modification, you must save it after. You are not saving your changes to the object review.
You have several options for saving, including save(), saveInBackground(), saveEventually(), and more. See the documentation for PFObject for more information:
https://www.parse.com/docs/ios/api/Classes/PFObject.html#//api/name/save
For example, you could save the object synchronously with
review.save() and you could save the object asynchronously with review.saveInBackground().

How to delete a specific row in the table using Swift CoreData

I new to Swift programming. I am using CoreData in my app as a database option.
I am using NSManagedObject (deleteObject) to delete lastObject, firstObject and entire rows in the table.
I want to delete a specific row in the table by using a value which is stored in a variable. I am not using table view (I don't have any index path), this delete operation is the background process after I get response from the my application server.
Any links or tutorials or suggestions will be helpful.
Thanks in advance!!!
Code for deleting lastObject
if var results1 = context.executeFetchRequest(requestParams, error: nil) as? [Params] {
println("\n Params Results count : \(results1.count)")
for param in results1{
for var n = 0 ;n < results1.count; ++n
{
let lastPerson = (results1 as NSArray).lastObject as Params
context.deleteObject(lastPerson)
var savingError: NSError?
context.save(&savingError)
}
}
}
Params table consists of columns 'pname' and 'pvalues'.
I want to delete a specific param pname ='server_timeout'.
Consider if 'Params' table consist of 10 rows and 'pname'='server_timeout' might be present at index 5, 6.
How can I find the 'pname' (i.e 'server_timeout') in this list of records and delete it?
How about creating a predicate that filters out the list to those with pname value of server_timeout in the first place.
context.performBlock {
requestParams.predicate = NSPredicate(format: "pname == %#", "server_timeout")
if let results = context.executeFetchRequest(requestParams, error: nil) as? [Params] {
for param in results {
context.deleteObject(param)
}
var error: NSError?
if !context.save(&error) {
println(error)
}
}
}
As you can see, I have placed the whole search-and-delete inside a performBlock closure. I don't know how you have setup your Core Data, but you might want to consider threading to maximize perceived performance.

Resources