Search code examples
bindingxamarin.iosxamarinquickblox

Monotouch/Xamarin Binding: Need to set config params before class is created by monotouch


I am creating the iOS bindings for the Quickblox library. Quickblox wrote the QBRequest class to check for config parameters (account id, etc.) in the static 'initialize' method. The library throws an exception if the config parameters are not set.

It seems that monotouch actually creates all the classes before I have an opportunity to set the config data. As a result the exception is uncaught and the app crashes.

I need to somehow call methods on other classes before monotouch creates the QBRequest class. Also, my project runs fine in the simulator. This only happens on the device. Maybe there is a linker or compiler flag I am missing?

Here is the log message from Quickblox and the stack trace:

Sep 30 10:31:30 FamilyMeiOS[3929] <Error>: *** Terminating app due to uncaught exception         'BaseServiceException', reason: 'You have missed setup credentials.
    Please insert following code inside your application 
    [QBApplication sharedApplication].applicationId = applicationID;
    [QBConnection registerServiceKey:authorizationKey];
    [QBConnection registerServiceSecret:authorizationSecret];
    Before any other code, that uses our service.'

Last Exception Backtrace:
0   CoreFoundation                  0x2e3a4ec6 __exceptionPreprocess + 126
1   libobjc.A.dylib                 0x38b3fce2 objc_exception_throw + 34
2   FamilyMeiOS                     0x000d0c62 __23+[QBRequest initialize]_block_invoke (QBRequest.m:42)
3   libdispatch.dylib               0x3902996a dispatch_once_f + 42
4   FamilyMeiOS                     0x000d09e2 +[QBRequest initialize] (QBRequest.m:40)
5   libobjc.A.dylib                 0x38b40554 _class_initialize + 568
6   libobjc.A.dylib                 0x38b44a0a lookUpImpOrForward + 126
7   libobjc.A.dylib                 0x38b4497e _class_lookupMethodAndLoadCache3 + 30
8   libobjc.A.dylib                 0x38b498b4 _objc_msgSend_uncached + 20
9   FamilyMeiOS                     0x02004bba monotouch_create_classes (registrar.m:33672)
10  FamilyMeiOS                     0x02004f5c monotouch_setup (main.armv7.m:82)
11  FamilyMeiOS                     0x0211a278 monotouch_main (monotouch-main.m:225)
12  FamilyMeiOS                     0x02005008 main (main.armv7.m:96)
13  libdyld.dylib                   0x3903dab2 tlv_initializer + 2

In my host project, I do set the required configuration before using the QBRequest class:

//Configure QuickBlox
QuickBlox.QBApplication.Shared.ApplicationID = QUICKBLOX_APP_ID;
QuickBlox.QBConnection.RegisterServiceKey (QUICKBLOX_AUTHORIZATION);
QuickBlox.QBConnection.RegisterServiceSecret (QUICKBLOX_SECRET);
QuickBlox.QBSettings.SetAccountKey (QUICKBLOX_ACCOUNT_KEY);

Any way to step in front of monotouch and set this config data before it tries to create the QBRequest class?


Solution

  • There's no way to run any managed code before that exception occurs.

    However you can run native (C/Objective-C) code, in particular a library initializer:

    __attribute__((constructor))
    static void initialize_quickblox ()
    {    
        [QBApplication sharedApplication].applicationId = applicationID;
        [QBConnection registerServiceKey:authorizationKey];
        [QBConnection registerServiceSecret:authorizationSecret];
    }
    

    So you'd have to create your own native library with this function, and link with it (the easiest is probably to add it to your binding library as a second native library).