2017-04-25 2 views
0

Ich versuche, ein Bindings-Projekt zu arbeiten. Aber ich habe einen Fehler gefunden, wo es mir nicht gefällt, einen Delegaten als Parameter an einen anderen Delegaten zu übergeben.Ist es möglich, einen Delegaten als Parameter eines anderen Delegaten in Bindungen Projekt übergeben

Der Fehler, den ich empfange, ist dies;

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

Für weitere Informationen siehe http://docs.xamarin.com/ios/about/limitations. \ N“

Also, was passiert, ist, ich bin mit PushySDK und erstellt ein Bindungsbibliotheksprojekt. Alles im Bindings Projekt mit Ausnahme des Delegierten BackgroundFetchResultHandler funktioniert. Wenn ich versuchen, eine Aktion oder Func anstelle eines Delegierten für die BackgroundFetchResultHandler verwenden die Bindungen werden nicht kompilieren lib

Meine apiDefinitions.cs Datei ist dies,.

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); 
    } 
} 

Ich habe versucht, statt delegate Aktion zu verwenden, aber ich bekomme den gleichen Fehler. Wenn ich den NotificationHandler-Delegaten in ändern möchte;

Everythign funktioniert gut, außer für die Tatsache, dass ich den Rückruf nicht aufrufen kann, weil es ein Int ist. Aber meine Push-Benachrichtigungen funktionieren einwandfrei und alles ist in Ordnung.

Also ich versuche nur eine Möglichkeit zu finden, diesen Callback aufzurufen, ohne einen Absturz zu bekommen. Es sieht so aus, als wenn Xamarin den Binding-Code erzeugt, hat es große Schwierigkeiten, zu entscheiden, welchen Typ der zweite Delegate haben soll.

Wenn ich NotificatioNHandler als dies verwenden;

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

Die Bindungen Bibliothek wird nicht kompilieren und ich erhalte eine Fehlermeldung über ein ungültiges Zeichen „Action`1“

Gibt es trotzdem jemand denken kann, diese Funktion zu erhalten. Danke im Voraus!

Antwort

0

Okay, also habe ich am Ende den kompilierten Code im Ordner obj angesehen, um zu sehen, wie sie den ersten Delegierten gemacht haben. Also habe ich es einfach für den Delegattyp kopiert, indem ich es in IntPtr ändere. Meine API-Definitionsdatei endete so.

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); 
} 
} 

Ich deklariere den Delegaten in meiner Klasse APPDelegate, wo der Rückruf zugewiesen wird.

[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)] 
internal delegate void DBackgroundFetchResultHandler(IntPtr blockPtr, nuint result); 

declare diese innere Klasse innerhalb AppDelegate sowie

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); 
     } 
    } 

und dann änderte ich meine Funktion

[Export("handleNotification:completionHandler:")] 
internal unsafe void HandleNotification(NSDictionary info, IntPtr actionPtr) 
{ 
    var proxy = new BackgroundFetchResultHandlerProxy((BlockLiteral *)actionPtr); 
     proxy.Invoke(UIBackgroundFetchResult.NewData); 
} 

und dann in der Lage Im

pushy.SetNotificationHandler(HandleNotification); 
nennen
Verwandte Themen