Search code examples
core-dataios8icloudnsmanagedobjectnsset

"Error: this process has called an NSArray-taking method..." when iCloud pushes managed objects


For every managed object that is sent via iCloud update, this warning/error is sent to the console:

*** ERROR: this process has called an NSArray-taking method, such as initWithArray:, and passed in an NSSet object. This is being worked-around for now, but will soon cause you grief.

My managed objects are Clients and have a one to many relationship with assessments as shown below.

    class Client: NSManagedObject {

        //other NSManaged vars are here

        @NSManaged var assessment: NSOrderedSet
}

Judging by the timing of this error (during ubiquitous updates) and the fact that this is my only use of NSSet objects in my project, I can presume that a function during this update is being passed an NSOrderedSet when its expecting an NSArray.

Turning off iCloud removes the errors.

I found two other folks with a very similar issue: Using iCloud enabled Core Data NSArray-taking method

Core Data Relation between Objects

However, neither offers any solution to my problem. Everything is working fine right now, however "it will soon cause you grief."

If this isn't resolved here, I'll take this issue up with the apple dev support.


Solution

  • I figured it out how to fix this error after much research. (No help in from the Apple Dev forums).

    This is error is caused by the Swift 1.2 upgrade. They encourage you to use their new Set<> class instead of NSSet. The error was a vague way of reinforcing that claim.

    Ordering of my data was ultimately handled by my NSFetchedResultsController, so I didn't need the stored data to be ordered. So I set out on a task to change the data type for my one to many relationship from NSOrderedSet to Set.

    So I created a new data model, selected my relationship and unchecked "Ordered" in the data model inspector. Then migrated to the new model in the next run. (as shown below)enter image description here

    Once that was done, I changed the data type in my managed object subclass from NSOrderedSet to Set. (or Set). That generated compiler errors that were easy to fix throughout my code.

    The new Set class easily converts to an array: Array(mySet)

    To insert an object to the set, there's an easy insert method. foo.mySet.insert(objectToInsert).

    Side note: Converting my relationship to a Set also fixed some weird ordering issues I was having with my table views and the NSFetchedResultsController.

    Then I ran the program, generated data, uninstalled the program. Ran the program again and watch the glorious iCloud data populate without the annoying errors.

    Boom. I hope this saves someone out there the 10 hours of turmoil (I tried a lot of different things..) I spent to fix this.