2017-04-25 78 views
0

我試圖獲得綁定項目的工作。但是我遇到了一個錯誤,它不喜歡我將委託作爲參數傳遞給另一個委託。是否有可能通過委託作爲綁定項目中的另一個委託的參數

我收到的錯誤是這個;

"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代表。如果我嘗試使用,而不是爲BackgroundFetchResultHandler委託的動作或Func鍵綁定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); 

Everythign正常工作,除了因爲它是一個int我不能調用回調。但我的推送通知正常工作,一切正常。

所以我只是想找到一種方法來調用這個回調沒有得到崩潰。看起來,當Xamarin生成綁定代碼時,在決定第二個代理應該是什麼類型時遇到了很多麻煩。

如果我使用NotificatioNHandler作爲這個;

public delegate void NotificationHandler(NSDictionary info, Action<UIBackgroundFetchResult> action); 

的綁定庫不會編譯,我得到一個錯誤說是無效字符「Action`1」

反正有任何人能想到得到這個工作。提前致謝!

回答

0

好吧,所以我最終看着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);