• This repository has been archived on 02/Jun/2018
  • Stars
    star
    562
  • Rank 79,281 (Top 2 %)
  • Language
    Swift
  • License
    MIT License
  • Created over 9 years ago
  • Updated about 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The Big Nerd Ranch Core Data Stack

BNR Core Data Stack

Carthage compatible CocoaPods Compatible GitHub license Build Status

Big Nerd Ranch

The BNR Core Data Stack is a small Swift framework that makes it both easier and safer to use Core Data.

A better fetched results controller and delegate

Our FetchedResultsController<ManagedObjectType> sends Swifty delegate messages, rather than a mess of optionals.

Turn this:

func controller(
    _ controller: NSFetchedResultsController<NSFetchRequestResult>,
    didChange anObject: Any,
    at indexPath: IndexPath?,
    for type: NSFetchedResultsChangeType,
    newIndexPath: IndexPath?
) {
    guard let book = anObject as? Book else {
        preconditionFailure("Why is this thing an Any anyway? WTH!")
    }

    switch type {
    case .insert:
        guard let newIndexPath = newIndexPath else {
            preconditionFailure("Insertion to nowheresville? WHY IS THIS OPTIONAL?")
        }

        print("We have a new book! \(book.title)")
        tableView?.insertRows(at: [newIndexPath], with: .automatic)

    case .delete:
        guard let indexPath = indexPath else {
            preconditionFailure("Deletion you say? Where? WHY IS THIS OPTIONAL?")
        }

        tableView?.deleteRows(at: [indexPath], with: .automatic)

    case .move:
        guard let newIndexPath = newIndexPath else {
            preconditionFailure("It moved to NOWHERE! WHY IS THIS OPTIONAL?")
        }
        guard let indexPath = indexPath else {
            preconditionFailure("It moved from NOWHERE?! WHY IS THIS OPTIONAL!")
        }

        tableView?.moveRow(at: indexPath, to: newIndexPath)

    case .update:
        guard let indexPath = indexPath else {
            preconditionFailure("I give up! Remind me, why are we using Swift, again?")
        }

        tableView?.reloadRows(at: [indexPath!], with: .automatic)
    }
}

Into this:

func fetchedResultsController(
    _ controller: FetchedResultsController<Book>,
    didChangeObject change: FetchedResultsObjectChange<Book>
) {
    switch change {
    case let .insert(book, indexPath):
        print("Hey look, it's not an Any! A new book: \(book.title)")
        tableView?.insertRows(at: [indexPath], with: .automatic)

    case let .delete(_ /*book*/, indexPath):
        print("A deletion, and it has a from-where? Finally!")
        tableView?.deleteRows(at: [indexPath], with: .automatic)

    case let .move(_ /*book*/, fromIndexPath, toIndexPath):
        print("Whoah, wait, I actually HAVE index paths? Both of them? Yay!")
        tableView?.moveRow(at: fromIndexPath, to: toIndexPath)

    case let .update(_ /*book*/, indexPath):
        print("It's almost like I'm actually using Swift and not Obj-C!")
        tableView?.reloadRows(at: [indexPath], with: .automatic)
    }
}

It also has properly typed sections and subscripting operators. Because, we are writing Swift, are we not?

As a further bonus, you get our workarounds for some misbehavior of Core Data that contradicts the documentation, like this one:

// Work around a bug in Xcode 7.0 and 7.1 when running on iOS 8 - updated objects
// sometimes result in both an Update *and* an Insert call to didChangeObject,
// … (explanation continues) …

Convenient store change listening

Our EntityMonitor<ManagedObjectType> makes it easy to listen to all changes for a given ManagedObjectType:

/* EXAMPLE: NOTIFYING WHEN A MOC SAVES AUTHOR CHANGES */
let authorMonitor = EntityMonitor<Author>(context: moc, entity: authorEntityDescription, frequency: .onSave)
let authorMonitorDelegate = AuthorMonitorDelegate()
authorMonitor.setDelegate(authorMonitorDelegate)


