- Home /
Passing NSDictionary from obj-C to C#
I have a Unity app which needs to read data from an iOS library, and I created an interface.mm file to connect that library to Unity.
I set up a GetNumber function in the interface file which returns an int. I can successfully read the int in Unity using [DllImport ("__Internal")] private static extern int GetNumber();
Now all I need to do is pass a NSDictionary instead of an int, but objective-c is incredibly foreign to me and I haven't yet figured out how to make things work.
My current interface code is:
#include "KochavaUnitySupport.h"
extern "C" {
//Works!
int GetNumber()
{
return 3;
}
//Need Help
string GetPastboardAttribute(string pasteboardName)
{
UIPasteboard *pb = [UIPasteboard pasteboardWithName:pasteboardName create:NO];
if (pb) return pb.string;
}
//Need serious help
NSDictionary* GetKochavaInfo()
{
NSDictionary *kochavaInfo = [[KochavaUnitySupport sharedManager]returnKochavaInfo];
return kochavaInfo;
}
}
MANY thanks to anyone that knows what I need to change to make the above code work, and what datatype I should be expecting to receive the NSDictionary in Unity (a Hashtable would be perfect).
Received a tip from SuperPig on IRC that I should try implementing a visitor pattern - iterating through each element of the NSDictionary pointer and activating a c# callback function. Any other ideas, or tips on making this work?
Ok, I now have this code working perfectly: http://pastebin.com/P2wCkiWe Unfortunately, I'd rather not rely on iOS 5's builtin JSON library, so I am now working on some code to build the JSON string manually through string concatenation. Any suggestions?
Answer by Aubrey-Falconer · Dec 16, 2012 at 06:57 AM
Done! This code should be extremely useful to anyone that happens to encounter similar situations in the future:
#import "JSONKit.h"
char* AutonomousStringCopy (const char* string)
{
if (string == NULL)
return NULL;
char* res = (char*)malloc(strlen(string) + 1);
strcpy(res, string);
return res;
}
extern "C" {
char* GETDICTIONARY()
{
NSDictionary *myNSDict = //Get Dict Here
//Works great for iOS 5+
//NSError *error;
//NSData *jsonData = [NSJSONSerialization dataWithJSONObject:myNSDict options:0 error:&error];
//NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
//Much more compatible library
NSString *jsonString = [myNSDict JSONString];
const char* jsonChar = AutonomousStringCopy([jsonString UTF8String]);
return AutonomousStringCopy(jsonChar);
}
}
Ins$$anonymous$$d of implementing your own AutonomousStringCopy
, why don't you use `strdub`?
Is there a reason you didn't use NSString's method for generating CStrings?
Answer by superpig · Dec 16, 2012 at 04:14 AM
It's not possible for Unity to work directly with an NSDictionary, as far as I know, so what you need to do is have your C DLL access it on your behalf. I'd use something like a visitor pattern for this:
void GetKochavaInfo(void (*visitorFn)(const char* key, const char* value))
{
// Get your NSDictionary
for(NSString* key in dictionary)
{
NSObject* value = [dictionary objectForKey:key];
// do something with value to get a string out of it
visitorFn([key UTF8String], [valueStr UTF8String]);
}
}
On the C# side, you'd then declare a delegate type to describe the function pointer:
public delegate void DictionaryVisitorHandler(string key, string value);
and then the external function definition:
public extern void GetKochavaInfo(DictionaryVisitorHandler handler);
Good idea. I am currently leaning towards JSON serialization, but i'll keep your solution in $$anonymous$$d
Answer by david90 · Feb 18, 2014 at 12:14 PM
I use https://developers.facebook.com/docs/unity/reference/current/Json/ on C# side to deserialize JSON in unity.