Transformable Attributes in Core Data

The way I tend to use transformable attributes in Core Data is to just make use of the standard NSValueTransformer that gets used to encode/decode any object that conforms to the NSCoding Protocol, then in my NSManagedObject subclass, cast this to the type it’s expected to be (I use mogenerator to generate the subclasses by the way):

name it with suffix Object since it will have type id

name it with suffix Object since it will have type id

  @interface MyObject : _MyObject
  @property (nonatomic, strong) NSDictionary *metadata;

And then in the .m file, the accessors

  @implementation MyObject
  + (NSSet*)keyPathsForValuesAffectingMetadata
      return [NSSet setWithObjects:@"metadataObject", nil];
  - (void)setMetadata:(NSDictionary *)metadata
      [self willChangeValueForKey:@"metadata"];
      self.metadataObject = metadata;
      [self didChangeValueForKey:@"metadata"];
  - (NSDictionary*)metadata
      [self willAccessValueForKey:@"metadata"];
      NSDictionary *metadata = (NSDictionary*)self.metadataObject;
      [self didAccessValueForKey:@"metadata"];
      return metadata;
  // the rest of your implementation here...

Summary: Saving your custom object classes in CoreData is pretty straightforward when supporting the NSCoding protocol. It’s then easy to ensure typing by declaring properties that just wrap these Core Data attributes. This post is basically something of a recipe so I can remind myself later.

UPDATE:  See this post.  You can actually get mogenerator to set the data type for you and you don’t have to write these accessors at all.


Notes on NSNotificationCenter

This blog is sometimes about content from my head, but also a place to just keep interesting reference info.

I was debugging a crash that provided very little info about my app’s code, but threw an exception when calling

[UIViewController didPurgeMemoryForReason:]

In the end I suspect it was because someone was calling

[[NSNotificationCenter defaultCenter] removeObserver: self];

outside of a dealloc method, which ends up accidentally deregistering for the didReceiveMemoryWarning notification.

Anyway, looking at this post, in the comments, I learned something new about a block-based API for the notification center where you can provide the notification’s handler right as you add the observer. What’s more is how you remove the observer.

I quote shusta from the comments:

NSNotificationCenter provides -addObserverForName:object:queue:usingBlock: which, unlike the other addObserver methods, returns an actual observer. To stop observing, you call -removeObserver: with that returned object instead of self. This isn’t as weird as it might sound.

To set up the observer, you would call

