views:

478

answers:

3

I'm trying to use Brandon Walkin's BWSplitView from BWToolkit in a Cocoa PyObjc project. When I run the project I get the following error message:

NSInvalidUnarchiveOperationException - *** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (BWSplitView)

Does this mean his toolkit is incompatible with a PyObc project, so I should just use the default interface builder views? BWToolkit seems pretty much perfect for my program, and I plan to use it elsewhere in my interface.

A: 

I've fixed this using the following steps:
1. Download and install http://github.com/jrydberg/pyobjc-bwtoolkitframework/tree/master
2. Ensure you have BWToolkit.framework installed in /System/Library/Frameworks (this can be done by redownloading BWToolkit and copying the folder across)
3. Use import BWToolkitFramework in main.py

Tom Crayford
+5  A: 

I suspect that you got that error because you had a BWSplitView in a nib/xib file that you were attempting to load. In order to unarchive the objects in a nib file, the runtime needs to be able to create instances of the archived classes (e.g. BWSplitView). The exception that's being thrown is because BWSplitView isn't available to the runtime. In an Objective-C app you would link to the BWToolkit framework and the dynamic linker would do the work of making BWSplitView available to the runtime. In a PyObjC app, you have to explicitly import classes that you want available to the runtime (that aren't linked behind the scenes for you, such as the Cocoa classes). Fortunately, BWToolkit has a bridge support file so you can import it directly (assuming it's in a standard framework location such as /Library/Frameworks). If you need to load a framework that does not have a bridge support file, you can use objc.loadBundle and then use NSClassFromString to get a class object.

On a side note, /System/Library/Frameworks is reserved for Apple-supplied system frameworks. You should not put third-party frameworks in that folder as Apple may wipe that folder at a system update (unlikely but possible). Thrid-party frameworks that are made available to all users on a system should be put in /Library/Frameworks, user-specific frameworks similarly in ~/Library/Frameworks and application specific frameworks in Contents/Frameworks, where within the application's app bundle.

Barry Wark
And application-specific frameworks in (your app bundle)/Contents/Frameworks.
Peter Hosey
A: 

We had a similar message:

*** Terminating app due to uncaught exception ‘NSInvalidUnarchiveOperationException’, reason: ‘*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (MKMapView)’

In our case it was due to a stray entry in the "Framework Search Paths" setting under the target's build settings. When that entry was cleared, the problem went away.

Kristian Domagala