Its more of a best practices sort of question. Here it goes...
I have automatically generated some classes for my entities in core data , now I want to use them as model objects to convert those models in JSON and send it over to the server. So my question is whether it is ok to use these classes or should I create separate classes and use a data mapper class to map these core data and model classes...
Which is a better approach and why...?
Thanks for your inputs...
You can use your NSManagedObject subclasses and add methods to those classes as you would any other NSObject class. This is perfectly acceptable (and would be better practice than to create separate object classes and using data mappers).
Use mogen to avoid the problem mentioned by #svena. It will automatically manage generation of core data models to prevent overriding your own code. Also I would suggest trying RestKit for server interactions. At least you can borrow their object serialization code because it does exactly what you want.
Related
I have been working with C# using a repository design pattern with Entity Framework (EF) that allows me to interact with the database using a generic class for each table.
This repository has all the functions that I would need such as: Adding a new entity into the database, updating an existing entity, deleting an entity, saving the context and so on...
Take, for example, I have an entity called 'Person' in the database. I would create a new class called PersonRepository which had all the functions I would need to change/add a value to the database.
As a result, to interact with the database, you create an instance of the repository class. This then allows you to call the functions of this class which in turn interacts with the database. The idea of this pattern is that all your database calls for an entity are isolated into a single class, this improves testability and separation of concerns.
I am learning how to use Core Data in my Swift programs and it appears to be similar to that of EF in C#. I have created the entities in the .xcdatamodel file and created the associated Cocoa Touch class via the Editor > Create NSManageedObject subclasses option.
I used the 'Category/Extension' CodeGen option, so, I then created a new class called 'Exercise'. From what I have read, this class can contain additional logic such as overriding the prepareForDeletion method. Does this mean I can add the addEntity, updateEntity functions onto this method and then call them from other code files?
My questions are:
Can I implement the same repository pattern that I can use in C#?
I believe this would be on the generated class of my entity (see image below)
Where do I place all my database call functions? If I can use this repository pattern I will place them on there, however, if I cannot, do I place them in a separate code file? Should I place them on the generated entity file which is created for the purposes of adding additional logic?
If I can use the repository pattern, is there a way to get the context injected into this class, or, do I have to call a getContext method each time I want to change it? In C# we can use the services to inject the context into the class each time I want to make changes to the database - I am unsure if the same is possible in Swift.
If I understand correctly, in Swift the equivalent of your 'repository' class could be one of two things. It could be context of core data, which you'd run queries and saves to OR (more likely) you would create a new class or struct that obscured away core data from the business side. Assuming the later, your "dataManager" class would perform all interactions with core data. It could then either return NSmanagedobjects to the business side, or you could map/transform/convert to some other type.
Yes, Exercise is a object that subclasses nsmanagedobject, so it has all the core data features of a managed object, but you can add any custom functions your want.
Your data manager class would perform the queries and return the correct objects. For example data manger.getExercises() -> [Exercises], dataManager.save(_ exercise: Exercise), etc....
You'll need to consider thread safety in your pattern. One option is converting your nsmanagedobjects to struct in your datamanager and not returning nsmangedobjects. Structs are thread safe and using codable you can easily convert between exerciseManagedOjbect and exerciseStruct. Plus, with this dataManager class example, you could remove core data for another persistence option in the future with reduced impact to your app overall.
I'm getting into Core Data and have started making "Classes" out of entities. Do I use these classes based off of entities as regular classes with methods etc?
Normally if I was using SQL directly I would have classes for each of my database objects (Tables) that store the working data and perform their functions.
Is this the same with Core Data - do I use the entity-based classes (subclasses of NSManagedObject).
So I might have these entities: Business -> Departments -> Employees
To comply with Core Data - do I make one class for each of these subclassing NSManagedObject and then add methods to it accordingly (like I would an NSObject class)?
Yes, you usually use the Core Data generated classes. You usually don't add methods to those classes, instead you should put them into a Category. This is because if you change an entity, you need to regenerate the class which will erase any methods that you added.
Yes(ish). They are your model classes. You aren't creating them 'out of' entities, they are the code representation of your entities.
You should have one class per entity, but you shouldn't create them yourself. You should get Xcode to create the classes. Or, better yet, use mogenerator.
I have a bit confusion in choosing whether to use NSManagedObjet class objects directly as models or whether to create separate classess for models and create data mappers to map data from these model class to NSManagedObject class objects.
Is there any harm in using Core Data objects as models ? What are the pros and cons of both approches?
Thanks in advance,
Regards,
tek3
I read your question and I take it you are not asking whether to use NSManagedObject directly or whether to subclass NSManagedObject, but if you should have your model as separate classes which use Core Data by explicit methods written by yourself.
Core Data is designed to act as the model layer for your application. I do not see any real benefits in having your own model classes, writing an interface for them and implementing it in core data behind the scenes, unless you really need the freedom to give up core data entirely at some point.
I recommend you create your model classes as subclasses of NSManagedObject. You are free to extend those in any way you deem necessary beyond what core data provides you, but at the same time your model classes will have full benefits from the core data framework: faulting, caching, data integrity assurances, cascade deletes, etc...
If you just use NSManagedObject, you will not have the benefit of the convenient "dot.notation" when referring to attributes and relationships.
Also, you will have to retrieve all values with valueForKey and set them with setValueForKey followed by strings. This can be extremely error prone and cumbersome and the resulting code is not nearly as readably as with the dot notation.
Finally, in your object classes you can implement all kinds of additional functionality. Where would you put this code otherwise? Remember the principle of encapsulation that helps produce independent and reusable code.
I have a iphone application in which I use nsecoding for saving my objects. However it has been decided that it should be saved using core data.
The questions is - what is the best way to convert my exsisting model classes to datacore classes. Should I create a new thorugh the xdatamodel editor and replace the old or what is the best strategy. I have not figure out an easy way to do this :P
Regards
Bjarke
Roughly, what you will need to do is this:
Create a data model that reflects the classes that you have already created - and I think you'll have to do it by hand in the model editor.
Then change your classes so they become subclasses of NSManagedObject. You'll have to make sure your properties are restricted to types handled by Core Data, of course.
I am struggling with how to understand the correct usage of models. Currently i use the inheritance of Db_Table directly and declare all the business logic there. I know it's not correct way to do this.
One solution would be to use Doctrine ORM, but this requires learning curve and all the current components what i use needs to be rewritten paginator and auth. Also Doctrine1 adds a another dozen classes which need to be loaded.
So the current cleanest implementation what i have seen is to use the Data Mapper classes between the so called model and DbTabel. I haven't yet implemented this as it seems to head writing another ORM. But example could be something this: SQL table User
create class with setters, getters, business logic here /model/User.php
data mapper /model/mapper/UserMapper.php, the funcionality is basically writing all the update, save actions in here.
the data source /model/DbTable/User.php extends the Db_Table_Abstract
Problems are with relationships between other models.
I have found it beneficial to not have my models extend Db_Table, but to use composition instead. That means my model 'has a' Db_Table rather than 'is a' Db_Table.
That way I find it much easier to reference multiple tables in the same model, which is a common requirement. This is enough for a simple project. I am currently developing a more complex application and have used the Data Mapper pattern and have found that it has simplified my code more than I would have believed.
Specifically, I have created a class which provides all access to the database and exposes methods such as getUser() etc.. That way, if the DB changes, or my client wants something daft like storing records in XML or we split the servers or something I only have to rewrite one class.
Again, my models do not extend this class, but have an instance of it assigned as a property during construction.
I would say the 'correct' way depends on the situation. Following the YAGNI and KISS principles, it is not good to over-complicate your model setup unless you really believe that it will benefit you in the long run.
What is the application you are developing? How is your current setup of extending Db_Table holding you back?