When I go to Editor-->CreateNSManagedObjectSubclass, and export my entities, they show up as the entity names... but another person who was working on my project before seems to have exported as their name with an underscorebefore, and these files look totally different on the inside...So I'm confused as to what's going on. Here's a google doc that contains a few relevant screenshots... Check out the second page to the two sections of fields. I'm sort of confused by them:
https://docs.google.com/document/d/1BMBqJME91Njb69JS4x3bvH0-KSmC-KLBl6QglE22jmQ/edit?usp=sharing
Can someone explain what is going on here?
You might want to read up on MOGenerator, since that's apparently what your predecessor used to generate the managed object classes. By default MOGenerator generates base classes prefixed with an underscore and initially generates stub subclasses (the ones without the underscores).
You can then write any custom code in the subclasses. That way, whenever the model changes, you can regenerate the base classes without worrying about clobbering your custom code, since by default MOGenerator won't regenerate the subclasses.
Related
I'm trying to understand how Core Data works in Objective-C and can't quite get the purpose of categories that have the name SomeClass+CoreDataClass and are created when we want to subclass NSManagedObject.
As far as I know, they should be created only once and not regenerated every time we need to update our entity's structure, so we can add our methods there. However, they are recreated as blank files every time I regenerate a subclass of NSManagedObject.
I think, I'm missing something, so could you explain their purpose?
+CoreDataClass is generated by xcode, you shouldn't edit it, because you can loose changes.
You can edit SomeClass, Xcode will only create it if it isn't exist.
This division was made just for programmers convenience.
You can freely move code from +CoreDataClass to main file and delete category if you wish.
Is it a good practice to define a category within the same .h/.m files of another class? I know it will build with no error and be exactly the same as if it was defined separately.
The main reason I want to do this is because I'm working on an open source control and I want it to have a single .h/.m file.
In general, the biggest problem with combining multiple classes and categories into the same header/implementation is impaired searchability. When a class is in a file with another class, the file name will no longer reflect the fact that the header/implementation contains your other class, making it much harder for others to look for your class.
If your project is small and self-contained, however, the searchability is less of an issue. When there is only one file to search, there is no question of where each particular piece of code is: it's all in that one file. It sounds like your project is both small and self-contained, so I see no problem in placing all code in a single source file if you want it that way.
Another alternative could be placing each class and category in a separate header/implementation pair of files, and then defining a header that includes them all. This would let you keep an ideal project organization, and let your users include a single header to use your component.
If you need this category in just one place I’d say that it’s not that bad having the category within the .m file.
Obviously, if you need that category in multiple places, you should definitely move to its own file: the convention is to name it in this way:
BaseClass+categoryName.{h,m}
e.g.:
NSString+reverseString.h
NSString+reverseString.m
Our current application uses a smart object style for working with the database. We are looking at the feasibility of moving to PetaPoco instead. Looking over the features I notice you can add attributes to make it easier to CRUD objects. Does adding these attributes have any negative side effects that I should be aware of?
Has anyone found a reason NOT to use these decorators?
Directly to the use of the POCO object instance itself? None.
At least not that I would be aware of. Jon Skeet should be able to provide more info because he knows compiler inner workings through and through, so he knows exactly what happens with this metadata after it's been compiled.
Other implications indirectly related to these
There are of course implications when accessing these declarative attributes, because they're read using reflection which is normally a slow process.
But there's nothing to worry here, because PetaPoco is a smart library and reads these only once then compiles & caches these things, so you only get penalized once then you get blazing performance afterwards. Because it uses compiled code.
Non-performance related implications
By putting attributes (any) on your classes/properties/methods you somehow bind your code to particular engine that will use this class, because they're directives for this particular engine to understand your code.
In case of PetaPoco attributes this means that your class can be used with PetaPoco but not with some other DAL (ie. EF) unless you add attributes of that one as well (EF Code First uses the very same approach with attributes).
The second implication is related to back-end database. In case you rename a table, column or any other part that is provided in your PetaPoco attribute as a constant magic string, you will subsequently have to change this string as well. This just means that you have to be thorough when doing database changes...
One downside is that it breaks the separation between the "domain" layer and the "data" layer, since it introduces the PetaPoco file (which contains data logic) to domain classes that should really not have any knowledge or dependency on the data layer.
If you're doing a single-project MVC app or something then it's okay to just use the Models directory for both, but for non-trivial and separated apps you'll have to have two PetaPoco files or play around with abstracting portions of the file in order to annotate your models without making them "know too much" about the underlying data, or else have you specify the table and/or primary key name all over the place.
The vCard 3.0 standard allows for extending the cards with custom field with a "X-" prefix. However adding a property via Objective-C's addPropertiesAndTypes: and setValue:forProperty: methods do not seem to result in an addition that will be exported to it's vCard format. Information added that way gets saved to the address book, but if you export the card to share with someone else, the new property gets left behind.
Is there a way using the AddressBook framework to add a vCard extension (like "X-") that will be exported and imported with the card?
If I edit an exported vCard manually, that added property is not displayed in Address Book, but is persistent through subsequent exports. It seems like there should be a way to programmatically write to an ABPerson that would result in a "X-" vCard property, and then subsequently read that custom property in.
Thanks for any/all help
If it's not doing this out of the box, perhaps you could write the code yourself, and maybe swizzle it into the ABPerson class using Objective-C method swizzling. Unfortunately, any functionality you add that way will only be used if your app is the one doing the exporting and importing. Since you're talking about vCard which is effectively an interchange format, that's probably less than completely helpful. (Not to mention that method swizzling is a total hack.)
Some quick experimentation in the debugger convinces me that the C interface just calls the Objective-C methods behind the scenes, so I'm guessing there'll be no additional functionality available there either.
Interestingly, you said...
If I edit an exported vCard manually, that added property is not
displayed in Address Book, but is persistent through subsequent
exports.
...but I did not see this behavior. Re-exports of an imported, hand-edited vCard don't contain my X-FOOBAR field. This makes the situation look even worse -- this means, for instance, that if someone imported a vCard containing your extension fields with the Address Book app, you'd likely lose those fields. But maybe I'm doing something wrong.
Perhaps you could piggyback on the NOTE field?
I want to programmatically (without Lightweight Migration) create a mapping model between two models that are exactly the same, except one of the entities (there are a bunch of entities) has different attributes. Let's call this entity "Person". And let's say the destination model has
1) added a new attribute called "address"
2) deleted an attribute called "eyeColor"
3) kept (i.e. not done anything with) an attribute called "name"
How would you create an NSMappingModel between these models programmatically? I happen to have some explicit questions that might help me do this by myself:
Q1) Do I have to create NSEntityMapping objects for all of the entities other than "Person", even if they remain unchanged?
Q2) How do I deal with the "address" attribute in "Person", which is a new one being created? Should I create an NSPropertyMapping for that somehow, that turns nothing into something ("address")?
Q3) How do I deal with the "name" attribute in "Person"? Do I have to create an NSPropertyMapping for that, even though it simply stays the same?
Q4) For the NSEntityMapping corresponding to "Person", is not creating any NSPropertyMapping for "eyeColor" a proper way to get it deleted? Or should I create an NSPropertyMapping for "eyeColor"? If yes, how would this object be created, i.e. what would determine that its purpose is to get rid of "eyeColor"?
Thank you in advance, and I apologize not being able to answer these questions myself, as the documenation really has no good example of how to create NSMappingModels programmatically. Note again that I'm not allowed to use Lightweight Migration. I must do this manually.
I've always used the automatic mapping feature of Xcode but it seems to me you can learn a lot from that as well. Make a model of (parts of) the source model, add a version, modify it to reflect the destination model and generate a Mapping Model (menu Design >> Mapping Model). If you then control-click the .xcmappingmodel Xcode has generated for you and tell the Finder to show you the contents of the package, you'll find an XML file inside that lists all the mappings. You can use the xml as a guide to help you recreate the process in code. Good luck.