IOS Swift Core Data, how to add fields in ToFetch properties that are not in ToGroupBy properties

Need help.

I have 4 fields in my table:

  • Email
  • message
  • read
  • date_received

I want to select email, message (recent), date_received and the amount of unread messages

Here is my expected result:

test@email.com | Test post | 2015-02-27 | 28 test2@email.com | Test Message2 | 2015-02-29 | 2

Here is my current code:

let fetchRequest:NSFetchRequest = NSFetchRequest() if let entityDescription:NSEntityDescription = NSEntityDescription.entityForName("Message", inManagedObjectContext: managedObjectContext){ fetchRequest.entity = entityDescription } fetchRequest.propertiesToFetch = ["email","message","read","date_received"] fetchRequest.propertiesToGroupBy = ["email"] fetchRequest.resultType = .DictionaryResultType fetchRequest.returnsObjectsAsFaults = false let items:NSArray = managedObjectContext .executeFetchRequest(fetchRequest, error: nil)! 

Output:

 20 18:24:51.639 JPtxt[33368:1345477] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'SELECT clauses in queries with GROUP BY components can only contain properties named in the GROUP BY 
+8
ios group-by swift core-data
source share
2 answers

Just select messages with the usual NSManagedObjectResultType (you don't need to specify this). Then just get the score through KVC (both tested solutions):

 let count = (result.filteredArrayUsingPredicate( NSPredicate(format: "read = NO")) as NSArray).count 

A non-standard, but possibly more concise way is to use the fact that Booleans are stored as ones and zeros

 let count = result.count - result.valueForKeyPath("@sum.read")!.integerValue 
+1
source share

The error you are getting is about SQL rules. However, SQL says that if you want to group by ["email"], you cannot request other properties unless you want to group by them. An example would be if you want to read messages, say, β€œgender” and β€œage,” rather than a case.

However, you can and do need a predicate on the read property to say that you want only unread messages. A predicate is usually more efficient than filtering after a query has completed:

  let fetchRequest:NSFetchRequest = NSFetchRequest() if let entityDescription:NSEntityDescription = NSEntityDescription.entityForName("Message", inManagedObjectContext: managedObjectContext){ fetchRequest.entity = entityDescription } fetchRequest.propertiesToFetch = ["email"] fetchRequest.propertiesToGroupBy = ["email"] fetchRequest.predicate = NSPredicate(format: "read = NO") let items:NSArray = managedObjectContext .executeFetchRequest(fetchRequest, error: nil)! 
0
source share

All Articles