我正在尝试使绑定项目工作。但是我遇到了一个错误,因为它不喜欢我将代表作为参数传递给另一个委托。
我收到的错误是
"Attempting to JIT compile method '(wrapper runtime-invoke)
:BackgroundFetchResultHandler(object,UIBackgroundFetchResult)' while running
with --aot-only.
请参阅http://docs.xamarin.com/ios/about/limitations有关更多信息。 n"
所以发生的事情是我正在使用PushySDK并创建了一个绑定库项目。绑定项目中的所有内容都起作用,除了BackgroundFetchresulthandler代表。如果我尝试使用动作或功能而不是代表来进行背景fetchresulthandler bindings lib不会编译。
我的apidefinitions.cs文件是
using System;
using Foundation;
using UIKit;
namespace PushySDK
{
public delegate void BackgroundFetchResultHandler(UIBackgroundFetchResult result);
public delegate void NotificationHandler(NSDictionary info, BackgroundFetchResultHandler action);
// @interface Pushy : NSObject
[BaseType(typeof(NSObject), Name = "_TtC8PushySDK5Pushy")]
[DisableDefaultCtor]
interface Pushy
{
// -(instancetype _Nonnull)init:(UIResponder * _Nonnull)appDelegate application:(UIApplication * _Nonnull)application __attribute__((objc_designated_initializer));
[Export("init:application:")]
[DesignatedInitializer]
IntPtr Constructor(UIResponder appDelegate, UIApplication application);
// -(void)setNotificationHandler:(void (^ _Nonnull)(NSDictionary * _Nonnull, void (^ _Nonnull)(UIBackgroundFetchResult)))notificationHandler;
[Export("setNotificationHandler:")]
void SetNotificationHandler(NotificationHandler notificationHandler);
// -(void)register:(void (^ _Nonnull)(NSError * _Nullable, NSString * _Nonnull))registrationHandler;
[Export("register:")]
void Register(Action<NSError, NSString> registrationHandler);
}
}
我试图使用动作而不是委托,但我遇到了相同的错误。如果我将NotificationHandler代表更改为;
public delegate void NotificationHandler(NSDictionary info, int action);
每一个标语都可以正常工作,除了我无法调用回调的事实,因为它是一个int。但是我的推动通知正常工作,一切都很好。
所以我只是想找到一种在不崩溃的情况下拨打此回调的方法。似乎当Xamarin生成绑定代码时,它在决定第二代表应该是哪种类型的情况下遇到很多麻烦。
如果我使用NotificationHandler;
public delegate void NotificationHandler(NSDictionary info, Action<UIBackgroundFetchResult> action);
绑定库不会编译,我会遇到关于无效字符" action '1"
的错误无论如何,有人能想到要实现这一工作。预先感谢!
好吧,所以我最终查看了OBJ文件夹中的编译代码,以查看他们是如何完成第一个委托的。因此,我只是将其复制为将其更改为INTPTR的委托类型。我的API定义文件最终是这样的。
using System;
using Foundation;
using UIKit;
using ObjCRuntime;
namespace PushySDK
{
internal delegate void NotificationHandler(NSDictionary info, IntPtr action);
// @interface Pushy : NSObject
[BaseType(typeof(NSObject), Name = "_TtC8PushySDK5Pushy")]
[DisableDefaultCtor]
interface Pushy
{
// -(instancetype _Nonnull)init:(UIResponder * _Nonnull)appDelegate application:(UIApplication * _Nonnull)application __attribute__((objc_designated_initializer));
[Export("init:application:")]
[DesignatedInitializer]
IntPtr Constructor(UIResponder appDelegate, UIApplication application);
// -(void)setNotificationHandler:(void (^ _Nonnull)(NSDictionary * _Nonnull, void (^ _Nonnull)(UIBackgroundFetchResult)))notificationHandler;
[Export("setNotificationHandler:")]
void SetNotificationHandler(NotificationHandler notificationHandler);
// -(void)register:(void (^ _Nonnull)(NSError * _Nullable, NSString * _Nonnull))registrationHandler;
[Export("register:")]
void Register(Action<NSError, NSString> registrationHandler);
}
}
我在我的AppDelegate类中声明了将分配回调的代表。
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
internal delegate void DBackgroundFetchResultHandler(IntPtr blockPtr, nuint result);
在AppDelegate中声明此内部类别
internal class BackgroundFetchResultHandlerProxy
{
IntPtr blockPtr;
DBackgroundFetchResultHandler invoker;
[Preserve(Conditional = true)]
public unsafe BackgroundFetchResultHandlerProxy(BlockLiteral* block)
{
blockPtr = _Block_copy((IntPtr)block);
invoker = block->GetDelegateForBlock<DBackgroundFetchResultHandler>();
}
[Preserve(Conditional = true)]
~BackgroundFetchResultHandlerProxy()
{
_Block_release(blockPtr);
}
[Preserve(Conditional = true)]
internal unsafe void Invoke(UIBackgroundFetchResult result)
{
invoker(blockPtr, (nuint) (UInt64) result);
}
}
然后我将功能更改为
[Export("handleNotification:completionHandler:")]
internal unsafe void HandleNotification(NSDictionary info, IntPtr actionPtr)
{
var proxy = new BackgroundFetchResultHandlerProxy((BlockLiteral *)actionPtr);
proxy.Invoke(UIBackgroundFetchResult.NewData);
}
,然后我能够致电
pushy.SetNotificationHandler(HandleNotification);