JSQCoreDataKit - A swifter Core Data stack

Last update: Jun 17, 2022

JSQCoreDataKit CI

A swifter Core Data stack

About

This library aims to do the following:

  • Encode Core Data best practices, so you don't have to think "is this correct?" or "is this the right way to do this?"
  • Provide better interoperability with Swift
  • Harness Swift features and enforce Swift paradigms
  • Bring functional paradigms to Core Data
  • Make Core Data more Swifty
  • Simplify the processes of standing up the Core Data stack
  • Aid in testing your Core Data models
  • Reduce the boilerplate involved with Core Data

Further reading on Core Data:

Requirements

  • Xcode 12.0+
  • Swift 5.3+
  • iOS 11.0+
  • macOS 10.12+
  • tvOS 11.0+
  • watchOS 4.0+
  • SwiftLint

Installation

CocoaPods

pod 'JSQCoreDataKit', '~> 9.0.0'

# develop branch
pod 'JSQCoreDataKit', :git => 'https://github.com/jessesquires/JSQCoreDataKit.git', :branch => 'develop'

Swift Package Manager

Add JSQCoreDataKit to the dependencies value of your Package.swift.

dependencies: [
    .package(url: "https://github.com/jessesquires/JSQCoreDataKit.git", from: "9.0.0")
]

Alternatively, you can add the package directly via Xcode.

Documentation

You can read the documentation here. Generated with jazzy. Hosted by GitHub Pages.

Contributing

Interested in making contributions to this project? Please review the guides below.

Also, consider sponsoring this project or buying my apps! ✌️

Credits

Created and maintained by @jesse_squires.

License

Released under the MIT License. See LICENSE for details.

Copyright © 2015-present Jesse Squires.

GitHub

