Strange behavior into my Core Data application. I have an entity with a fetched property, whose result is stored into the content array of a controller.
The first time I run the application, the result is NIL for the first entity of the controller's array (not for the others). If I re-launch the app, everything is ok.
Is the controller really informed that a new object has been added to its array? If yes, why so late? Did you ever encountered such an anomaly?
Regards,
Related
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.
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)
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.
is there a simple and efficient/fast way to query a managedobjectcontext to get an array of all the managedobjects in the context that have not yet been added to the persistent store?
i ask this because i would like to be able to save nsmanagedobjects that have been added to the MOC only if they conform to certain criteria. basically i want to be able to do this so that if some unexpected event happened before my managed object attributes were properly populated, i can catch this fact and purge the object(s) before saving the context. given the complexity of the navigation possible in the app, i'd like to have a look at the data to be sure they are good before i save.
i suppose i could also do this with some kind of validation rule and a flag field that doesn't get set until i am sure the user has added all the data to the record, but i don't yet know how to implement this...
any help much appreciated.
The insertedObjects method of NSManagedObjectContext
returns the set of objects that have been inserted into the context but not yet saved in a persistent store.
The documentation for content handlers in Orchard mentions Lifecycle Events (http://docs.orchardproject.net/Documentation/Understanding-content-handlers).
Most events are self explanatory, but I was wondering if anybody can tell me the differences between OnActivated, OnInitializing, and OnLoading?
In firing order:
OnActivated - content item object hierarchy has been created, but not yet fetched from db
Used for preparing content part for further usage. Eg. setting getters and setters for lazy loaded objects, setting up delegates etc. Think of it as of a "constructor" for a given part.
OnInitializing - content item object hierarchy has been created, but not yet fetched from db.
Used for setting initial/default property values for a given part.
OnLoading - content item is about to be loaded from db.
Used for various things. Fired only if an item exists in the database and is about to be loaded. Orchard core uses this event to set up lazy loaders for part records.
OnLoaded - content item has been loaded from db
Used for various things. Fired only if an item exists in the database and all record loaders have been set. You can be sure that part.Record will not be null for any part at this point and will contain data fetched from database.
I have an ios 5 app which does not create any data - it simply makes a GET call to a REST webservice and populates the sqlite database with those records. The initial GET works great when there are no records in the local database. However when I make subsequent calls, I will only be returning a subset of records whose data has changed since the last GET. But what is happening is that the records are just being added again, not updating the existing records.
I have an ID field which is the primary key (or should be) and when a record comes in whose ID already exists, I want that data to be updated. If that ID does not exist, it should be an insert.
I didn't see a way to set my ID field as a 'primary key' in the datamodel in XCode. I tried doing this in my didFinishLaunchingWIthOptions method:
userMapping.primaryKeyAttribute = #"id";
But that alone didn't really seem to do anything.
This is my call to actually perform the GET:
// Load the object model via RestKit
[objectManager loadObjectsAtResourcePath:[#"/synchContacts" appendQueryParams:params] delegate:self];
Which seems to do everything automagically. I am lost at this point as to where I should be putting logic to check to see if the ID exists, and if so do an update vs an insert, or what.
As of the latest RESTKit version (0.23) you can define the primary key like this:
[_mapping addAttributeMappingsFromDictionary:#{ #"id" : #"objectId", #"name" : #"name" }];
[_mapping setIdentificationAttributes:#[ #"objectId" ]];
Whereas objectId is you primary key on the core data object.
You seem to be doing it correctly and when your didLoadObjects callback happens you should be able to query Core Data for the objects you need.
You might be having an issue with the way your fetch requests are being set up. With the latest RestKit you can use RKObjectMappingProvider's
- (void)setObjectMapping:(RKObjectMappingDefinition *)objectMapping forResourcePathPattern:(NSString *)resourcePathPattern withFetchRequestBlock:(RKObjectMappingProviderFetchRequestBlock)fetchRequestBlock;
function and have the fetchRequestBlock fetch the proper data.
RestKit doesn't really handle partial update requests very well out of the box though. You might have more luck on the RestKit google group which is very active.
Quote:
I didn't see a way to set my ID field as a 'primary key' in the datamodel in XCode. I tried doing this in my didFinishLaunchingWIthOptions method:
userMapping.primaryKeyAttribute = #"id";
Keep in mind, the 'primaryKeyAttribute' is the one from your api payload, NOT a CoreData id, which CoreData manages on its own. RestKIt then maps the (invisible) CoreData primary key to the specified JSON key.
This question covncerns my lack of understanding of how to use the core data undo manager and how to restore a NSManagedObject to its state before editing was done.
I am just learning my way around Core Data. I have my NSManagedObject classes set up with their dynamic accessors. I perform a fetch that returns several NSManagedObject entity results. Content from each of these entity results (first name, last name) get put into a table view, and then the user picks one out of the table for detailed view and then editing.
The detail view controller receives a pointer to the selected NSManagedObject entity. As the user edits the fields, the corresponding property value in the NSManagedObject entity is updated. This seemed like the cleanest way to manage these changes.
Now, rather than committing the changes using save, I want to provide a cancel-editing feature that rolls back to what is in the data base for that entity. I really only want to restore the one entity and not perform the entire refetch.
I tried rollback and I tried NSUndoManager (with beginUndoGrouping and endUndoGrouping), and that is not working. I don't think I understand what rollback is really supposed to do.
But in any case, I still want to restore the property values in just that single entity (taking the lazy approach to only fetch what is needed, which is the one entity) so that my detail view controller can refill its view with the correct information. Right now it is using the NSManagedObject entity values, which contain the edited values, which were cancelled.
I suppose I could just start the edit process by creating a copy of the NSManagedObject. If the cancel-editing button is pressed, I could copy it back into the original. (I might even be able to just replace the original with the copy by moving the pointer. But since the pointer has actually been passed through several objects, I'm not sure how to manage the retain number on the copy.)
Does anyone have any other suggestions?
Thanks
Using rollback should accomplish what you want and I'm not sure what it doesn't. It is probably an implementation detail error.
You can find the specific managed object/s that were updated but not yet saved by calling the context's updatedObjects.