Linking MonoTouch to ObjectiveC library does not work

.h:

#import <Foundation/Foundation.h> typedef enum _XLBadgeManagedType { XLInboxManagedMethod = 0, XLDeveloperManagedMethod = 1 } XLBadgeManagedType ; @interface XLXtifyOptions :NSObject { NSString *xoAppKey; BOOL xoLocationRequired ; BOOL xoBackgroundLocationRequired ; BOOL xoLogging ; BOOL xoMultipleMarkets; XLBadgeManagedType xoManageBadge; } + (XLXtifyOptions *)getXtifyOptions; - (NSString *)getAppKey ; - (BOOL) isLocationRequired; - (BOOL) isBackgroundLocationRequired ; - (BOOL) isLogging ; - (BOOL) isMultipleMarkets; - (XLBadgeManagedType) getManageBadgeType; - (void)xtLogMessage:(NSString *)header content:(NSString *)message, ...; @end 

.m:

 #import "XLXtifyOptions.h" #import "XtifyGlobal.h" static XLXtifyOptions *xXtifyOptions=nil; @implementation XLXtifyOptions + (XLXtifyOptions *)getXtifyOptions { if (xXtifyOptions==nil) { xXtifyOptions=[[XLXtifyOptions alloc]init]; } return xXtifyOptions; } -(id)init { if (self = [super init]) { xoAppKey=xAppKey; xoLocationRequired=xLocationRequired; xoBackgroundLocationRequired=xRunAlsoInBackground ; xoLogging =xLogging ; xoMultipleMarkets=xMultipleMarkets; xoManageBadge=xBadgeManagerMethod; } return self; } - (NSString *)getAppKey { return xoAppKey; } - (BOOL) isLocationRequired { return xoLocationRequired; } - (BOOL) isBackgroundLocationRequired { return xoBackgroundLocationRequired; } - (BOOL) isLogging { return xoLogging; } - (BOOL) isMultipleMarkets { return xoMultipleMarkets; } - (XLBadgeManagedType) getManageBadgeType { return xoManageBadge; } - (void)xtLogMessage:(NSString *)header content:(NSString *)format, ... { va_list args; va_start(args, format); if (xoLogging) { NSString *prettyFmt=[NSString stringWithFormat:@"%@ %@", header,format]; NSLogv(prettyFmt, args); } va_end(args); } @end 

Global.h:

 #define xAppKey @"abc123" #define xLocationRequired NO #define xRunAlsoInBackground FALSE #define xBadgeManagerMethod XLInboxManagedMethod #define xLogging TRUE #define xMultipleMarkets FALSE 

