MonoTouch绑定到ObjectiveC库无法正常工作

时间:2013-03-12 00:32:07

标签: objective-c xamarin.ios

.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

我的约束定义:

[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,, );
    //      
}

这些返回null:

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

供应商的入门说明:

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

我匆匆试图重命名一些东西,因为我不确定供应商的代码有多少可以粘贴,所以希望我没有把事情搞糊涂。

这与:Binding #define used as constant

有关

更多信息:

如果我在设备而不是模拟器上运行它,我会收到以下错误:

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

修改

re @Stephane:我更新了代码,不再模糊供应商。我具有约束力的是:http://developer.xtify.com/display/sdk/Getting+Started+with+Apple+Push+Notification+Service,fwiw。我按照你的建议更新了对getXtifyOptions的引用,但是我得到了相同的结果。我尽可能地使用你引用的github库,但我会继续挖掘。

我正在处理的绑定位于:https://github.com/lordscarlet/monotouch-bindings/tree/master/Xtify

4 个答案:

答案 0 :(得分:3)

getVendorOptions的正确绑定应如下所示:

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

get部分和大写按惯例完成。看看为此生成的代码。只要将它绑定为方法而不是属性,GetAppKey就可以了。请注意,它不应返回null但抛出异常。

关于

MyNamespace.Current;

我没有看到任何定义。所以我不知道出了什么问题。

此时,我对如何构建您的本机库并将其包含在您的托管库中感到担心(re:设备上的例外)。确保你做得对,看看https://github.com/mono/monotouch-bindings

中的大量例子

答案 1 :(得分:3)

tl; dr没有编译Options类

我查看了您的项目以及您尝试绑定的功能。看起来有两部分,嵌入式框架,分布式预编译,以及其他一些东西(主要是Options类),包括设置.h的{​​{1}},其中应该在你的应用程序中编译。

除非你创建一个最小的AppKey项目(并为xcode公开一个setter),否则你的绑定无法工作。

另一种选择是抛弃该部分并在C#中完全实现XLXtifyOptions,然后你自己负责设置AppKey。

UPDATE :已编译的embeddedframework的某些api调用将Options作为参数,因此如果仅在C#中定义Options,请确保为每个函数添加AppKey属性或在Options.h文件中定义的属性

希望它有所帮助,你明白我的意思。

答案 2 :(得分:3)

当您需要构建自己的托管选项类时,您是如何做到的(在Extra.cs文件中)

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's the idea
    [Export ("xtLogMessage:content:")]
    public void LogMessage (string header, params string[] message)
    {
        //print the message
    }
}

public enum XLBadgeManageType {
    Inbox,
    Developer
}

这应该会给你一个想法...

答案 3 :(得分:2)

首先,这个API有一个糟糕的设计,它依赖于#define预处理器指令,用于初始配置,如ApiKey,标题上的大量空格......只是提到一些问题。

你可以在这里找到一个绑定项目,请测试它并告诉我它是否能解决你的问题。

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


尚未在绑定上设置APIKey。

在SDK标头文件中,您会发现XLXtifyOptions.hXLXtifyOptions.m这意味着XLXtifyOptions类不在静态XtifyPush内,所以我将两个文件都修改了一点点,创建另一个名为libXtifyLibHelper.a的静态脂肪(ARMv7,ARMv7s和i386)库。

此库包含两个帮助程序objc消息getXtifyOptionsWithAppKey:locationRequired:backgroundLocationRequired:logging:multipleMarkets:manageBadge:getXtifyOptionsWithAppKey:,可帮助您正确设置API密钥。

请使用上述帮助程序之一为您设置API密钥,这些密钥已被绑定为XLXtifyOptions类中的静态方法。

作为旁注,您不必担心libXtifyLibHelper.a,当您构建提供的项目时,它将自动包含在您的DLL中。

希望这有帮助

亚历