2017-04-25 8 views
0

バインディングプロジェクトを取得しようとしています。しかし、私は、別の代理人にパラメータとして代理人を渡すのが好きではないというエラーが発生しました。バインディングプロジェクトの別のデリゲートのパラメータとしてデリゲートを渡すことはできますか?

私が受け取っているエラーはこれです。

"Attempting to JIT compile method '(wrapper runtime-invoke) 
:BackgroundFetchResultHandler(object,UIBackgroundFetchResult)' while running 
with --aot-only. 

だから何が起こっていることは、私はPushySDKを使用してバインディングライブラリプロジェクトを作成しています。バインディングプロジェクトのすべてがBackgroundFetchResultHandlerデリゲートを除いて動作します。詳細についてはhttp://docs.xamarin.com/ios/about/limitationsを参照してください\ n」は

。場合は、私がバインディングは文句を言わないコンパイルLIB代わりBackgroundFetchResultHandlerためのデリゲートのアクションまたはのFuncを使用しよう

マイ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 Delegateを変更した場合、

public delegate void NotificationHandler(NSDictionary info, int action); 

Everythignは、コールバックがintであるためコールバックできないという点を除いて正常に動作します。しかし、私のプッシュ通知は正常に動作し、すべて正常です。

だから、このコールバックをクラッシュすることなく呼び出す方法を見つけようとしています。 Xamarinがバインディングコードを生成しているときに、2番目のデリゲートがどのようなタイプになっているのかを決めるのが難しいようです。

私は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); 
を呼び出すことImができます
関連する問題