I'm trying to set up iCloud sync for an existing CoreData app. The basic syncing is working fine. Now I'm trying to check for duplicates when updating the store.
I've used the official documentation as well as this thread and tried to translate the code into swift. Here is what I've got so far:
func checkDuplicates() {
let uniquePropertyKey = "titel"
let entityName = "entity"
let keyPathExpr = NSExpression(forKeyPath: uniquePropertyKey)
let countExpr: NSExpression = NSExpression(forFunction: "count:", arguments: [keyPathExpr])
let countExprDesc = NSExpressionDescription()
countExprDesc.name = "count"
countExprDesc.expression = countExpr
countExprDesc.expressionResultType = NSAttributeType.Integer64AttributeType
let entity: NSEntityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: moc)!
let uniqueAttr: NSAttributeDescription = (entity.attributesByName[uniquePropertyKey]! as? NSAttributeDescription)!
let sortDescriptor = NSSortDescriptor(key: "timestamp", ascending: true)
let fr = NSFetchRequest(entityName: entityName)
fr.resultType = NSFetchRequestResultType.DictionaryResultType
fr.propertiesToFetch = [uniqueAttr, countExprDesc]
fr.propertiesToGroupBy = [uniqueAttr]
fr.sortDescriptors = [sortDescriptor]
let fetchedDictionaries: NSArray = self.fetchDictionariesWithRequest(fr)
println(fetchedDictionaries)
var valuesWithDupes: NSMutableArray?
for dict in fetchedDictionaries {
let count: Int = dict["count"] as! Int
if count > 1 {
valuesWithDupes!.addObject(dict[uniquePropertyKey]!!)
}
}
println(valuesWithDupes)
let dupeFR = NSFetchRequest(entityName: entityName)
dupeFR.includesPendingChanges = false
dupeFR.fetchBatchSize = 20
let predicate = NSPredicate(format: "\(uniquePropertyKey) IN %@", valuesWithDupes!)
dupeFR.predicate = predicate
let dupes: NSArray = self.fetchDictionariesWithRequest(dupeFR)
println(dupes)
}
func fetchDictionariesWithRequest (request: NSFetchRequest) -> NSArray {
var fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
println(fetchedResultsController.fetchedObjects)
var error: NSError? = nil
if fetchedResultsController.performFetch(&error) {
println("Error when fetching Records: \(error)")
return nil
}
return fetchedResultsController.fetchedObjects!
}
First and obvious problem is that the error check in fetchDictionariesWithRequest
cannot return nil as it does here
Second the fetchedResultsController
always returns nil. This is how the fetchRequest looks in the logs:
<NSFetchRequest: 0x1744c4280> (entity: entity; predicate: ((null)); sortDescriptors: ((
"(timestamp, ascending, compare:)"
)); type: NSDictionaryResultType; includesPendingChanges: NO; propertiesToFetch: ((
"(<NSAttributeDescription: 0x17012b040>), name titel, isOptional 1, isTransient 0, entity entity, renamingIdentifier titel, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue (null)",
"(<NSExpressionDescription: 0x170171f40>), name count, isOptional 1, isTransient 0, entity (null), renamingIdentifier count, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}"
)); propertiesToGroupBy: ((
"(<NSAttributeDescription: 0x17012b040>), name titel, isOptional 1, isTransient 0, entity entity, renamingIdentifier titel, validation predicates (\n), warnings (\n), versionHashModifier (null)\n userInfo {\n}, attributeType 700 , attributeValueClassName NSString, defaultValue (null)"
)); )
However I'm stuck. Do I have any typos in my code? Did I translate something wrong from Objective-C? Does anyone know of a working example of this in swift somewhere in the net?
Any help is much appreciated!
Thx Seb