- 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.
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                