Giter Club home page Giter Club logo

core-data's People

Contributors

floriankugler avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

core-data's Issues

Question: Extensions in embedded framework

Hi,

There are several extensions to Foundation types in Utilities.swift, which have no explicit access control specifier.

When I try to set up a project with an embedded framework, which contains an extension I get a build error, unless I specify it explicitly public.

i.e.
Type 'NSURL' has no member 'documentsURL'.

I couldn't find a clue how the build configuration is different when it comes to linking the embedded frameworks in this project. It builds fine without the access control specifiers. How is this possible?

Thanks for any pointer!

Migration.swift: question about NSProgress management

Hi,

Looking at the code in Migration.swift, I was wondering why the migrationProgress?.resignCurrent() call is done partway through the for step in steps loop as opposed to at the bottom of the loop, after the actual data migration for each step is done?

Crash when instantiating FetchedResultsDataProvider

I was trying the code to use Core Data and Table Views, and I get a crash just in iOS 7:

#0
Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_PROTECTION_FAILURE 0x00000000004266e0

Crashed: com.apple.main-thread
0  libswiftCore.dylib             0x6dbd22 swift_initClassMetadata_UniversalStrategy + 439
1  MyApp                          0xab284 protocol witness table accessor for <A where ...> FetchedResultsDataProvider<A> (FetchedResultsDataProvider.swift)
2  libswiftCore.dylib             0x6dcdbf swift_getGenericWitnessTable + 888
3  libswiftCore.dylib             0x6dccb5 swift_getGenericWitnessTable + 622
4  libswiftCore.dylib             0x6daee7 swift_getResilientMetadata + 382
5  libswiftCore.dylib             0x6db03f swift_getGenericMetadata3 + 68

My table view controller code looks like this:

private func setupTableView() {
   tableView.registerNib(UINib(nibName: "Cell", bundle: nil), forCellReuseIdentifier: "Cell")

   let request = Event.sortedFetchRequest
   request.fetchBatchSize = 20
   request.returnsObjectsAsFaults = false

   let frc = NSFetchedResultsController(fetchRequest: request, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
   let dataProvider = FetchedResultsDataProvider(fetchedResultsController: frc, delegate: self)
   dataSource = TableViewDataSource(tableView: tableView, dataProvider: dataProvider, delegate: self)
}

CoreData Error: Invalid generation token: this persistent store coordinator does not have any of the referenced stores

I'm getting this CoreData error in my crash reporter but I'm unable to reproduce it.

The crashing lines:

The error message:

Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=134060 "A Core Data error occurred." UserInfo={Reason=Invalid generation token: this persistent store coordinator does not have any of the referenced stores}: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang_Fall2018/swiftlang_Fall2018-1000.11.42/src/swift/stdlib/public/core/ErrorType.swift, line 184

I would like to decipher error message. Does Invalid generation token refers to NSQueryGenerationToken? Is the error part of conflict resolution process?

I guess the only thing different in my implementation is that I didn't use custom merge policy but mergeByPropertyStoreTrumpMergePolicyType.

Build error "Switch must be exhaustive" in file CloudKit+Sync.swift

Just purchased your book thank you for writing this I am finding it very helpful already.

I've downloaded "core-data-master" from GitHub, updated all settings per instructions including addition of Mood Record Type in CloudKit Dashboard, note following error...

In file CloudKit+Sync.swift

under
var permanentCloudKitError: Bool { }
and
switch errorCode { }
note the build error

Switch must be exhaustive.

Edit: Xcode offered the following fix..
case .assetNotAvailable

There are a few other compiler warnings but this seems to be the only problem stopping the project from running.

Sorry this is my first attempt at using GitHub despite being a member for years and I've never involved myself in a project before so forgive me if my comments are not very well set out. Happy for some constructive criticism.

switchmustbeexhaustive

Running first time ...moody Failed to create file at ModelVersionType.swift

Running first time I receive crash ...moody Failed to create file. This happens in the ModelVersionType.swift in the extension NSManagedObjectContext {...} It crashes on line let psc = NSPersistentStoreCoordinator(...)

Any ideas? I have made all of the changes for the CloudKit setup.
Thank you.

CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///Users/name/Library/Developer/CoreSimulator/Devices/50A111d9-B60C-49D0-d037-CAD21D8G96CC/data/Containers/Data/Application/3DE20E67-C970-4A56-A138-538D8F0420A6/Documents/YnBsaXN0MDDUAQIDBAUGCQpYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hvdmGyVCR0b9ASAAGGoKIHCFUkbnVbbC8QFBQ3L/RDZAr0ISZbweTAix7l2EpRXxAPTlNLZXllZEFyY2vpdmCy0RsMEHJvb3SAAQgRGiMtMjc6TFdpbHEAAAAAAAABAQAAAAAAAAANAAAAAAAAAAAAAAAAAAAAcw==.moody options:(null) ... returned error Error Domain=NSCocoaErrorDomain Code=512 "The file couldn’t be saved." UserInfo={reason=Failed to create file; code = 2} with userInfo dictionary {
    reason = "Failed to create file; code = 2";
}
fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=512 "The file couldn’t be saved." UserInfo={reason=Failed to create file; code = 2}: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-700.1.101.15/src/swift/stdlib/public/core/ErrorType.swift, line 50
extension NSManagedObjectContext {
    public convenience init<Version: ModelVersionType>(concurrencyType: NSManagedObjectContextConcurrencyType, modelVersion: Version, storeURL: NSURL, progress: NSProgress? = nil) {
        if let storeVersion = Version(storeURL: storeURL) where storeVersion != modelVersion {
            migrateStoreFromURL(storeURL, toURL: storeURL, targetVersion: modelVersion, deleteSource: true, progress: progress)
        }

        let psc = NSPersistentStoreCoordinator(managedObjectModel: modelVersion.managedObjectModel())   // CRASH HAPPENS HERE...

        try! psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil)
        self.init(concurrencyType: concurrencyType)
        persistentStoreCoordinator = psc
    }
}