My binding definition:

 [BaseType (typeof (NSObject))] public interface XLXtifyOptions { [Static] [Export ("xtifyOptions")] XLXtifyOptions Options { get;} [Export ("getAppKey")] string GetAppKey (); [Export ("isLocationRequired")] bool IsLocationRequired (); [Export ("isBackgroundLocationRequired")] bool IsBackgroundLocationRequired (); [Export ("isLogging")] bool IsLogging (); [Export ("isMultipleMarkets")] bool IsMultipleMarkets (); [Export ("getManageBadgeType")] XLBadgeManagedType GetManageBadgeType (); // [Export ("xtLogMessage:content:...")] // void XtLogMessagecontent... (string header, string message,, ); // } 

They return null:

 XLXtifyOptions.Options; new XLXtifyOptions().GetAppKey(); 

Instructions for beginners:

  XLXtifyOptions *anXtifyOptions=[Options getVendorOptions]; [[TheirClass get ]initilizeXoptions:anVendorOptions]; 

I hastily tried to rename some things because I'm not sure how much vendor code is approved for insertion, so I hope I haven't confused the questions.

This is due to: #define binding used as constant

ADDITIONAL INFORMATION:

If I run this on the device, and not in the simulator, I get the following error:

 Unhandled managed exception: Wrapper type 'XtifyPush.XLXtifyOptions' is missing its native ObjectiveC class 'XLXtifyOptions'. 

EDIT

re @Stephane: I updated the code so that I no longer hide the provider. I am required: http://developer.xtify.com/display/sdk/Getting+Started+with+Apple+Push+Notification+Service , fwiw. I updated the link to getXtifyOptions as you recommended, but I have the same result. I got, as far as I know, with the github library that you referenced, but I will continue to dig.

The binding I'm working on is available at: https://github.com/lordscarlet/monotouch-bindings/tree/master/Xtify

+4
source share
4 answers

First of all, this API has a terrible design, it relies on #define preprocessor directives for initial configurations like ApiKey, tons of spaces in the headers ... just to mention a few issues.

You can find the Binding Project here, please check it and tell me if it solves your problems.

https://dl.dropbox.com/u/2058130/random%20stuff/XtifyLib.zip


APIKey has not been set in your bindings.

Inside the SDK header files you will find XLXtifyOptions.h and XLXtifyOptions.m , which means that the XLXtifyOptions class does not live inside Static XtifyPush , so I took both files, changed them a bit and created another static fat (ARMv7, ARMv7s and i386), which called libXtifyLibHelper.a .

This library contains two objc helper messages getXtifyOptionsWithAppKey getXtifyOptionsWithAppKey:locationRequired:backgroundLocationRequired:logging:multipleMarkets:manageBadge: and getXtifyOptionsWithAppKey: to help you set the API key correctly.

Please use one of the above helpers to set the API key, those were linked as static methods inside the XLXtifyOptions class.

As a side note, you do not need to worry about libXtifyLibHelper.a , when you create the provided project, it will be automatically (TM) included in your DLL.

Hope this helps

Alex

+2
source

The correct binding for getVendorOptions should look like this:

 [Static] [Export ("vendorOptions")] Options Options { get;} 

part of get , and capitalization - by agreement. Look at the code generated for this. GetAppKey is great if you bind it as a method, not a property. Note that it should not return null, but it throws an exception.

ABOUT

 MyNamespace.Current; 

I do not see any definitions. So I don’t know what happened.

At this point, I have some problems with the way you create your own library and enable it inside your managed library (re: exception on device). Make sure you do it right, look at a lot of examples at https://github.com/mono/monotouch-bindings

+3
source

tl; dr Options class not compiled

I looked at your project and the functionality you are trying to link. It looks like there are 2 parts, a built-in structure that is distributed precompiled and some other materials (mainly the Options class), including .h , which sets the AppKey that you AppKey to compile in your application.

If you do not create a minimal xcode project that does this (and exposes the setter for AppKey ), then you will not be able to work with it.

Another option is to cut out this part and fully implement XLXtifyOptions in C #, and then you yourself are responsible for setting up AppKey.

UPDATE Some api calls of the compiled inline template use the Parameters as Parameter parameter, so if you define parameters only in C #, be sure to add the [Export] attribute for each function or property defined in the Options.h file

Hope this helps and you get my point.

+3
source

How you need to create your own managed class Options, how you can do it (in Extra.cs file)

 public class XLXtifyOptions : NSObject { static XLXtifyOptions options; [Export ("getXtifyOptions")] //not sure that one will be ever called by obj-C code public static XLXtifyOptions XtifyOptions () { return options ?? (options = new XLXtifyOptions () { appKey = "yourappkey", }); } string appKey; [Export ("getAppKey")] public string GetAppKey () { return appKey; } //same for all the getters [Export ("getManageBadgeType") public XLBadgeManageType GetManageBadgeType () { return manageBadge; } //Have to check if this is the right way to bind method with variable lengths argument, but that the idea [Export ("xtLogMessage:content:")] public void LogMessage (string header, params string[] message) { //print the message } } public enum XLBadgeManageType { Inbox, Developer } 

That should give you an idea ...

+3
source

All Articles