I’m trying to create an Android client for a client/server app that has previously only supported iPhone-based clients. The server was not really designed with the intention of supporting other devices, and some of the data I need to be able to process is stored as a chunk of bytes that was generated by using an NSKeyedArchiver to serialize an NSDictionary on the iPhone client.
To handle the deserialization I’m trying to use the Eclipse SWT, which includes Java bindings for Cocoa API calls and classes, including NSKeyedArchiver and NSKeyedUnarchiver. These seem to be working, but NSKeyedUnarchiver.unarchiveObjectWithData() returns an id type, and I haven’t been able to figure out how to convert it into something usable (it should actually be an NSDictionary). Obviousing in objective-c a simple cast would do the trick, but attempting the same in Java throws a ClassCastException at runtime:
Exception in thread “main” java.lang.ClassCastException:
org.eclipse.swt.internal.cocoa.id cannot be cast to
org.eclipse.swt.internal.cocoa.NSDictionary
The code I am testing with is:
public static void main(String[] args) throws Exception {
NSAutoreleasePool pool = (NSAutoreleasePool)new NSAutoreleasePool().alloc().init();
//read the test data into a byte array
int read = 0;
byte[] buffer = new byte[1024];
FileInputStream in = new FileInputStream(INPUT);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
while((read = in.read(buffer)) != -1) {
bytes.write(buffer, 0, read);
}
buffer = bytes.toByteArray();
System.out.println("Read " + buffer.length + " bytes");
//load the byte array into an NSData instance
NSData data = NSData.dataWithBytes(buffer, buffer.length);
//deserialize the data
id result = NSKeyedUnarchiver.unarchiveObjectWithData(data);
//error here
NSDictionary dictionaryResult = (NSDictionary)result;
pool.release();
}
So what do I need to do to convert ‘result’ from id to something more useful, like NSDictionary?
Bah, nevermind, I figured it out. The way to get from
idto something usable in SWT is to construct a new instance of the desired concrete type, passing theidas a parameter to the constructor. Like:Obvious enough, when you think about it.