{"id":19011899,"url":"https://github.com/3squared/peakcoredata","last_synced_at":"2025-04-22T23:27:53.734Z","repository":{"id":48831454,"uuid":"158395306","full_name":"3Squared/PeakCoreData","owner":"3Squared","description":"PeakCoreData is a Swift microframework providing enhancements and conveniences to Core Data.","archived":false,"fork":false,"pushed_at":"2025-03-20T11:10:16.000Z","size":2887,"stargazers_count":11,"open_issues_count":3,"forks_count":6,"subscribers_count":8,"default_branch":"develop","last_synced_at":"2025-04-17T16:03:26.608Z","etag":null,"topics":["coredata","nsfetchedresultscontroller","peak-framework","persistence"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/3Squared.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-11-20T13:38:58.000Z","updated_at":"2025-03-20T11:10:19.000Z","dependencies_parsed_at":"2025-04-17T05:36:25.841Z","dependency_job_id":"49d13f89-5c8f-451d-8f45-154785ebc115","html_url":"https://github.com/3Squared/PeakCoreData","commit_stats":null,"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3Squared%2FPeakCoreData","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3Squared%2FPeakCoreData/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3Squared%2FPeakCoreData/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/3Squared%2FPeakCoreData/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/3Squared","download_url":"https://codeload.github.com/3Squared/PeakCoreData/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250339497,"owners_count":21414365,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coredata","nsfetchedresultscontroller","peak-framework","persistence"],"created_at":"2024-11-08T19:16:04.891Z","updated_at":"2025-04-22T23:27:53.685Z","avatar_url":"https://github.com/3Squared.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"![PeakCoreData](PeakCoreData.png \"PeakCoreData\")\n\nPeakCoreData is a Swift microframework providing enhancements and conveniences to [`Core Data`](https://developer.apple.com/documentation/coredata). It is part of the [Peak Framework](#peak-framework).\n\n## Observers\n\n### `ManagedObjectObserver`\n\nThe `ManagedObjectObserver` class can be used to observe changes made to a single managed object. State changes include when it is refreshed, updated or deleted.\n\n```Swift\nvar event: Event!\nvar eventObserver: ManagedObjectObserver\u003cEvent\u003e!\n\noverride func viewDidLoad() {\n    super.viewDidLoad()\n    \n    eventObserver = ManagedObjectObserver(managedObject: event)\n    eventObserver.startObserving() { [weak self] obj, changeType in\n        guard let strongSelf = self else { return }\n        switch changeType {\n        case .initialised, .refreshed, .updated:\n            strongSelf.updateView()\n        case .deleted:\n            strongSelf.navigationController?.popToRootViewController(animated: true)\n        }\n    }\n}\n```\n\n### `CountObserver`\n\nThe `CountObserver` class can be used to observe changes to the number of `NSManagedObject` objects as defined by a generic type and an optional `NSPredicate`.\n\n```Swift\nvar countObserver: CountObserver\u003cEvent\u003e!\n\noverride func viewDidLoad() {\n    super.viewDidLoad()\n\n    let predicate = NSPredicate(format: \"%K == false\", argumentArray: [#KeyPath(Event.isHidden)])\n    countObserver = CountObserver\u003cEvent\u003e(predicate: predicate, context: viewContext)\n    countObserver.startObserving() { [weak self] count in\n        guard let strongSelf = self else { return }\n        strongSelf.countLabel.text = String(count)\n    }\n}\n```\n\n## Fetched Data Sources\n\n### `FetchedCollection`\n\n`FetchedCollection` is a wrapper for `NSFetchedResultsController` which acts as its own delegate and exposes changes though a closure.\n\n```Swift\nlet fetchedCollection = FetchedCollection(fetchRequest: Event.sortedFetchRequest(), context: viewContext)\n\nfetchedCollection.onChange = { collection, update in\n    // use collection, or process updates\n}\n\n// subscriptable\nlet object = fetchedCollection[0, 0]\n\n// or with a tuple\nlet object = fetchedCollection[(0, 0)]\n\n// or with an index path\nlet object = fetchedCollection[IndexPath(row: 0, section: 0)]\n\n```\nThis allows you to decouple the `NSFetchedResultsController` from your viewcontroller.\n\n### `FetchedCollectionViewDataSource` and `FetchedTableViewDataSource`\n\nThese classes take care of the boiler-plate code needed to use a `NSFetchedResultsController` with a `UITableView` or `UICollectionView`.\n\n```Swift\nclass EventsTableViewController: UITableViewController {\n\n    var dataSource: FetchedTableViewDataSource\u003cEventsTableViewController\u003e!\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        let frc = NSFetchedResultsController(\n            fetchRequest: Event.sortedFetchRequest(), \n            managedObjectContext: viewContext, \n            sectionNameKeyPath: nil, \n            cacheName: nil\n        )\n        dataSource = FetchedTableViewDataSource(\n            tableView: tableView, \n            cellIdentifier: EventTableViewCell.cellIdentifier, \n            fetchedResultsController: frc, \n            delegate: self\n        )\n        dataSource.animateUpdates = true\n        dataSource.onDidChangeContent = {\n            print(\"Something changed\")\n        }\n        dataSource.performFetch()\n    }\n}\n\nextension EventsTableViewController: FetchedTableViewDataSourceDelegate {\n    \n    func identifier(forCellAt indexPath: IndexPath) -\u003e String {\n        return EventTableViewCell.cellIdentifier\n    }\n\n    func configure(_ cell: EventTableViewCell, with object: Event) {\n        cell.textLabel?.text = object.date?.description\n    }\n}\n```\n\n## Operations\n\n### `CoreDataOperation`\n\n`CoreDataOperation` is a concurrent `Operation` subclass that can be used to perform core data tasks on a background thread. To use, simply subclass `CoreDataOperation` then override the `performWork(in:)` method.\n\nThings to note about this operation:\n\n* `CoreDataOperation` simply wraps the `performBackgroundTask((NSManagedObjectContext) -\u003e Void)` method on `NSPersistentContainer` in a operation.\n* To finish the operation you must call `saveAndFinish()`.\n* Changes will only be merged in to your `viewContext` if you have set the `automaticallyMergesChangesFromParent` on `viewContext` to `true`.\n* `CoreDataOperation` conforms to `ProducesResult` and so can be used to produce a `Result`.\n\n### `CoreDataChangesetOperation`\n\nA `CoreDataOperation` subclass that returns a `Changeset` struct containing all the `NSManagedObjectID` objects that were inserted and updated during the operation.\n\n### `CoreDataBatchImportOperation` and `CoreDataSingleImportOperation`\n\nTwo `CoreDataChangesetOperation` subclasses that can be used to import an array of intermediate objects or a single intermediate object in to Core Data. They would normally be used to import `Decodable` objects from your web service. These operations work automatically as long as the following requirements are met:\n\n* The intermediate object must conform to  `ManagedObjectUpdatable` and `UniqueIdentifiable`.\n* The `NSManagedObject` type you are converting to must conform to `ManagedObjectType` and `UniqueIdentifiable`.\n\n## Protocols\n\n### `ManagedObjectType` and `UniqueIdentifiable`\n\nTo give your `NSManagedObject` subclasses access to a range of helper methods for inserting, deleting, fetching and counting, simply make them conform to the `ManagedObjectType` and `UniqueIdentifiable` protocols. Doing so will also allow you to use `CoreDataBatchImportOperation` and `CoreDataSingleImportOperation`.\n\n### `PersistentContainerSettable`\n\nEach view controller that needs access to the `NSPersistentContainer` should conform to `PersistentContainerSettable`. Conforming to this protocol gives you easy access to the `viewContext` property and a method for saving the `viewContext`. It also allows your `NSPersistentContainer` to be passed around more easily in `prepare(for:sender:)`.\n\n```Swift\noverride func prepare(for segue: UIStoryboardSegue, sender: Any?) {\n    if let controller = segue.destination as? PersistentContainerSettable {\n        controller.persistentContainer = persistentContainer\n    }\n    if let navController = segue.destination as? UINavigationController, let controller = navController.topViewController as? PersistentContainerSettable {\n        controller.persistentContainer = persistentContainer\n    }\n}\n```\n\n## Contributing\n\nPlease read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.\n\n## Versioning\n\nWe use [SemVer](http://semver.org/) for versioning.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details\n\n## Acknowledgments\n\n* [Core Data by objc.io](https://www.objc.io/books/core-data/)\n\n# Peak Framework\n\nThe Peak Framework is a collection of open-source microframeworks created by the team at [3Squared](https://github.com/3squared), named for the [Peak District](https://en.wikipedia.org/wiki/Peak_District). It is made up of:\n\n|Name|Description|\n|:--|:--|\n|[PeakOperation](https://github.com/3squared/PeakOperation)|Provides enhancement and conveniences to `Operation`, making use of the `Result` type.|\n|[PeakNetwork](https://github.com/3squared/PeakNetwork)|A networking framework built on top of `Session` using PeakOperation, leveraging the power of `Codable`.|\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F3squared%2Fpeakcoredata","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F3squared%2Fpeakcoredata","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F3squared%2Fpeakcoredata/lists"}