Giter Site home page Giter Site logo

coredatastack's Introduction

CoreDataStack

Helper to set up a CoreData stack, fetch, create and save NSManagedObject objects for your iOS/tvOS/watchOS/OSX projects. You continue using NSManagedObject, NSFetchedResultsController classes... Not magic, just a helper :)

CoreDataStack instances provide a default NSManagedObjectContext object to use with the NSFetchedResultsController objects. CoreDataStack instances provide also convenient methods to execute the recurring pattern: create a NSManagedObjectContext object, create some NSManagedObject objects, save them and update the user interface in the main thread.

The syntax from the version 2.0 is not compatible with the syntax from version < 2.0. Swift 3 is supported since the version 2.0. To use Swift 2, please switch to the branch swift2.

Example:

import CoreDataStack

// The first block is used to perform actions on the context's thread.
// This block provides a context and save it.
// The second block is used to update the user interface, it runs on the main thread.
myStack.perform(inContext: { context in
    let person = NSEntityDescription.insertNewObject(forEntityName: "Person", into: context) as! Person
    person.firstName = "John"
    person.lastName = "Doe"
}) {
    self.tableView.reloadData()
}

Platforms

iOS, OSX, tvOS, watchOS

Requirements

System

  • iOS 9.0+ / Mac OS X 10.10+ / tvOS 9.0+ / watchOS 2.0+
  • Xcode 7.3+

Installation

Embedded frameworks require a minimum deployment target of iOS 8.0 or OS X Yosemite (10.9).

Carthage

$ sudo brew update
$ sudo brew install carthage
  • Create a Cartfile at the root of your Xcode project:
github "cygy/CoreDataStack"
  • Run the command carthage update, the CoreDataStack framework will be downloaded and built.

  • Drag the files Carthage/Build/[platform]/*.framework into your Xcode project.

  • Go to the "Build Phases" panel, create a Run Script with the following contents:

/usr/local/bin/carthage copy-frameworks

and add the paths to the frameworks under “Input Files”, e.g.:

$(SRCROOT)/Carthage/Build/iOS/CoreDataStack.framework

Manually (embedded framework)

  • Your project must be initialized as a git repository, if not open up a Terminal console, go to your project folder:
$ git init
$ git submodule add https://github.com/cygy/CoreDataStack.git
$ git submodule update --init --recursive
  • Drag the file CoreDataStack/CoreDataStack.xcodeproj into the Project Navigator of your application's Xcode project.

  • Go to the "General" panel and for each target of your project, add the corresponding CoreDataStack.framework as an "Embedding Binaries".

  • The framework must appear under the sections "Embedding Binaries" and "Linked Frameworks and Libraries".

  • Go to the "Build Phases" panel, the framework must appear under the sections "Target dependencies" and "Embed Frameworks".

  • Done! Now you can compile your project with CoreDataStack as a dependency.

Usage

Initialize a CoreDataStack object

import CoreDataStack

let myStack = CoreDataStack(modelFileNames: ["CoreDataStack_Example"], persistentFileName: "example.sqlite")

You pass the names of the .mom files (without the extension) as arguments. CoreDataStack will create the model by merging the .mom files. The second argument is the name of the persistent file. The other arguments are optional (see code source)

Each file name must be passed as argument. By experience I do not recommend to automatically merge all the .mom files in the bundle.

Pull and display objects in UI from CoreData

To pull and display objects from CoreData, use the defaultContext property of CoreDataStack, i.e. with the NSFetchedResultsController objects. As the defaultContext is using the main thread it is fit to be used with the UI objects like the UITableView objects.

import CoreDataStack

let fetchedResultsController = NSFetchedResultsController<MyObject>(fetchRequest: fetchRequest, managedObjectContext: myStack.defaultContext, sectionNameKeyPath: nil, cacheName: nil)

Execute a few operations on NSManagedObject objects

If you want to do a few operations on NSManagedObject objects (like create one object, or delete one object) use a simple NSManagedObjectContext for this task. Execute your tasks and save the context. The changes will be updated to the defaultContext object too.

import CoreDataStack

let context = myStack.newContext()

context.perform {
    // Do your operations here.
    ...

    // Save the context.
    if let error = context.saveToParent() {
        // Handle error here.
        ...
    }
}

This shorthand is equivalent:

import CoreDataStack

myStack.perform(inContext: { context in
    // Do your operations here.
    ...

    // The context is saved at the end of this block, no need to call the `saveToParent` method.
}) {
    // This block is run after the first block is done and the context is saved.
    // This block is run in the main thread and can be used to update the UI.
    ...
}

Behind the scene, a NSManagedObjectContext object that its parent context is the defaultContext object is created.

Execute operations on NSManagedObject objects on background

If you want to do operations on NSManagedObject objects on a background thread, use a dedicated NSManagedObjectContext for this task. Once the operations are done, you have to refresh to defaultContext to update the UI (i.e. refetch from NSFetchedResultsController objects).

import CoreDataStack

let context = myStack.newContextForBackgroundTask()

context.perform {
    // Do your operations here.
    ...

    // Save the context.
    if let error = context.saveToParent() {
        // Handle error here.
        ...
    }

    // Now update the 'defaultContext' object.
    OperationQueue.main.addOperation {
        do {
            try fetchedResultsController.performFetch()
        }
        catch let e {
            // Handle error here.
        }
    }
}

This shorthand is equivalent:

import CoreDataStack

myStack.performBackgroundTask(inContext: { (context, saveBlock) in
    // Do your operations here.
    ...

    // For long running tasks you can save the context occasionally thanks the `saveBlock`.
    if let error = saveBlock(false) {
        // Handle error here.
    }

    // The context is saved at the end of this block, no need to call the `saveContext` method.
}) {
    // This block is run after the first block is done and the context is saved.
    // This block is run in the main thread and can be used to update the UI.
    ...
}

Behind the scene, a NSManagedObjectContext object that its parent context is the writerContext object and not the defaultContext object is created.

Execute a batch of operations on NSManagedObject objects

If you want to do a batch of operations on NSManagedObject objects (like large import and create, or delete), use a dedicated NSManagedObjectContext for this task. Once the operations are done, you have to refresh to defaultContext to update the UI (i.e. refetch from NSFetchedResultsController objects).

This is also useful to import a large amount of data that are not related to the UI.

import CoreDataStack

let context = myStack.newContextForBatchTask()

context.perform {
    // Do your operations here.
    ...

    // Save the context.
    if let error = context.saveToParent() {
        // Handle error here.
        ...
    }

    // Now update the 'defaultContext' object.
    OperationQueue.main.addOperation {
        do {
            try fetchedResultsController.performFetch()
        }
        catch let e {
            // Handle error here.
        }
    }
}

This shorthand is equivalent:

import CoreDataStack

myStack.performBatchTask (inContext: { (context, saveBlock) in
    // Do your operations here.
    ...

    // For long running tasks you can save the context occasionally thanks the `saveBlock`.
    if let error = saveBlock() {
        // Handle error here.
    }

    // The context is saved at the end of this block, no need to call the `saveContext` method.
}) {
    // This block is run after the first block is done and the context is saved.
    // This block is run in the main thread and can be used to update the UI.
    ...
}

Behind the scene, a NSManagedObjectContext object that its parent persistent store is different than the defaultContext object is created.

Save the contexts

You can save the contexts before the application terminates.

import CoreDataStack

func applicationWillTerminate(application: UIApplication) {
    myStack.saveContexts()
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.