Core Data returns NSManagedObject instead of Concrete class, but only when using . accessor - objective-c

I have set up a Core Data model where I have two objects, say Person and Address. A person has an address, and an address can belong to many people. I have modelled it in core data as such (so the double arrow points to Person, while the single arrow goes to Address)
I have then created two classes for those objects, and implemented some custom methods in those classes. In the Core Data model I have entered the names of the classes into them.
If I fetch an Address from Core Data directly, it gives me the actual concrete class and I can call my custom methods on it.
If on the other hand I fetch a Person and try to access the Address through Person (eg: person.address) I get back an NSManagedObject that is an address (eg: I can get to all the core data attributes I've set on it) but it doesn't respond to my custom methods, because it's of type NSManagedObject instead of Address. Is this a limitation of Core Data or am I doing something wrong? If it is a limitation are there any work arounds?

Did you create those classes using the modeller (Select an Entity, File > new file.., Managed Object Class, then select the Model Entity)?
A while ago I had a similar problem because I didn't create my managed object models using the Modeller. What I did to make sure everything was up and running was to copy and save my custom methods (and everything else I'd implemented) and start from scratch using the modeller. Then I was able to customize my model classes again and everything worked just fine.
I know this is not a complete answer but perhaps it can help you until someone explains exactly what is going on.
Cheers!

You probably just forgot to set the name of the class in the model when you created the entity - it defaults to NSManagedObject. Click on Person and Address in the modeller and check, on the far right side where the Entity properties are listed, that the Class field is filled in correctly with the name of the corresponding objective C class and isn't just the default NSManagedObject setting.

Your implementation file for the class probably hasn't been added to the Target that you are running.
(Get Info on the .m file -> Check the targets tab)
If your xcdatamodel has the Class set, if it can't find it at run time it will still work, you will just get NSManagedObject instances back instead. Which will actually work just fine, until you try to add another method to the class, as you have found.

Related

Accessing AppSettings.json value from a model class

I have a calculated field in a class used for photos which prepends a url to the filename, I want to be able to add a base url for the photos (which is to an azure storage account) which will come from the appsettings file.
Initially I created a strongly typed class to access the settings, and I can inject it just fine to say a service class, but how can I access this in a model class? Am I completely going in the wrong direction with this?
Thanks for any help!
When instantiating the model, you could inject your strongly typed settings class, as long as the model already has a dependency on that. Alternatively, you'd need to move the calculation of that field out of the model, or simply provide the base URL to the model from your service classes.

Spine.js have updateAttributes include new attributes

It seems that Spine's Model.updateAttributes only updates attributes, and does not create new ones in case you supply any.
In my usecase, I have a controller that creates part of the attributes. Then through an Ajax request the server responds with the full object, and I want to update the model instance living in Spine with the additional variables.
For example, I have a model with attributes: name, date_created. Through the controller a user instantiates an object providing only the name. An Ajax request notifies the server which in turn responds with a name and a date_created. This date_created should then be added to the user's model.
Model.updateAttributes doesn't work, and I wouldn't be too fond of deleting the object and creating a new one - that just seems as too much overhead. I could provide default values for variables that are not set upon creation, but that also has a negative side. I guess what I'm looking for is a method that could be called Model.createOrUpdateAttributes. Can anybody recommend a way to achieve this? Thanks!
I might haven't fully understood your usecase, but I'll try to answer.
You need to declare whatever attributes a type of a model has with the configure class method. This declaration helps various model function to do their job later.
After you declare all the attributes you need, you can create model instances with any of the previously declared attributes.
You don't have to provide values for all the declared attributes.
After the ajax call returns, the date_created will be set on your model instance. Until this happens it will be just undefined.
If this solution still can't work for you, please describe why, and I'll gladly try to help.

Passing array from one class to another using delegation - Best design pattern?

