-
Core Data: Sundries and maxims
Core Data is the central way to durably and persistently store information from your app — and we're going to show you how to refine that implementation for even faster data ingest and fetching. Discover how you can improve data capture with batch insert, tailor fetch requests to your data needs, and react to notifications about changes in the persistent store.
To get the most out of this session, you should know and have interacted with Core Data in the past. For more information on the framework, watch “Making Apps with Core Data.”Recursos
Vídeos relacionados
WWDC19
-
Buscar neste vídeo...
-
-
1:48 - Batch Operations - Enable Persistent History
storeDesc.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) -
2:32 - NSBatchInsertRequest.h
//NSBatchInsertRequest.h @available(iOS 13.0, *) open class NSBatchInsertRequest : NSPersistentStoreRequest { open var resultType: NSBatchInsertRequestResultType public convenience init(entityName: String, objects dictionaries: [[String : Any]]) public convenience init(entity: NSEntityDescription, objects dictionaries: [[String : Any]]) @available(iOS 14.0, *) open var dictionaryHandler: ((inout Dictionary<String, Any>) -> Void)? open var managedObjectHandler: ((inout NSManagedObject) -> Void)? public convenience init(entity: NSEntityDescription, dictionaryHandler handler: @escaping (inout Dictionary<String, Any>) -> Void) public convenience init(entity: NSEntityDescription, managedObjectHandler handler: @escaping (inout NSManagedObject) -> Void) } -
3:01 - Earthquakes Sample - Regular Save
//Earthquakes Sample - Regular Save for quakeData in quakesBatch { guard let quake = NSEntityDescription.insertNewObject(forEntityName: "Quake", into: taskContext) as? Quake else { ... } do { try quake.update(with: quakeData) } catch QuakeError.missingData { ... taskContext.delete(quake) } ... } do { try taskContext.save() } catch { ... } -
3:16 - Earthquakes Sample - Batch Insert with Array of Dictionaries
//Earthquakes Sample - Batch Insert var quakePropertiesArray = [[String:Any]]() for quake in quakesBatch { quakePropertiesArray.append(quake.dictionary) } let batchInsert = NSBatchInsertRequest(entityName: "Quake", objects: quakePropertiesArray) var insertResult : NSBatchInsertResult do { insertResult = try taskContext.execute(batchInsert) as! NSBatchInsertResult ... } -
3:28 - Earthquakes Sample - Batch Insert with a block
//Earthquakes Sample - Batch Insert with a block var batchInsert = NSBatchInsertRequest(entityName: "Quake", dictionaryHandler: { (dictionary) in if (blockCount == batchSize) { return true } else { dictionary = quakesBatch[blockCount] blockCount += 1 } }) var insertResult : NSBatchInsertResult do { insertResult = try taskContext.execute(batchInsert) as! NSBatchInsertResult ... } -
5:42 - NSBatchInsertRequest - UPSERT
let moc = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.privateQueueConcurrencyType) moc.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy insertResult = try moc.execute(insertRequest) -
6:30 - Batch Update Example
//Earthquakes Sample - Batch Update let updateRequest = NSBatchUpdateRequest(entityName: "Quake") updateRequest.propertiesToUpdate = ["validated" : true] updateRequest.predicate = NSPredicate("%K > 2.5", "magnitude") var updateResult : NSBatchUpdateResult do { updateResult = try taskContext.execute(updateRequest) as! NSBatchUpdateResult ... } -
7:33 - Batch Delete without and with a Fetch Limit
// Batch Delete without and with a Fetch Limit DispatchQueue.global(qos: .background).async { moc.performAndWait { () -> Void in do { let expirationDate = Date.init().addingTimeInterval(-30*24*3600) let request = NSFetchRequest<Quake>(entityName: "Quake") request.predicate = NSPredicate(format:"creationDate < %@", expirationDate) let batchDelete = NSBatchDeleteRequest(fetchRequest: request) batchDelete.fetchLimit = 1000 moc.execute(batchDelete) } } } -
12:18 - Fetch average magnitude of each place
//Fetch average magnitude of each place let magnitudeExp = NSExpression(forKeyPath: "magnitude") let avgExp = NSExpression(forFunction: "avg:", arguments: [magnitudeExp]) let avgDesc = NSExpressionDescription() avgDesc.expression = avgExp avgDesc.name = "average magnitude" avgDesc.expressionResultType = .floatAttributeType let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Quake") fetch.propertiesToFetch = [avgDesc, "place"] fetch.propertiesToGroupBy = ["place"] fetch.resultType = .dictionaryResultType -
13:36 - NSManagedObjectContext.h - Modernized Notifications
//NSManagedObjectContext.h @available(iOS 14.0, *) extension NSManagedObjectContext { public static let willSaveObjectsNotification: Notification.Name public static let didSaveObjectsNotification: Notification.Name public static let didChangeObjectsNotification: Notification.Name public static let didSaveObjectIDsNotification: Notification.Name public static let didMergeChangesObjectIDsNotification: Notification.Name } -
13:54 - NSManagedObjectContext.h - Modernized Keys
//NSManagedObjectContext.h @available(iOS 14.0, *) extension NSManagedObjectContext { public enum NotificationKey : String { case sourceContext case queryGeneration case invalidatedAllObjects case insertedObjects case updatedObjects case deletedObjects case refreshedObjects case invalidatedObjects case insertedObjectIDs case updatedObjectIDs case deletedObjectIDs case refreshedObjectIDs case invalidatedObjectIDs } } -
14:08 - Enable Remote Change Notifications with Persistent History
storeDesc.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) storeDesc.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) -
16:19 - History Pointers
let changeDesc = NSPersistentHistoryChange.entityDescription(with: moc) let request = NSFetchRequest<NSFetchRequestResult>() //Set fetch request entity and predicate request.entity = changeDesc request.predicate = NSPredicate(format: "%K = %@",changeDesc?.attributesByName["changedObjectID"], objectID) //Set up history request with distantPast and set fetch request let historyReq = NSPersistentHistoryChangeRequest.fetchHistory(after: Date.distantPast) historyReq.fetchRequest = request let results = try moc.execute(historyReq)
-