/* EXAMPLE: AUTHOR MONITOR DELEGATE */
class AuthorMonitorDelegate: EntityMonitorDelegate {
    func entityMonitorObservedInserts(
        _ monitor: EntityMonitor<Author>,
        entities: Set<Author>
    ) {
        print("inserted authors:", entities)
    }

    func entityMonitorObservedModifications(
        _ monitor: EntityMonitor<Author>,
        entities: Set<Author>
    ) {
        print("modified authors:", entities)
    }

    func entityMonitorObservedDeletions(
        _ monitor: EntityMonitor<Author>,
        entities: Set<Author>
    ) {
        print("deleted authors:", entities)
    }
}

A friendlier managed object context

Extension methods on ManagedObjectContext ensure saves happen on the right queue and make your life easier:

// Gotta catch 'em all
let allBooks = try Book.allInContext(moc)

// Or at least one of 'em
let anyBook = try Book.findFirstInContext(moc)

// Ah, forget it. Rocks fall, everyone dies.
try Book.removeAllInContext(moc)


// Blocking save, including up through parent contexts,
// on the appropriate queue.
try moc.saveContextToStoreAndWait()

Interested?

Check out the documentation!

For more details on the design methodology, read "Introducing the Big Nerd Ranch Core Data Stack."

Why "Stack"? Previously, the Core Data Stack provided a full, ready-made Core Data stack. Apple now provide that themselves in NSPersistentContainer, so we're free to focus on the other benefits listed above, and we have [deprecated][#sec:deprecations] our own stack in favor of Apple's.

Swift-Only: Note that the Core Data Stack is intended to be used from Swift. Any use you can make of it from Objective-C is by luck, not design.

Support

Big Nerd Ranch can help you develop your app, or train you or your team in Swift, iOS, and more. We share what we learn here on GitHub and in bookstores near you.

For questions specific to the Core Data Stack, please open an issue.

Minimum Requirements

Running

Apps using BNR Core Data Stack can be used on devices running these versions or later:

  • macOS 10.10
  • tvOS 9.0
  • iOS 8.0

Building

To build an app using BNR Core Data Stack, you'll need:

  • Xcode 8.0
  • Swift 3.0

Usage

Type Safe Monitors

Fetched Results Controller

FetchedResultsController<T> is a type safe wrapper around NSFetchedResultsController using Swift generics.

Example

See BooksTableViewController.swift for an example.

Entity Monitor

EntityMonitor<T> is a class for monitoring inserts, deletes, and updates of a specific NSManagedObject subclass within an NSManagedObjectContext.

Example

See EntityMonitorTests.swift for an example.

NSManagedObject Extensions