The Problem
I have a class which calculates the path a user took using CoreLocation and and array of arrays containing the coordinates of each point (taken when the users location changes). This class method is being called by my View Controller, but I want to set it's delegate to another class which will store the result in Core Data or upload it to a database. I can return the array to the View Controller by using:
PathFinder.delegate = self
Then make my View Controller implement my delegate protocol, but this isn't what I want.
What I've Considered
I've thought about making the class which uploads the data to the database/stores it in Core Data a singleton class so that I can easily access it from my View Controller. E.g.
PathFinder.delegate = <MY SINGLETON CLASS>
Conclusion
What would be the best way to do this? Would it be bad practice to put the code to upload the array to my server in the PathFinder class? Any help would be appreciated.
I have something like this - a singleton class that manages a Core Data repository for images (some in the repository, some on the file system but a URL in the entity).
Why not have a singleton class that all objects that need the services import? That way, you tell some object to do something, when that works is done they tell the repository to save it. You can use a delegate protocol to know if it succeeded or not, but just decouple the saving of it from driving the process and knowing the outcome.

How should I import object instances into Core data?

I created a custom LocationGenerator class that uses CoreLocation and Reverse Geocoding, and generates (when asked) a custom Location object. My custom Location object has two instance variables - Address and GPS...both point to instance of two custom classes - Address is a bunch of strings and GPS is three floats - latitude, longitude and altitude.
Location = Address + GPS
For this to work, I needed to create three custom classes - Location, Address and GPS, all with default values set in their respective init methods.
Then I moved to Core Data. In the model I have these entities - Item, Location, Address and GPS. Item entity has some simple string properties and a Location relationship.
The location entity has a Address and GPS relatioship.
Since I moved to Core data, I deleted the custom classes Location Address and GPS I mention above and let Xcode generate classes from based on core data model.
The problem is, I am not sure how to create a Location instance in LocationGenerator anymore.
My former class definitions for Location and Address and GPS are gone, and in those from core data I should not override the init method.but should those generatede classess be a blueprint for my new Location object?
I guess my question is, how should I generate a location object in the LocationGenerator.
Should the LocationGenerator have its Location object created "inside" the managed object context?
To clarify from the UI point of view -I am just in the process of creating an Item, but it is not created yet, it waits for the Location..and only then is it inserted into core data..
Should I look at all objects that are created in the context the same way as i looked at objects before, with the only difference that they are in the context (and managed by the CD rules) and they persist?
The designated initializer for managed objects (Core Data objects, that is) is -initWithEntity:insertIntoManagedObjectContext: which is to say that you can't create a managed object without it being associated with a managedObjectContext. You indicate that you want to create the object, and then at some time later, decide whether or not to store it. There are essentially two ways to do that. The first way is to have some other object type that's not an NSManagedObject, but which you can use to populate an NSManagedObject subclass later when you decide to it should be persisted. The other way is to just created the managed object in the context, and then delete it from the context if it turns out that you don't need it.
NSManagedObjectContexts can be thought of as "scratch pads." Nothing is actually persisted until you -save: the context, so if you're going to be able to make a determination of whether or not to persist the object in the same workflow in which you're going to save the context, the second way is probably the way to go. If the lifetime of this pre-persisted data is longer than the standard workflow you're doing with your ManagedObjectContexts then the first way might be better.
HTH.

How to pass user details between objects in VB.net?

I'm redesigning an old VB6 application into VB.net and there is one thing I'm not sure on the best way to do.
In the VB6 application whenever we created a new instance of a component, we would pass in the user details (user name and the like) so we new who was performing the tasks. However, no that I'm redesigning I've created some nice class designs, but I'm having to add in user details into every class and it just looks wrong.
Is there a VB.net way of doing this so my classes can just have class specific details? Some way so that if my classes need to know who is performing a task, they can get the information themselves, rather than having it passed in whenever the objects are created?
You could put the details of the current user in a class that is accessible by all class instances of your application.
One place you could consider putting it is in the MyApplication class. You could also create a module and place it there.
Could you wrap the current user details into an object, and pass the object when you create the others? They would just keep a reference, and delegate to the user object for user-specific stuff.
That seems like the obvious way?