id keyboardWillShowObserver = [[NSNotificationCenter defaultCenter] 
            usingBlock:^(NSNotification *notification) {

// react to notification

This tells the notification center to call the provided block upon UIKeyboardWillShowNotification, and returns to you keyboardWillShowObserver. (NSNotificationObserver retains keyboardWillShowObserver. You probably don’t need to.)

To stop observing UIKeyboardWillShowNotification, you would call

[[NSNotificationCenter defaultCenter] removeObserver:keyboardWillShowObserver];
keyboardWillShowObserver = nil;

So now you don’t have to worry about side effects such as superclass observers, since you’re not removing your entire object as an observer.

This isn’t all sparkly pixie dust, though. Block-based observers come with their own problems, which is that blocks probably retain self. So if you want to remove the observer in -dealloc, you’ll have a problem because -dealloc will not be called. (A retain cycle)

The way to solve this is to create a block variable (for primitives), or a weak pointer to self and use that instead.

__weak MyClass *weakself = self;
/***/ ^(NSNotification *notification) {
    [weakself->array removeAllObjects];
    [weakself showKeyboardLabel];

The block won’t retain weakself, and you can -removeObserver: in -dealloc, no problem.

Of course, if you’re going to removing the observer sooner, it’s probably unnecessary. Regardless, the block based method avoids the pitfall described in this article by removing observers very precisely instead of indiscriminately.

Quick Reference – Load a UIView created in a NIB

I have a few situations where I would like to visually lay out some UIView and writing code just to move something over by a pixel, no back two, no actually the original was fine, etc. is just a pain. I like WYSIWYG. So from time to time I’d like to load a UIView from a NIB because sometimes you need more than one instance of that UIView in your view hierarchy.

It’s dead easy. For a subclass of UIView called MyCustomView, you just need to do the following in Interface Builder:

* Create a NIB file for your view, and lay it all out. Create Outlets as necessary.
* Set the File’s owner in IB to your UIView subclass’ name
* Set the class type of your NIB’s view (much like a view controller’s view property) to your subclass name.
* Any outlets should be relative to the view, NOT the file’s owner

Then in code:

– Implement a method something like:

- (id)initWithNib
    // where MyCustomView is the name of your nib
    UINib *nib = [UINib nibWithNibName:@"MyCustomView" bundle:[NSBundle mainBundle]];
    self = [[nib instantiateWithOwner:self options:nil] objectAtIndex:0];
    return self;
- (id)initWithCoder:(NSCoder*)aDecoder
    self = [super initWithCoder: aDecoder];
        // do your initialization tasks here
    return self;
- (void)awakeFromNib
   // then do any other initialization tasks here. Possibly interesting to you

Bam! It’s that easy.

Cocoa Bindings – The Easy way for an NSView subclass to update itself

So, say you have a NSView subclass in your Interface that is purely data-driven (i.e. it’s not an interactive component, it merely provides a graphical representation of an underlying data model).  It would be nice to keep this view updated to the current state of your data model automatically without writing too much glue code.  Here comes Cocoa Bindings!

Now, as Cocoa Bindings and Core Data are both powerful technologies, it’s hard to write a tutorial that doesn’t start from the beginning.  So, this is not a tutorial (per se), nor am I starting from the beginning.  Here is the start situation:

– You are using Core Data in your app, and don’t have any issues like I have described in blog posts preceding these (i.e. pretty much every attribute is immutable (i.e. you use myAttribute = newAttribute to register any kind of change on my attribute),

– You are familiar with NSArrayControllers and know a bit about basic Cocoa Bindings.

So?  How to get things working?  The trick is to make use of the CoreData framework’s automatically generated NSNotifications, namely this one:

NSManagedObjectContextObjectsDidChangeNotification, which you can use to determine if any of these objects are of any interest to your NSView subclass, and if yes, tell your class to redraw itself.

How does this all begin?  It begins with the bindings.   In an app I’m working on, I have sort of objects that have a specific duration, and this duration is derived from the duration of child objects.  Imagine the parent object as a day, and the child objects as tasks, and those children have children of subtasks, who have a duration.  Get it ?  A sort of pseudo equation for the entire duration would be:

totalDuration = [day valueForKeyPath: @"tasks.@sum.subtasks.@sum.duration"];

(although in Cocoa this isn’t allowed, but perhaps you get the shorthand.  It sums all durations in the sub elements)

Or said another way, a Day has many Task object who each have many Subtask objects, and a subtask has a duration property that you are editing elsewhere in your GUI.

So, how do we get this working? Here would be a portion of your NSView subclass’ .m file. The .h is a subclass of NSView and has:

@property (nonatomic, strong) Day *day;

static int DayObservingContext; // see here for an explanation of KVO contexts

+ (void)initialize
    [self exposeBinding:@"day"];

- (void)bind:(NSString *)binding toObject:(id)observable withKeyPath:(NSString *)keyPath options:(NSDictionary *)options
    if ([binding isEqualToString:@"day"]) {
        [observable addObserver:self forKeyPath:@"selection" options:0 context:&DayObservingContext];
        _arrayController = (NSArrayController*)observable;
        [super bind:binding toObject:observable withKeyPath:keyPath options:options];

- (void)unbind:(NSString *)binding
    if ([binding isEqualToString:@"day"]) {

        [_arrayController removeObserver:self forKeyPath:@"selection"];
        _arrayController = nil; = nil;
        [super unbind: binding];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    if (context == &DayObservingContext) {

        id selection = _arrayController.arrangedObjects[_arrayController.selectionIndex];

        if (!selection && [selection isKindOfClass:[Day class]] == NO) {
            [NSException raise:NSInternalInconsistencyException format:@"This object should be bound to Day Objects!"];
        } = (Day*)selection;

        [self setNeedsDisplayInRect:[self visibleRect]];
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];

- (Day*)day { return _day;}
- (void)setDay:(Day *)day
    if (day == _day) {

    if (_day) {
        [[NSNotificationCenter defaultCenter] removeObserver: self
                                                        name: NSManagedObjectContextObjectsDidChangeNotification
                                                      object: _day.managedObjectContext];

    _day = day;

    if (_day) {
        [[NSNotificationCenter defaultCenter] addObserver: self
                                                 selector: @selector(contextChanged:)
                                                     name: NSManagedObjectContextObjectsDidChangeNotification
                                                   object: _day.managedObjectContext];

    [self setNeedsDisplayInRect:[self visibleRect]];

- (void)contextChanged:(NSNotification*)notification
    // Get a set containing ALL objects which have been changed
    NSSet* insertedObjects = (NSSet*)[[notification userInfo] objectForKey:NSInsertedObjectsKey];
    NSSet* updatedObjects = (NSSet*)[[notification userInfo] objectForKey:NSUpdatedObjectsKey];
    NSSet* deletedObjects = (NSSet*)[[notification userInfo] objectForKey:NSDeletedObjectsKey];

    NSSet *changedObjects = [NSSet set];

    if (insertedObjects) changedObjects = [changedObjects setByAddingObjectsFromSet:insertedObjects];
    if (updatedObjects) changedObjects = [changedObjects setByAddingObjectsFromSet:updatedObjects];
    if (deletedObjects) changedObjects = [changedObjects setByAddingObjectsFromSet: deletedObjects];

    // go through all objects, find type, and see if they have a relationship that is a part of this Day
    BOOL shouldRefresh = NO;

    for (NSManagedObject *object in changedObjects) {

        if ([object isKindOfClass:[Day class]]) {
            if (object == _day) {
                shouldRefresh = YES;
        if ([object isKindOfClass:[Task class]]) {
            if ([(SCRecipeStep*)object day] == _day) {
                shouldRefresh = YES;
        if ([object isKindOfClass:[Subtask class]]) {  // it is a subtask that has the .duration property which is edited elsewhere in your GUI
            if ([[(Subtask*)object task] day] == _day) {
                shouldRefresh = YES;

    if (shouldRefresh) {
        [self setNeedsDisplayInRect:[self visibleRect]];


- (void)drawRect:(NSRect)dirtyRect
   // your custom code here that knows how to draw a Day object

Now, all you have to do in Interface Builder is create an outlet to the NSArrayController that is managing your Day objects (i.e. _arrayController.arrangedObjects will be a collection of Day objects), and of course an outlet to your “DayView” subclass.

then, you just add the binding in your loadView method:

- (void)loadView
    [super loadView];

    [self.dayView bind: @"day"
              toObject: self.daysArrayController
           withKeyPath: @"selection" /* due to the way we overrode bind: we could specify nil here */
               options: nil];

And so any time your currently selected day changes, it will know how to change the currently drawn day, and because we are using NSNotificationCenter to be informed of any changes to the managedObjectContext, and have code that checks if any of these changes are relevant to our view, the DayView will update itself accordingly.

I spent ages trying to get the Day object’s children to notify the parent if any of its properties change (explained in the KVO documentation, “Registering Dependent Keys, to-many relationships), but found it to be an insane amount of code required and thought “there must be an easier way than this”, I read that one sentence in this section of the documentation that states:

“2. If you’re using Core Data, you can register the parent with the application’s notification center as an observer of its managed object context. The parentshould respond to relevant change notifications posted by the children in a manner similar to that for key-value observing.”

This is what this post attempts to clarify. I hope it helps. I can’t believe how much time I’ve spent trying to get something that’s meant to be simple, working.

PS – THIS POST was very helpful for getting the right approach

Core Data, KVO, Bindings… Tips and Tricks for the Layman

So, as my blog has indicated, I have been trying to tackle many advanced technologies all at once, and I’m sure I will look back on this blog one day and shake my head at the silliness of the issues I’m having currently, but well, you can’t make an omelette without breaking some eggs.

I really wish I had a mentor, some guru, someone where I could just ask “am I on the right track?  Is this the right approach?”  I don’t need much supervision or direction, but just a point in the right direction would be IMMENSELY helpful.   So, without that, taking the brute force approach, I thought I’d post a few things that you, as the beginner may want to keep in mind until you are more advanced yourself.

This list will be periodically updated.

* KVO and Bindings are deep and powerful technologies (as is Core Data).  Apple has tried to hide a lot of this from you so you can get up and running quickly.  That said, it’s still a steep learning curve and it’s difficult to just ‘jump into’ KVO, Bindings, and Core Data all at once.

* Errors and exceptions relating to KVO, CoreData, and Bindings are difficult to debug as the console output of such errors is seldom descriptive enough so to help you track down the problem.

* Core Data entities should have properties that are ‘one thing’, and not a compound property.  (else you have to write a bunch of custom code)  i.e., if you for example use a Value Transformer to restore a custom object, changes to those objects’ properties will not mark the Core Data entity as dirty, and thus any changes you make to that will not get saved.  (unless you are setting these properties after just having added that object to the array, because by definition that object will be dirty.)  In slightly more programmer speak, your custom properties (transformable attributes) should be IMMUTABLE, meaning, only changes are registered if you make a call that’s something like

myEntity.myCustomProperty = someValue


myEntity.myCustomProperty.maxValue = someMaxValue

* All the tutorials and intros to Cocoa Bindings tout it as this magic thing that will result in you never having to write glue code again!  Wrong.  F•cking wrong wrong wrong.  (At least until you get your head around it!!)  I’m actually quite surprised at how terrible some of Apple’s documentation can be on the topic of KVO, Core Data, and Bindings.  iOS Developers (which I am, 2 weeks into Cocoa…) won’t have to worry as most of this stuff doesn’t work on iOS.  For example, the easiest way to make a NSView subclass that is backed by a Core Data model.  I spent AGES trying to figure this out the KVO way, whereas the solution’s approach was briefly mentioned in ONE sentence in a KVO programmer’s guide.   (will write a post about this soon)

False Assumptions I have made along the way and what WASN’T true:

– changes to an object in a to-many relationship will notify its parent.  (i.e. I change an Employee’s name, the Department will not receive a KVO notification about this.  Only if you add/remove employees, will the Department receive an update about this.  This isn’t such an issue, but what if your object was a TimeLine with many TimeSteps, who each have a duration property?  The Timeline won’t update.  Yes yes, this is all in the KVO Documentation, and implementing such updates are non-trivial)

KVO – Observing any change in Object state

I have a situation where it would be really handy to bind an entire object (and its encapsulated states) to a view.  As this view displays itself depending on the all the different values of its member variables, it could be very tedious to set all this up, property by property, when all a view object really needs to know is when its underlying data model has changed and it should therefore redraw itself.

So, I thought I would post my solution to the problem.  Basically the approach is to create a property that you can observe (call it observableSelf), and will send change notifications any time any other property of that object changes.  Other than the fact that you have to observe some extra property, I find the solution kind of elegant.

meh.  Here’s the code.  It speaks for itself.

//  KVOUpdatingObject.h
//  Created by Stephen O'Connor on 1/28/13.
//  Copyright (c) 2013 Stephen O'Connor. All rights reserved.

#import <Foundation/Foundation.h>

typedef NSUInteger ChangeMonitor;  // I put this here because it seemed better to
                                   //define an appropriate type than int, although it doesn't really matter.

@interface KVObservableObject : NSObject

@property (nonatomic, assign) ChangeMonitor observableSelf; // basically you observe this


and now the .m

//  KVOUpdatingObject.m
//  CocoaBindingsTesting
//  Created by Stephen O'Connor on 1/28/13.
//  Copyright (c) 2013 Stephen O'Connor. All rights reserved.

#import "KVOUpdatingObject.h"
#import <objc/runtime.h> // very important to import this!

@implementation KVOUpdatingObject

+(NSSet*)keyPathsForValuesAffectingValueForKey:(NSString*)key {

    NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];

    if ([key isEqualToString:@"observableSelf"]) {
        NSMutableArray *keys = [NSMutableArray array];
        unsigned int count;
        objc_property_t *properties = class_copyPropertyList([self class], &count);  // see imports above!
        for (size_t i = 0; i < count; ++i) {
            NSString *property = [NSString stringWithCString:property_getName(properties[i])

            if ([property isEqualToString: @"observableSelf"] == NO) {
                [keys addObject: property];

        keyPaths = [keyPaths setByAddingObjectsFromArray: keys];

    return keyPaths;


KVC is easy to understand. KVO starts to get a little more complicated, and Cocoa Bindings is the next step up. I’ve been having trouble with Bindings and CoreData only because I haven’t had very much time with it. It’s amazing what Apple hides from the Developer and yet still enables the Developer to do wonderful things. But slowly the Developer needs to know more and more and go deeper. I’m still on my way down that road.

This is easily tested to give you some safe feeling. I created a subclass of the above, gave it a NSNumber property and an NSArray property (someNumber, and someObjects respectively). Here’s the test case:

@implementation CocoaBindingsTestingTests

- (void)setUp
    [super setUp];

    // Set-up code here.
    _testObject = [KVOTesting new];   // the subclass of KVObservableObject

    _observationCount = 0;  // some instance variable on this test case

    [_testObject addObserver:self forKeyPath:@"observableSelf"

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    if ([keyPath isEqualToString:@"observableSelf"]) {

        NSLog(@"Object Changed!");
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];

- (void)tearDown
    // Tear-down code here.
    [super tearDown];

- (void)testExample
    [_testObject setValue:@4 forKey:@"someNumber"];  
    _testObject.someNumber = @4; 
    _testObject.someObjects = @[@2, @3, @4]; 
    [_testObject setSomeNumber: @5];

    STAssertTrue(_observationCount == 4, @"Should have reported 4 changes");


Now, the only remaining issue for such a use case is what if this object is a member of another object, and this object's properties change, but not the object itself.  How would that 'parent' know?

Cocoa Bindings Tips – Array Controllers

Working with Array Controllers I’ve learned a few things that I’d like to write down.

1)  You can subclass and override an NSArrayController’s awakeFromNib file to set your own sortDescriptors.  When you do this, you can around the issue of a NSTableView not being sorted until you click on a column header.

2)  Content, Content Objects, Content Values explained:

Binding a NSPopUpCell to a collection of objects can be tricky.  I had the case where I have enumerated values, so ultimately we are talking about setting a numeric value for a property in the data model, but want to display user friendly text.  One would think “bind the number then use a one-way value transformer to convert those enums to strings.”  Somehow this didn’t work like I’d hoped.  In the end I used an array of NSDictionary objects and did the bindings as follows:

Content binds an array controller’s arranged objects.  But each of these will be an NSDictionary.  (Don’t forget in the NSArrayController’s inspector in Interface Builder, so specify that objects for that controller are of type NSDictionary, and specify the keys you use in those dictionaries in that same pane)

Content Objects – this is like saying, from the Content, is there a specific property that you are trying to bind to your data model?  What you set here is the object that will be selected.

Content Values – what would you like to display?

Selected Object – what are you binding the selected object to?

So, in this case I bound content to an array of NSDictionaries, the Content Object was that dictionary with key “numberRepresentation”, and the contentValue was “textRepresentation”, so that I would be displaying text, but assigning a NSNumber – the selected contentObject – to the parameter on the bound data model (as specified by the selected Object binding).

This seems pretty trivial, but was very helpful getting my head around Core Bindings.  It’s a powerful technology, but it’s unforgiving as it isn’t easy to debug, and it doesn’t provide much in terms of debug info / what went wrong.  The error messages are often not that helpful.


Cocoa Bindings misery

I’m really starting to think twice about Cocoa Bindings.  It’s touted as the ‘never write glue code again’ solution, making it seem like you’ll never spend time writing boring code again.  YAY.

Except they forget to mention that you’ll spend just as much time trying to debug a black box.  -.-  OR writing code that makes your application ‘fit into’ their way of doing things.  So if you don’t fully understand the technology, you’re spending all of your time trying to figure out WHY something won’t work.  It’s really kind of a pain in the a**.  I feel like I’m a first grader who got thrown into 5th grade math class.   Missing big pieces of the big picture and hoping you can fumble or fake your way through it.  Cocoa Bindings will punish you for that.

Can anyone tell me how you can set breakpoints on specific setters on Core Data generated accessors?  It would be nice to inspect the properties of specific data models at runtime.

I am binding a NSTableView (well, it’s individual columns), to an array controller who elements (arrangedObjects) are of type ‘TimeBlock’.  Now a TimeBlock is defined in the Core Data model, and it has a few NSNumber properties, and then a Transformable Property to type TimeRange (which I successfully convert to and from NSData with a NSValueTransformer subclass… as the docs say you should).

A TimeRange object has 2 NSNumbers for min and max amount of time something should take.  I want to bind either of these to a NSTextCell’s value.  So I bind the column to arrangedObjects.timeRange.max  (and even use a NSValueTransformer  to ensure strings are numbers and vice versa) and provide a NSNumberFormatter object to the NSTextCell.

But the Time Range object shows itself to be nil in the UI.  I have no idea what’s going wrong.  I set a value.  It ‘sticks’.  I save the models.  I restart the app.  None of the values have been committed.  I can’t debug it.  (Can I ?)

Teaching oneself such a technology is maybe not the best idea.  It’s like it’s a constant two steps forward, one step back way of learning, and it’s kind of annoying.

Rant over.  If and when I get this figured out I’m gonna write a tutorial – in plain English – how one needs to visualize how these things work.  This is just way too annoying, and the documentation is very very boring.

Core Data, Cocoa Bindings, OSX Programming

So, I took on a hefty task these past few days and decided to do a lot of complicated stuff all at once.  Teach myself CoreData was the original goal, but then it occurred to me there’s not much you can do with CoreData when you don’t HAVE ANY DATA.

So, knowing that I’m going to want to have a rather substantial pre-populated database in the app, and ideally delegate this menial task of populating it away to the other App designer, I thought I should create a database Editor.   This would then involve making a Mac OSX app that would make it straightforward to get data in the database.

But, if you use Mac OSX, you can leverage the extremely powerful technology called Cocoa Bindings, which is designed in a way where you shouldn’t have to write much (boring) glue code, that would be responsible for synchronizing the UI Controls / Elements with the Data they are controlling/being controlled by.

So there.  CoreData, OSX, and Cocoa Bindings, all at the same time.  Here is my qualitative report on my progress so far:

– Once you understand how things work, it is simple and VERY useful.  😀  (Yeah, ONCE you do)
– Learning a lot of things at the same time can be very difficult because one technology depends on another, and if you don’t understand any of them in great depth, it’s hard to find where the source of your problems are.
– OSX Programming is FUN.  Possibly more fun than iOS programming.

Things that tripped me up:

  • NSTextCell is used to edit text or number properties, though with numbers you will want to apply a NSNumberFormatter, and may require a subclass of NSValueTransformer to ‘translate’ the string output of a NSTextCell into a NSNumber value for your data model.
  • If you want to edit an object’s “to one” relationship with another object, don’t use a NSTextCell nor a NSComboBoxCell, but rather a NSPopUpButtonCell and follow instructions given at Apple Developer
  • If you’re using an array controller for NSManagedObjects, you should bind a NSManagedObjectContext, and use it in entity mode (not class mode), because the add: and remove: (and other such) actions of the NSArrayController will instantiate via [[SomeClass alloc] init] instead of [[SomeManagedObjectClass alloc] initWithEntity… ];
  • I still haven’t figured out how custom validation works.  It seems to validate but then reports validation failures although there shouldn’t be… Will figure that out later and in the meantime ‘will be careful’
  • Maintaining Object uniqueness can be tricky.   I added this method to a category for NSManagedObject:
+ (NSManagedObject*)findForEntityName:(NSString*)anEntityName
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
 	[fetchRequest setFetchLimit:1];
 	[fetchRequest setEntity: [NSEntityDescription entityForName: anEntityName inManagedObjectContext: aContext]];
 	[fetchRequest setPredicate: findCriteria];
 	NSArray *results = [aContext executeFetchRequest:fetchRequest error:nil];

 	if ([results count]==0) return nil;  // no matches (existing records with this code) were found

    return results[0];

Then you can quickly check if an object exists based on the entity name and the predicate (which would be filled with the query that would define uniqueness… i.e.  the property that is your “primary key” )

  • In CoreData, if you have an object that has a to-one relationship, i.e. a Recipe has many steps, and with each step there is an ingredient associated with it. However, many recipes can make use of that same ingredient.  So the step has a to-one relationship with an ingredient, and the inverse relationship has a to-many with recipe steps (and therefore indirectly to a Recipe).    Oh yeah, data modelling databases…. the one course I had, the professor was out sick for 2 months of it, and somehow nobody at my Uni seemed to care if we were receiving an education or not.  Being a German University, it’s not in their nature to care about quality, it’s in their nature to check if everyone has the stamp on their piece of paper that *proves* they are capable.
  • If you use a Transformable Attribute on your model, your subclass of NSValueTransformer has to do the following:
    – the transformedValueClass is NSData
    – Therefore the transformedValue: method should be returning NSData
    – the reverseTransformedValue: should return your custom type
    – allowsReverseTransformation should be set to YES

Things that are still a problem (will update this later when I find the solution):

  • When I create an association from a data parser (via awakeFromInsert), these aren’t being displayed in the User Interface.  However, if I create an object via the UserInterface, the associations are created.

The Most Useful Resources so far have been:

  • Ray Wenderlich Tutorials for Mac App programming (first (CoreData), second (a simple Mac OSX app), third (Cocoa Bindings))
  • Editing “to-one” relationships with Cocoa Bindings:  AppleDeveloper
  • Apple Documentation (yes, really.  Maybe I am getting better at this, or my Attention Deficit problems that arise when reading boring technical texts is not as bad as it used to be)
  • The one and only  Where would we be without that?!

But anyway, I plan to update this post a bit later.   It’s strange; now I seem to know a lot more, but am unclear how I got to this point.  There was a lot of time spent that feels like wasted time, but I guess that’s to be expected when you try to tackle a lot at once, with nobody to answer  your questions, and a lot of pre-requisite knowledge is also kind of missing.

In the end I’m thrilled that I’m learning this stuff as it only serves to make me a better developer.  At least with Apple technology, which is still really fun to work with.