https://github.com/jessesquires/JSQCoreDataKit
Comments
  • 1. Framework does not include symbols from NSManagedObjectContext

    When attempting to call 'delete' I am receiving a -[NSManagedObjectContext delete:]: unrecognized selector sent to instance 0x79e53be0.

    Placing breakpoints in the extension, I can quickly see that the JSQCoreDataKit NSManagedObjectContext extension is NOT called, which makes it understandable why the above error as 'delete' is being called

    Other included frameworks with extensions have worked ok... and I see that the example project works fine. No idea why these symbols are being lost, though a SO post sheds some light on the issue being known for 'generics'

    General information

    • Library version(s): 4.0.1
    • OS version(s): iOS 9.3
    • Devices/Simulators affected: iPhone 5 simulator
    • Reproducible in the demo project (Yes/No): No
    • Related issues: [http://stackoverflow.com/questions/24175596/swift-framework-does-not-include-symbols-from-extensions-to-generic-structs]

    Expected behavior

    Object is deleted

    Actual behavior

    -[NSManagedObjectContext delete:]: unrecognized selector sent to instance 0x79e53be0

    Steps to reproduce

    1. Include framework within the project.
    2. Add framework to the appropriate Build Phases.
    3. Call self.stack?.mainContext.delete(obj)
    Reviewed by MobileVet at 2016-06-03 15:24
  • 2. Add extensions to replace free functions

    Prefer methods and properties to free functions.

    Swift API Design Guidelines

    ~~Let's keep the free functions in place, but add extensions to types (which should call the free functions).~~

    Update:*

    • [x] extension on NSManagedObjectContext for delete
    • [x] extension on NSManagedObjectContext for fetch
    • [x] move resetStack to CoreDataStack
    Reviewed by jessesquires at 2016-04-04 05:33
  • 3. Provide the ability for the CoreDataStackFactory user to supply their…

    Pull request checklist

    • [ √ ] All tests pass. Demo project builds and runs.
    • [ √ ] I have resolved any merge conflicts.
    • [ √ ] I have followed the coding style, and reviewed the contributing guidelines.

    What's in this pull request?

    For a current project, I needed to supply a custom NSPersistentStoreCoordinator subclass so I could support an encrypted backing store. This pull request adds the ability to supply an optional factory method to the CoreDataStackFactory that allows the user of the factory to do just that. I included test coverage and all tests pass.

    Reviewed by troya2 at 2016-06-09 06:01
  • 4. Add persistent store to coordinator on background queue

    Hey Jesse - was looking over the release-2.0 branch and noticed that the persistent store wasn't being added to the psc on a background thread. According to the new (preliminary) docs, they suggest you do so because it can take an unknown amount of time. Just thought I'd throw it out there.

    As part of the initialization of Core Data, assign the adding of the persistent store (NSPersistentStore) to the persistent store coordinator (NSPersistentStoreCoordinator) to a background queue. That action can take an unknown amount of time, and performing it on the main queue can block the user interface, possibly causing the application to terminate.

    https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Conceptual/CoreData/IntegratingCoreData.html#//apple_ref/doc/uid/TP40001075-CH9-SW1

    And there sample implementation fwiw.

    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
            NSError *error = nil;
            NSPersistentStoreCoordinator *psc = [[self managedObjectContext] persistentStoreCoordinator];
            NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error];
            NSAssert(store != nil, @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]);
    });
    

    https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Conceptual/CoreData/InitializingtheCoreDataStack.html#//apple_ref/doc/uid/TP40001075-CH4-SW1

    Reviewed by bartcone at 2015-07-07 02:45
  • 5. Concurrency thread limitations in CoreDataStackFactory not necessary

    The current implementations in the createStackInBackground and createStack methods of the CoreDataStackFactory have some technically unnecessary limitations regarding the calling thread (precondition statements).

    Creating queue based contexts with the NSPrivateQueueConcurrencyType and NSMainQueueConcurrencyType on any thread (including the main thread) is absolutely legit and valid.

    As described in the NSManagedObjectContext Class Reference only contexts using the deprecated confinement pattern must be created and used from a single thread. I.e. those contexts are no longer valid if the thread to which the context was bound during the init phase ends. Queue based contexts on the other hand must not be used with anything else but the performBlock and performBlockAndWait which automatically ensures that the operations are run in a correct context (thread).

    That being said:

    • the precondition in createStack of CoreDataStackFactory is unnecessary. Calling this method asynchronously would be totally fine, both backgroundContext and the mainContext would work as expected.
    • the precondition in createStackInBackground of CoreDataStackFactory is also unnecessary.
    • CoreDataFunctions and the resetStack have the same limitation.

    It does however make sense for some of the mentioned methods to be called asynchronously (or to be called on the main queue) even though there's no technical requirement to do so. If the mentioned limitations are intended because it helps the UI to stay responsive then this should be at least documented. Otherwise it would be a good thing to give developers the freedom to use those methods on any queue they want for whatever reason there may be.

    Reviewed by wiedem at 2016-04-28 16:27
  • 6. Added Framework Search Paths to ExampleModel project (#100)

    Pull request checklist

    This fixes issue #100

    What's in this pull request?

    Added Search Framework Path to the ExampleModel project to locate the JSQCoreDataKit.framework built during carthage build

    Reviewed by darkhonor at 2016-10-25 02:45
  • 7. Update FetchRequest

    Pull request checklist

    This fixes issue #___.

    What's in this pull request?

    Uses a cleaner FetchRequest.

    Reviewed by MaxHasADHD at 2016-06-05 22:31
  • 8. Default saving uses performBlockAndWait and leads to deadlock?

    General information

    • Library version(s): 2.2.0

    Description

    Hi, we're using your excellent framework, and I noticed that the saving performed on didReceiveChildContextDidSaveNotification is using performBlockAndWait by default (see here).

    This may cause deadlocks, for example, if I replace the implementation of didTapAddButton in the ExampleApp with:

        func didTapAddButton(sender: UIBarButtonItem) {
            let childContext = stack.childContext()
            childContext.performBlock {
                Company.newCompany(childContext)
                saveContext(childContext, wait: false)
            }
    
            for i in 1...10 {
                childContext.performBlockAndWait { }
                print(i)
            }
        }
    

    It deadlocks.. I iterate 10 times just to make sure, but it deadlocks on the 2nd time.

    The problem is that there's an implicit waiting when using saveContext(childContext, wait: false), i.e. the childContext thread is waiting for the mainContext to save..

    Why not use a different mechanism for the parent's context saving, so that the waiting behaviour will be preserved?

    Thanks in advance, Amitai.

    Reviewed by david-hoze at 2016-03-28 14:21
  • 9. Carthage builds ExampleModel.framework

    Since Example.xcodeproj and JSQCoreDataKit.xcodeproj are at the same level, Carthage builds ExampleModel.framework which is undesired. Moving /Example into /JSQCoreDataKit seems to me to be the best way to resolve this if you have no objections.

    Reviewed by alexcurylo at 2015-05-07 01:02
  • 10. Podspec needs to specify Swift version 3.0

    New issue checklist

    General information

    • Library version(s): 6.0.0
    • OS version(s): MacOS 10.12
    • Devices/Simulators affected: No
    • Reproducible in the demo project (Yes/No): No
    • Related issues: None

    Expected behavior

    • No "Convert to Current Swift Syntax" dialog should appear after installing cocoapod
    • Project should build

    Actual behavior

    • "Convert to Current Swift Syntax" dialog appears after installing cocoapod
    • Project does not build. Error that JSQCoreDataKit is using legacy Swift.

    Steps to reproduce

    Create a project using Swift 3. Install latest cocoapod 6.0.0 Open project workspace Dialog opens to ask to "Convert to Current Swift Syntax"

    Crash log? Screenshots? Videos? Sample project?

    screen shot 2016-10-13 at 11 18 58

    This can be fixed by adding...

    "pod_target_xcconfig": { "SWIFT_VERSION": "3.0" }
    

    to the podspec but I don't know the syntax of the podspec file that you are using. I am used to the old syntax so not sure how it works with your podspec.

    Once this is added to the podspec it should quiet the dialog.

    Reviewed by oliverfoggin at 2016-10-13 10:21
  • 11. Top level function for migrations

    Pull request checklist

    • [x] All tests pass. Demo project builds and runs.
    • [x] I have resolved any merge conflicts.
    • [x] I have rebased on develop squashed my commits into 1 commit.
    • [x] I have followed the coding style, and reviewed the contributing guidelines.

    This fixes issue #46 .

    What's in this pull request?

    Added a top level function that performs progressive migrations. The function is a bit large, it could be broken down but not sure what's your preference @jessesquires .

    Reviewed by marius-serban at 2016-03-16 22:18
  • 12. Include some test helpers?

    Can wrap this to be reusable:

    https://useyourloaf.com/blog/async-core-data-testing/

    (See also: "verifySaveSucceeded/Failed" helpers from my existing projects)

    Reviewed by jessesquires at 2022-03-05 01:19
  • 13. Remove plist files, autogenerate instead

    As of Xcode 13, plists can be generated automatically.

    We can delete them from the framework targets and test targets.

    Also update Package.swift

    https://useyourloaf.com/blog/xcode-13-missing-info.plist/

    Reviewed by jessesquires at 2021-11-02 23:17
  • 14. macOS unit tests hang on GH actions

    Not sure why this is happening yet, but need to fix.

    Hypothesis: some tests write to disk. maybe a disk access permissions issues?

    Possible solution: disable those tests for macOS

    Reviewed by jessesquires at 2021-07-06 03:57
  • 15. Implement `FetchedResultsCoordinator` a wrapper for `FetchedResultsController`/`Delegate`

    The goal is to remove all boilerplate with FRC.

    The FetchedResultsCoordinator will:

    • create and own the NSFetchedResultsController
    • be the controller's delegate, implement NSFetchedResultsControllerDelegate
    • be the dataSource via DiffableDataSource APIs
    • UICollectionView only

    Todo

    • [x] implement initial FetchedResultsCoordinator (get working with configuring cells)
    • [x] update example project
    • [x] add support for supplementary views
    • [ ] cell interaction: didSelect, etc.
    • [ ] cell swipe actions (delete, favorite)
    • [ ] data source prefetching?
    • [ ] update guides
    • [ ] add docs
    • [ ] add tests

    Notes & docs:

    • https://www.avanderlee.com/swift/diffable-data-sources-core-data/
    Reviewed by jessesquires at 2021-07-04 02:09
100% Swift Simple Boilerplate Free Core Data Stack. NSPersistentContainer
100% Swift Simple Boilerplate Free Core Data Stack. NSPersistentContainer

DATAStack helps you to alleviate the Core Data boilerplate. Now you can go to your AppDelegate remove all the Core Data related code and replace it wi

Jun 7, 2022
JSON to Core Data and back. Swift Core Data Sync.
JSON to Core Data and back. Swift Core Data Sync.

Notice: Sync was supported from it's creation back in 2014 until March 2021 Moving forward I won't be able to support this project since I'm no longer

Jun 8, 2022
Core Data Generator (CDG for short) is a framework for generation (using Sourcery) of Core Data entities from plain structs/classes/enums.
Core Data Generator (CDG for short) is a framework for generation (using Sourcery) of Core Data entities from plain structs/classes/enums.

Core Data Generator Introduction Features Supported platforms Installation CDG Setup RepositoryType ModelType DataStoreVersion MigrationPolicy Basic U

Feb 7, 2022
DataKernel is a minimalistic wrapper around CoreData stack to ease persistence operations.

DataKernel What is DataKernel? DataKernel is a minimalistic wrapper around CoreData stack to ease persistence operations. It is heavily inspired by Su

Jun 2, 2022
Super awesome Swift minion for Core Data (iOS, macOS, tvOS)

⚠️ Since this repository is going to be archived soon, I suggest migrating to NSPersistentContainer instead (available since iOS 10). For other conven

Jan 29, 2022
A powerful and elegant Core Data framework for Swift.
A powerful and elegant Core Data framework for Swift.

A powerful and elegant Core Data framework for Swift. Usage Beta version. New docs soon... Simple do that: let query = persistentContainer.viewContext

May 23, 2022
CloudCore is a framework that manages syncing between iCloud (CloudKit) and Core Data written on native Swift.
CloudCore is a framework that manages syncing between iCloud (CloudKit) and Core Data written on native Swift.

CloudCore CloudCore is a framework that manages syncing between iCloud (CloudKit) and Core Data written on native Swift. Features Leveraging NSPersist

Jun 23, 2022
Unleashing the real power of Core Data with the elegance and safety of Swift
 Unleashing the real power of Core Data with the elegance and safety of Swift

Unleashing the real power of Core Data with the elegance and safety of Swift Dependency managers Contact Swift 5.4: iOS 11+ / macOS 10.13+ / watchOS 4

Jun 25, 2022
JustPersist is the easiest and safest way to do persistence on iOS with Core Data support out of the box.
JustPersist is the easiest and safest way to do persistence on iOS with Core Data support out of the box.

JustPersist JustPersist is the easiest and safest way to do persistence on iOS with Core Data support out of the box. It also allows you to migrate to

Mar 13, 2022
QueryKit, a simple type-safe Core Data query language.
QueryKit, a simple type-safe Core Data query language.

QueryKit QueryKit, a simple type-safe Core Data query language. Usage QuerySet<Person>(context, "Person")

Jun 16, 2022
A minimalistic, thread safe, non-boilerplate and super easy to use version of Active Record on Core Data.
A minimalistic, thread safe, non-boilerplate and super easy to use version of Active Record on Core Data.

Skopelos A minimalistic, thread-safe, non-boilerplate and super easy to use version of Active Record on Core Data. Simply all you need for doing Core

May 11, 2022
HitList is a Swift App shows the implementation of Core Data.
HitList is a Swift App shows the implementation of Core Data.

HitList HitList is a Swift App shows the implementation of Core Data. It is the demo app of Ray Wenderlich's tech blog. For details please reference G

Dec 17, 2021
A synchronization framework for Core Data.

Core Data Ensembles Author: Drew McCormack Created: 29th September, 2013 Last Updated: 15th February, 2017 Ensembles 2 is now available for purchase a

Jun 12, 2022
Core Data code generation

mogenerator Visit the project's pretty homepage. Here's mogenerator's elevator pitch: mogenerator is a command-line tool that, given an .xcdatamodel f

Jun 21, 2022
Super Awesome Easy Fetching for Core Data!

MagicalRecord In software engineering, the active record pattern is a design pattern found in software that stores its data in relational databases. I

Jun 21, 2022
A type-safe, fluent Swift library for working with Core Data
A type-safe, fluent Swift library for working with Core Data

Core Data Query Interface (CDQI) is a type-safe, fluent, intuitive library for working with Core Data in Swift. CDQI tremendously reduces the amount o

Jun 27, 2020
A feature-light wrapper around Core Data that simplifies common database operations.
A feature-light wrapper around Core Data that simplifies common database operations.

Introduction Core Data Dandy is a feature-light wrapper around Core Data that simplifies common database operations. Feature summary Initializes and m

May 11, 2022
Example repo of working with Core Data in a SwiftUI application

CoreData in SwiftUI This repository serves many purpose. But mostly so I can experiment with Core Data in SwiftUI, and also so I can use it show my ap

Jan 30, 2022
This project server as a demo for anyone who wishes to learn Core Data in Swift.

CoreDataDemo This project server as a demo for anyone who wishes to learn Core Data in Swift. The purpose of this project is to help someone new to Co

May 3, 2022