Adds convenience methods on NSManagedObject` subclasses. These methods make fetching, inserting, deleting, and change management easier.

Example

let allBooks = try Book.allInContext(moc)
let anyBook = try Book.findFirstInContext(moc)
try Book.removeAllInContext(moc)

Installation

Installing with Carthage

Add the following to your Cartfile:

github "BigNerdRanch/CoreDataStack"

Then run carthage update.

In your code, import the framework as CoreDataStack.

Follow the current instructions in Carthage's README for up to date installation instructions.

Installing with CocoaPods

Add the following to your Podfile:

pod 'BNRCoreDataStack'

You will also need to make sure you're opting into using frameworks:

use_frameworks!

Then run pod install.

In your code, import the framework as BNRCoreDataStack.

Contributing

Please see our guide to contributing to the CoreDataStack.

Debugging Tips

To validate that you are honoring all of the threading rules it's common to add the following to a project scheme under Run > Arguments > Arguments Passed On Launch.

-com.apple.CoreData.ConcurrencyDebug 1

This will throw an exception if you happen to break a threading rule. For more on setting up Launch Arguments check out this article by NSHipster.

Excluding sensitive data from iCloud and iTunes backups

The default store location will be backed up. If you're storing sensitive information such as health records, and perhaps if you're storing any personally identifiable information, you should exclude the store from backup by flagging the URL on disk:

/* EXAMPLE: EXCLUDING A FILE FROM BACKUP */
var excludeFromBackup = URLResourceValues()
excludeFromBackup.isExcludedFromBackup = true

let someParentDirectoryURL: URL = …
var storeFileURL = URL(
    string: "MyModel.sqlite",
    relativeTo: someParentDirectoryURL)!
try! storeFileURL.setResourceValues(excludeFromBackup)

You then need to point your persistent container at that location:

/* EXAMPLE: AIMING YOUR CONTAINER AT A SPECIFIC URL */
// Ensure parent directory exists
try! FileManager.default.createDirectory(
    at: storeFileURL.deletingLastPathComponent(),
    withIntermediateDirectories: true)

// Configure the persistent container to use the specific URL
container.persistentStoreDescriptions = [
    NSPersistentStoreDescription(url: storeFileURL),
    ]

Prior to NSPersistentContainer, this would be done with Core Data Stack by:

/* EXAMPLE: DEPRECATED CORE DATA STACK WITH STORE URL */
CoreDataStack.constructSQLiteStack(
    withModelName: "MyModel",
    withStoreURL: storeFileURL) { result in
        switch result {
        case .success(let stack):
            // Use your new stack

        case .failure(let error):
            //handle error ...
        }
    }

Deprecations

iOS 10.0 / macOS 10.12

  • Deprecated: The CoreDataStack class itself.
    • Replacement: Use Apple's NSPersistentContainer instead. The [Container Example](./Container Example/README.md) demonstrates how to use NSPersistentContainer with the BNR Core Data Stack.
  • Deprecated: The CoreDataModelable protocol.
    • Replacement: Use the type method NSManagedObject.entity(). Many of the convenience methods formerly available on CoreDataModelable are now offered by BNR Core Data Stack as extension methods on NSManagedObject as FetchHelpers.

More Repositories

1

expandable-recycler-view

[DEPRECATED]
Java
1,215
star
2

Freddy

A reusable framework for parsing JSON in Swift.
Swift
1,090
star
3

Deferred

Work with values that haven't been determined yet.
Swift
421
star
4

developing-alexa-skills-solutions

JavaScript
232
star
5

why_elixir

Selling points for Elixir / Phoenix
155
star
6

Typesetter

Android tool to help display changes to text positioning.
Java
150
star
7

iOS7Demos

Some short demos of new stuff in iOS 7
Objective-C
145
star
8

BNRDynamicTypeManager

Objective-C
127
star
9

android-bluetooth-testbed

Provides a Server and Client example for understanding Bluetooth Low Energy on Android
Java
97
star
10

music-frequency-d3

A music frequency visualizer using D3.js
JavaScript
93
star
11

rust-ios-app-part-1

Let's Build an iOS App in Rust, part 1
Swift
81
star
12

iOS8Demos

iOS 8 release day demonstrations
Objective-C
77
star
13

AndroidCourseResources

Resources for our Android Bootcamp.
Java
75
star
14

stockwatcher

stockwatcher, a modern android development stack showcase
Java
62
star
15

alexa-airportinfo

Node.js src for the article "Developing Alexa Skills Locally with Node.js"
JavaScript
61
star
16

bnns-cocoa-example

An example of a neural network trained by tensorflow and executed using BNNS
Objective-C
59
star
17

type-erasure-playgrounds

Code to accompany Swift Symposium Talk - https://www.youtube.com/watch?v=d_FJHBl5ohU
Swift
56
star
18

Result

Small Swift library for Result type
Swift
47
star
19

android-listview-custom-view

Example of using a custom view subclass with ListView and a custom Adapter
Java
45
star
20

linette

Custom lint checks for Android development.
Java
42
star
21

rust-ios-app-part-3

Let's Build an iOS App in Rust, part 3
Swift
31
star
22

iOS3eSolutions

Solutions to iOS Programming: The Big Nerd Ranch Guide, 3rd Edition.
Objective-C
31
star
23

doze-logger

Simple app thrown together to help demonstrate the effects of doze mode on your background schedulers.
Java
30
star
24

ScriptableTextEditor

A simple Cocoa text editor that demonstrates creating a plugin system in Python.
Objective-C
29
star
25

DeferredTCPSocket

DeferredTCPSocket is a Swift framework for asynchronous TCP networking.
Swift
28
star
26

macOS-bootstrap

A bootstrap script for configuring machine to develop iOS, tvOS, and macOS apps
Shell
25
star
27

BNR-blog-cameraxMlkit

Sample project associated with blog post on using Firebase MLKit with CameraX.
Kotlin
21
star
28

blog-ios-xcui-todo

Demonstrates using Xcode 7's new UI testing support
Swift
20
star
29

BNRun-SiriKit-Sample

Sample code for the SiriKit blog post
Swift
19
star
30

Roger

Roger is jolly. By Franklin.
Objective-C
18
star
31

controllers-for-tvOS

Sample app for tvOS that reads game controllers
Swift
18
star
32

jenkins-android-signing

[DEPRECATED] Jenkins Plugin for signing Android APKs
Java
18
star
33

alexa-account-linking-service

Code example for the Oauth account linking example for an alexa skills
JavaScript
17
star
34

tensorflow-cocoa-example

Using tensorflow inside a desktop Cocoa application
Python
17
star
35

ViewRotationTest

A demonstration of various techniques for view rotation in Cocoa Touch.
Objective-C
17
star
36

BlappyFird

Demo clone of a popular game
Swift
16
star
37

rust-ios-app-part-2

Let's Build an iOS App in Rust, part 2
Swift
12
star
38

rust-ios-app-part-4

Let's Build an iOS App in Rust, part 4
Rust
12
star
39

react-testing-workshop

Starter Code for BNR React Testing Workshop
JavaScript
11
star
40

BNRXIBCell

A UITableViewCell subclass, intended to be subclassed, to forward action messages from cell subviews to a controller.
Objective-C
11
star
41

opencv-cocoa-example

An example of using OpenCV in a Cocoa application
Objective-C++
10
star
42

BNR-blog-motionlayout

Sample project associated with blog post on using MotionLayout and MotionEditor.
Kotlin
9
star
43

semaphorejs

A functional-style Semaphore for managing concurrent access to a resource. For JavaScript.
JavaScript
9
star
44

RanchWeather

A demo app written in Swift 3 to demonstrate different code patterns.
Swift
9
star
45

android-securebank

Code example companion for the DevNexus talk: "Keeping Android Secrets Secure with Fingerprint Authentication and the Keystore"
Java
8
star
46

ember-engine-example

Ember-Engine Example: Large Company Site from Blogpost
JavaScript
8
star
47

dexie-fulltextsearch

Full text search for IndexedDB databases, powered by Dexie.
JavaScript
8
star
48

id3-meta

A metadata parser for ID3v2 formatted MP3s, in JavaScript.
JavaScript
8
star
49

SyncAdapterDemo

Experiment with android sync adapters. Getting them to work with a remote rails server to sync book error data.
Java
8
star
50

iOS-Responsive-UI-Sample

3 examples examining modern techniques for making iOS app UI accessible and responsive.
Swift
7
star
51

OpenParentApplicationDemo

Demo of openParentApplication method of WatchKit
Swift
7
star
52

doktor-demo

A simple Ktor demo app. Write Kotlin on the server.
Kotlin
7
star
53

BNRLoupe

A magnifying loupe for images that displays one-for-one pixel information for the point under the finger.
Objective-C
7
star
54

permission-manager

Easily and seamlessly ask for Android runtime permissions.
Java
7
star
55

alexa-cakebaker

JavaScript
7
star
56

cocoa-conf-stack-views

@cbkeur's CocoaConf talk on UIStackViews
Swift
6
star
57

character-data-api

Kotlin Ktor backend for the Samodelkin Android Client
Kotlin
6
star
58

meta_elixir

Elixir
5
star
59

cleaning-up-messy-chaining-code-in-swift

Swift
5
star
60

ShindigSheriff

Event Manager Manager, Mr. Manager
Ruby
5
star
61

auto-layout-mastery-conference-talk-2016

Step's Auto Layout Mastery talk about Priorities
Swift
4
star
62

upfront

Go
4
star
63

ottergram-solutions

Sample of how we could organize solutions for the 4 apps in the frontend book.
4
star
64

FocusWheel

A tvOS app for a two-part Big Nerd Ranch Blog Post on collection view layouts and the focus engine
Swift
4
star
65

Github-Issues-Reader

A super cool app for reading github issues that definitely doesn't already exist
Swift
3
star
66

cocoa-layout-instrument-demo

Sample files to accompany a blog post on the Cocoa Layout Instrument.
Swift
3
star
67

BNR-react-native-style-queries

Declarative responsive design for React Native.
JavaScript
3
star
68

bootstrap

Ruby
3
star
69

SocialDistancingSimulator

A SpriteKit-based social distancing simulator
Swift
3
star
70

auto-layout-priorities-2016

Demo project that accompanies Auto Layout Mastery Conference Talk on priorities from Step Christopher
Swift
3
star
71

alfred_reflecticle_extension

Ruby
2
star
72

KotlinConf2023-TestRefactor

Kotlin 2023 Testing Workshop Template
Kotlin
2
star
73

tacostand

A sample project for practice using Rails applications
Ruby
2
star
74

authorizing-jsonapi-resources

A tutorial for protecting private resources in JSONAPI::Resources.
Ruby
2
star
75

BNR-blog-React-to-Vue-react-simple

React project for comparison to Vue for blog entry
JavaScript
2
star
76

vapor-testing-example

Demonstrates testing techniques in the Vapor framework
Swift
2
star
77

bnr-webhooks

Big Nerd Ranch's webhook layer for inter-service communication.
Ruby
2
star
78

cardo

DSL for creating recurring Pivotal Tracker stories
Ruby
2
star
79

ember-engine-external-admin

Ember-Engine Example: External Admin
JavaScript
2
star
80

html5-course-ajax-dummy

Just a dummy AJAX endpoint for the HTML5 course.
Ruby
2
star
81

CrashTest

UIKit Dynamics Playground
Objective-C
2
star
82

KotlinConf2023-ContextReceivers

The supporting code for Bryan Sills's talk titled "Introduction To Context Receivers" at KotlinConf 2023
Kotlin
2
star
83

constraints_experiments

Some experiments for a blog post
Elixir
2
star
84

BNR-graphql-java-samples

Holds some meaningful examples of building GraphQL API's in Java.
Java
2
star
85

nybblr-javascript-book-walkthrough

My run through of the frontend dev book.
JavaScript
2
star
86

AtomicSwift

Objective-C
1
star
87

BNR-blog-React-to-Vue-vue-simple

Vue project for comparison to React for blog entry
Vue
1
star
88

gatsby-twenties-tribute

A tribute page to the twenties built with Gatsby.js
CSS
1
star
89

ml-boston-pricer

A repo for hosting the demo project for BNR's Core ML blog post.
Swift
1
star
90

service-object-testing-example

Java
1
star
91

devnulldb

:trollface: MySQL server
JavaScript
1
star
92

clash_of_the_coders

Site for Clash of the Coders scoreboard
Ruby
1
star
93

omniauth-stable

Omniauth Strategy for Stable
Ruby
1
star
94

KotlinConf2023-ComposeForDesktop

The supporting code for Bryan Sills's codelab titled "Compose For Desktop" at KotlinConf 2023
Kotlin
1
star
95

RubyCourseResources

Files and helpful info associated with the Ruby portion of our Beginning Ruby on Rails Bootcamp.
1
star
96

carkeeper

Sample code accompanying @lyricsboy's talk "Applying the Single Responsibility Principle in iOS"
Objective-C
1
star
97

ios-ci-example

Example Distribution for the Travis CI Integration of a sample app
Objective-C
1
star
98

TableCollectionView

Handful of classes that make it easier to use a Collection View as a replacement for a Table View
1
star
99

iOS-Win8-Seminar-Public

Files for use in the exercises of the "Windows Store Development for iOS Developers" seminar.
1
star
100

iOSCourseResources

1
star