Crash on adding new moody after delete

Here is scenario: After adding new new mood, I try to delete it and then add new one. It crash at:

public func saveOrRollback() -> Bool {
    do {
        try save()
        return true
    } catch {
        rollback()
        return false
    }
}

I do some debugging by lldb with po $arg1 and it say: Constraint violation

Xcode 9.2, Swift 4 Compile Errors

The CapureSession.swift file does not compile. the setup function should become:

fileprivate func setup() { #if !IOS_SIMULATOR session.sessionPreset = AVCaptureSession.Preset.photo let discovery = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back) if let camera = discovery.devices.first { let input = try! AVCaptureDeviceInput(device: camera) if session.canAddInput(input) { session.addInput(input) } } photoOutput = AVCapturePhotoOutput() if self.session.canAddOutput(photoOutput) { self.session.addOutput(photoOutput) } #endif }

This is after accepting Xcode's automatic fixes.

question about extending CollectionViewDataSource

Not sure if this is the right forum where readers of your book can discuss questions, but I'm giving it a shot anyway. :)

I’m using your CollectionViewDataSource generic class with a view controller and I’m stuck trying to extend it. My view controller needs to respond to one of the optional UICollectionViewDataSource methods not implemented in CollectionViewDataSource. I don’t want to add it to CollectionViewDataSource because not all VCs will need to implement it. So I thought I could just extend the class with a where restriction for my particular view controller:

extension CollectionViewDataSource where Delegate: MyViewController {
    func collectionView()   // my extra method goes here
}

This compiles and seems like it should work based on some playground experimentation, but my method in this extension is never called by the CollectionView.

Any suggestions to make this work, or an alternative approach?

-Rich

Purpose of `removeAllObserverTokens` in `SyncCoordinator`?

Hello!

I've been reading and finding very useful the book. Thanks so much for writing it! We are incorporating some aspects of it into an app we are working on. It's been very useful, and we found it pretty straight-forward to add a separate remote type.

I have a question:
In the SyncCoordinator, removeAllObserverTokens() is called in the tearDown() method. It seems like this is a no-op, doing nothing at all (except removing tokens from the private collection of tokens). Am I correct in this understanding? Was this simply added for potential future extensibility?

Xcode 9+ NSManagedObject Auto Class Generation

I'm not sure how else to note this, but in Xcode 9+ NSManagedObject entities are (by default) set to have their class autogenerated. This is a departure from the way things were done (manual generation via the Editor > Create NSManagedObject Subclass ... as noted in the Managed Object Subclasses section of chapter 1 of the book. It might be worth it to note the difference and how to set the automatic code generation to none.

Purpose of Explicit `setup()` in `SyncCoordinator`?

Why not just perform these operations in the init method? I'm not sure I see the utility of this pattern. Is this simply to protect against someone initializing a SyncCoordinator at the same time on separate threads?

Receiving Subscription Update Events Before Uploader Has a Chance to Finish Uploading

Howdy!

I've really been enjoying the book and the sync codebase, and am building off it for our own project.

I'm building a remote type that uses Firebase instead of CloudKit. One thing I encountered is the following:

  1. Object A created locally, recognized by Uploader Change Processor. Object A has a nil remoteIdentifier until it is successfully uploaded
  2. Upload begins
  3. Upload succeeds, but the completion block has not been fired and our app has not yet been notified of a successful upload
  4. Object Added Change Subscription from Firebase notifies the app that we have a new object that was added to the remote destination
  5. App adds the object from step (4) to the local store
  6. Successful upload from step (2) returns to app, and remoteIdentifier is assigned to the local object created in step (1)

Expected result: we should have one object that has been successfully stored in the remote destination

Actual result: we have created two local objects with identical remoteIdentifier values, and there is one object at the remote destination.

I'm not sure this scenario is possible with the Moody sample app, or with CloudKit at all, because of the way remote push updates work with CloudKit. But with the way I added Firebase subscriptions / push updates, it's definitely happening for me.

Is this a scenario you contemplated or experienced at all during your work on the sample app? Do you have any ideas about how this could be avoided?

Relevance of `fault` in `DelayedDeletable` / `markForLocalDeletion()`

I've got a question about DelayedDeletable and two-step deletion from the book.

In markForLocalDeletion(), the first line of the method is:

guard fault || markedForDeletionDate == nil else { return }

I'm not sure why the value of fault matters here, and I can't find any explanations in the book.

ManagedObjectType requires an NSManagedObjectContext property

In working through the first chapter, I was building the ManagedObjectObservable (p. 45) to handle background changes of objects. The ManagedObjectObservable(object: mood) method uses the mood.managedObjectContext property from the ManagedObjectType protocol.

However, when creating the ManagedObjectType protocol (p. 33), it looks like the following:

public protocol ManagedObjectType: class {
    static var entityName: String {get}
    static var defaultSortDescriptors: [NSSortDescriptor] {get}
}

The final protocol includes a reference to an NSManagedObjectContext.

Why do all ManagedObjects need a reference to the context they belong in? Is it only for the MangedObjectObservable?

I'm sure there is an important reason for it, I just didn't see any discussion of it at the first point it was required.

Thanks!

Update Sync Shared Code

More a comment than an issue. I'm just reading through the book and I'm about half way through. First off, EXCELLENT work. Learning a lot and really happy to understand the guts of Core Data better.

I am looking at pulling out pieces into a sample app for more hands on learning and I'm wondering if most of the classes in MoodySync should be considered part of the "SharedCode". A lot of it isn't really app specific, but more core pieces of the sync process.

The classes I'm talking about are all the classes in the "Sync Engine" folder and all classes in "Helpers" folder. I see why the ChangeProcessors and the Remote code is application specific.

Thoughts?

Issue on Xcode 8.1 DefaultManagedObjectType

Getting following issue while compiling -

While emitting IR SIL function @_TToZFE22 DefaultManagedObjectTypeg17aDefaultPredicateCSo11NSPredicate for 'defaultPredicate' at /ManagedObject.swift:23:14

If I comment following code it works -

extension DefaultManagedObjectType {
 static var defaultPredicate: NSPredicate {
    return NSPredicate(value: true)
  }
}

Crash when update last row

When there are updates in collection view data source which contains delete(any row) and update for last row there is a crash when accessing object using frc. The solution to the problem is to use newIndexPath for updates #42

ManagedObjectObserver issues

Have you verified if ManagedObjectObserver works? I added logs throughout the parsing the notification's user info, and it fails to cast to Set<ManagedObject> but succeeds as NSSet for me

Update: It succeeds to cast to Set<NSManagedObject>. I'm pretty sure I conform to the ManagedObject protocol though for this object.

Update 2: Figured it out. I was conforming to the ManagedObjectType protocol but all my types were still NSManagedObject's not ManagedObject's

Initial ViewController Loading twice?

In AppDelegate the Main-Storyboard and initial VC is initiated and configured.
Also in the App-Info.plist the App is configured to automatically load the Main-Storyboard [with its initialViewController].

So my Question: Is the Main-Storyboard and ViewController loaded twice?

Crash on update in CollectionViewDataSource

I'm experimenting with the code in a slightly different context (so there may be no bug in the example app), but I believe there's a lurking bug in the implementation of

processUpdates(updates: [DataProviderUpdate<Data.Object>]?)

if an update is received for an object (say via the FetchedResultsDataProvider invoking it's delegate - DataProviderDelegate.dataProviderDidUpdate(updates: [DataProviderUpdate<Object>]?)) for an object which is known and in the model, but has become off-screen, then inside the batch update's .Update(let indexPath, let object): clause, then the line

guard let cell = self.collectionView.cellForItemAtIndexPath(indexPath) as? Cell else { fatalError("wrong cell type") }

will fail because self.collectionView.cellForItemAtIndexPath(indexPath) can return nil for cells which are out of range, or simply because they're offscreen. If there's no cell, it's likely the right approach is to check for a valid cell before proceeding and retain the type check on the cell type for safety (i.e.. split out the nil check from the type check)... something like

                case .Update(let indexPath, let object):
                    // Note: cell can be offscreen and therefore nil
                    if let c = self.collectionView.cellForItemAtIndexPath(indexPath) {
                        guard let cell = c as? Cell else { fatalError("wrong cell type") }
                        cell.configureForObject(object)
                    }

Implementing UITableViewDataSource methods in TableViewDataSource

I wanted to implement swipe-to-delete in one of my UITableViewControllers. This VC displays a table of objects that inherit from ManagedObject and implement ManagedObjectType. To do so, the VC's dataSource needs to implement the tableView(tableView: commitEditingStyle: forRowAtIndexPath:) method, and handle the .Delete case. To delete I simply do the following:

In TableViewDataSource.swift

// MARK: UITableViewDataSource methods
    func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {

        switch editingStyle {
        case .Delete:
            let deleted = dataProvider.objectAtIndexPath(indexPath) as! ManagedObject
            print("Deleted: \(deleted)")
            deleted.delete()

        default: break
        }
    }

delete() is simply:

In ManagedObject.swift

/// ManagedObject - protocol extension that implements defaults
extension ManagedObject {
    public func delete() {
        managedObjectContext?.performChanges({ 
            self.managedObjectContext?.deleteObject(self)
        })
    }
}

Because the TableViewDataSource does not have access to the NSManagedObjectContext, but the ManagedObject does, I am required to cast down to ManagedObject, as the TableViewDataSource's where clause does not actually require ManagedObject.

Is there a better way to handle this? Obviously, I would implement a guard in the cast, but I was wondering if there were a better way to implement deleting an object in this way? Without access to the moc, and without access to the tableView's delegate it seems I have to require some type constraints on the Object to be able to delete.

for reference, the TableViewDataSource generic requirements

class TableViewDataSource<Delegate: DataSourceDelegate, Data: DataProvider, Cell: UITableViewCell where Delegate.Object == Data.Object, Cell: ConfigurableCell, Cell.DataSource == Data.Object>: NSObject, UITableViewDataSource

Opening `.omo` file directly considered harmful

First of all, thanks for the book! It's been extremely helpful to us working with Core Data in our app.

We recently got an email from Apple advising us that opening the .omo file for a managed object model is not supported, since the file format can change from release to release:

We are reaching out to you regarding your app, XXXX. We’ve identified an issue for this app on devices running the iOS 11 beta.

We noticed you are opening models by passing the URL for the optimized model to -[NSManagedObjectModel initWithContentsOfURL:]. This is unsupported as the format for .omo files can change in a non-backwards-compatible fashion at any time.

Please address this issue to avoid any problems once iOS 11 is released. If you need further assistance please follow this link: https://developer.apple.com/support/technical/

For your reference we’ve tracked this issue in bug ID 32238005.

You may want to update the sample code and next revision of the book to reflect this guidance.

Utilities.swift Binary Operator Error

When attempting to run Sample Project Chapter 1.1 and 1.2 I get the following error on the Utilities.swift file:

Binary operator '===' cannot be applied to operands of type 'Self.Element' and 'AnyObject'

There is also a warning on ColorSpaceConversion.swift:

Initializer for struct 'ARGBPixel_s' must use "self.init(...)" or "self = ..." because the struct was imported from C

Compiler error for insertObject method

I'm currently reading the Core Data book (which I really really like) and I'm trying to apply what I'm learning on a sample project of mine.

However, I'm stuck for the past 2 days trying to fix an issue I can't seem to be able to tackle.

I have just added the insertObject<A: ManagedObject where A: ManagedObjectType>() -> A method in the NSManagedObjectContext extension as seen here.

When I try to call it from my model class though, for example like this (as seen here):

public static func insertIntoContext(moc: NSManagedObjectContext, image: UIImage) -> Mood {
        let mood: Mood = moc.insertObject()
        mood.colors = image.moodColors
        mood.date = NSDate()
        return mood
    }

I get a compiler error that reads: Missing argument for parameter #1 in call. If I understand the problem correctly, the compiler tries to call the public func insertObject(object: NSManagedObject) found in NSManagedObjectContext instead of the one I just added.

I have tried writing the CoreDataHelpers files manually and creating a new target for them as demonstrated in the Moody project but without any luck.

Any help / suggestions would be much appreciated.

syncContextDidSave calling notifyAboutChangedObjectsFromSaveNotification

In https://github.com/objcio/core-data/blob/master/Moody/MoodySync/SyncContextOwner.swift#L65 , does anyone know why the notifyAboutChangedObjectsFromSaveNotification is called?

The sync context is saved and then the changes are merged into the main managed object context in the ContextOwnerType's syncContextDidSave function. It seems that since the changes are coming from the sync context, that we shouldn't have to basically call performLocalChanges in notifyAboutChangedObjectsFromSaveNotification.

Thanks for any help anyone can provide!

Swift 3 errors in multiple Core Data Helper files

Hello,
A lot of the code from the Core Data book seems to be broken in Swift 3 (I made the mistake of being on the bleeding edge of converting); I think I’ve been able to fix a lot of it, but as someone who is still learning, I’m struggling with some of the errors that XCode is spitting out.

Is there an update planned to the code posted on GitHub?

The specific areas I’m stumped by are:

In file Collection+CoreDataExtensions.swift, in the fetchObjectsThatAreFaults function, XCode complains: “Generic parameter ‘ResultType’ could not be inferred” for the line:

    let request = NSFetchRequest()

Then, in file NSManagedObjectContext+Observers.swift, the ContextDidSaveNotification function has the error: "Ambiguous reference to member ‘joined()’” in the line:

    return components.joined(separator: " ")

I’ve managed to (I think) fix the ~20+ other errors that appeared and prevented successful build, but no matter what I do or think I should do to resolve the two above, XCode is not happy, and I’ve scoured the internet to try and find some leads to solutions, but have come up empty.

Thanks for any info you can provide.

NSPersistentContainer background context merge changes

NSPersistentContainer's newBackgroundContext() documentation states that the created context is setup to automatically consume didSave notifications. Yet, the syncContext in SyncContextOwner still merges changes manually on the main context's didSave.

Is it necessary?

Incremental tags per chapter?

First of all, I just want to say that I am very impressed with the book, and am very satisfied. I'm consistently impressed (and challenged) by the quality of the code Objc.io has produced over the years.

As I'm working through the book, however, it is difficult to come to this project and maintain a context for what is currently being developed. Would it be possible to see the project not in a final state, but as it is built up and refactored?

I understand that this is no small request. I think the learning potential of such an undertaking would be relatively huge, though.

ModelBuilder.swift Compile error in Xcode 8.1

function transformableType

ValueTransformer.registerTransformerWithName(transform.name, transform: t, reverseTransform: r)

error:

Cannot convert value of type '(A?) -> Data?' to expected argument type '(_?) -> _?'

Error with NSFetchedResultsController. -copyWithZone: cannot be sent to an abstract object of class NSPredicate: Create a concrete instance!

I'm getting an interesting crash while running the setupTableView function on the following line:

let frc = NSFetchedResultsController(fetchRequest: request, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

Just before I instantiate the NSFetchedResultsController I run a check to see if the ManageObjectContext exists and it does. Then I step into the NSFetchedResultsController object and it sets the managedObjectContext from my controller and then immediately crashes.

Any insight would be appriciated.

I get the following error:

'NSInvalidArgumentException', reason: '*** -copyWithZone: cannot be sent to an abstract object of class NSPredicate: Create a concrete instance!'

[edit: removed stack trace, see comment below]

TableViewDelegate ?

I hope this is an ok place to ask questions about the book. Really enjoying it so far and learning a lot.

Would it make sense to use a TableViewDelegate similar to TableViewDataSource for functions such as didSelectRowAtIndexPath, willDisplayCell, etc using the ConfigurableCell protocol ? Or does it make more sense to just keep these functions inside the UITableViewController subclasses ?

Fragility of using ubiquityToken?

Quick question regarding the use of ubiquityToken as the file name for the persisted store. Won't that mean that if the user changes iCloud account or logs out they will lose all of their data?

I see the reasoning for this, but it seems like if the phone is not wiped it's a fair assumption that the same person is still using the phone.

Xcode 9.3, swift 4.1 compile error

core-data-master/SharedCode/Utilities.swift:47:30: Binary operator '===' cannot be applied to operands of type 'Self.Element' and 'AnyObject'

Why is notifyAboutChangedObjects called when sync context did save?

When we receive a did-save notification, we call notifyAboutChangedObjects(from notification:), which, in turn, calls processChangedLocalObjects(_:). That method will then distribute the objects to all change processors

Calling notify... happens on did-save notifications for both MOCs (view and sync).

I see why this is done for the view context; after merging the changed MOs into the sync context, we want to send them along to the change processors where presumably they will be uploaded to CloudKit by MoodUploader.

But, I do not understand why notify... is called when the sync MOC did-save. The remap calls should be mostly a no-op; there's an early return:

guard unmappedMO.managedObjectContext !== context else { return unmappedMO }

I believe the change processors are also a no-op since there's nothing more do download or upload. Am I correct about the no-op on the change processors? Is this by design? Why?

Aside: Could there be situations where saves are called back-to-back and an upload change processor didn't finalize the Mood upload by setting its remoteIdentifier property?

Setting Up Stack issue

Your book on page 20, which details setting up the Core Data stack, mentions a line of code:
private let StoreURL = NSURL.documentsURL.URLByAppendingPathComponent("Moody.moody")

This line can't compile because there's nothing inside "NSURL" called documentsURL.

Question: Confused with one place in SyncCoordinator

fileprivate func fetchLocallyTrackedObjects() {
        self.perform {
            // TODO: Could optimize this to only execute a single fetch request per entity.
            var objects: Set<NSManagedObject> = []
            for cp in self.changeProcessors {
                guard let entityAndPredicate = cp.entityAndPredicateForLocallyTrackedObjects(in: self) else { continue }
                let request = entityAndPredicate.fetchRequest
                request.returnsObjectsAsFaults = false
                let result = try! self.syncContext.fetch(request)
                objects.formUnion(result)
            }
            self.processChangedLocalObjects(Array(objects))
        }
    }

In SyncCoordinator, since each ChangeProcessor only care about their own tracked objects fetched from cp.entityAndPredicateForLocallyTrackedObjects(in:)
Why here union them together and send to every ChangeProcessor

I've changed it to the code below and it works well.
So what's the purpose or advantage of the above one?

fileprivate func fetchLocallyTrackedObjects() {
        self.perform {
            // TODO: Could optimize this to only execute a single fetch request per entity.
            for cp in self.changeProcessors {
                guard let entityAndPredicate = cp.entityAndPredicateForLocallyTrackedObjects(in: self) else { continue }
                let request = entityAndPredicate.fetchRequest
                request.returnsObjectsAsFaults = false

                let result = try! self.syncContext.fetch(request)

                self.processChangedLocalObjects(result, using: cp)
            }
        }
    }

Update fails if the cell is not visible

If the UICollectionViewCell being updated is not visible, the update will trigger wrong cell type:

case .update(let indexPath, let object):
    guard let cell = self.collectionView.cellForItem(at: indexPath) as? Cell else { fatalError("wrong cell type") }
    self.delegate.configure(cell, for: object)

https://github.com/objcio/core-data/blob/master/Moody/Moody/CollectionViewDataSource.swift#L69-L70

I'm sure there must be a reason, but why not use this instead:

case .update(let indexPath, let object):
    self.collectionView.reloadItems(at: [indexPath])

FetchedResultsDataProvider cannot be invoked error

Going through the first chapter, I am getting the following error when creating the dataProvider in MyTableViewController:

let dataProvider = FetchedResultsDataProvider(fetchedResultsController: frc, delegate: self)
Cannot invoke initializer for type 'FetchedResultsDataProvider<_>' with an argument list of type '(fetchedResultsController: NSFetchedResultsController, delegate: MyTableViewController)'

I'm sure there is somewhere some code missing, and I looked at the final Moody example, but I cannot figure out what part I am missing.

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.