2016-05-11 5 views
1

Aufruf habe ich ein iOS Xamarin Projekt wurde ich die folgende Störung erhalte:UI Konsistenzfehler, wenn iOS Benachrichtigungs

UIKit Consistency error: you are calling a UIKit method that 
    can only be invoked from the UI thread. 

Dieser Fehler mit dem folgenden Code auftritt:

In meiner Willkommen Ansicht Seite Ich habe eine Schaltfläche namens SyncButton10, die angeklickt wird. Dieser Klick auf die Schaltfläche soll Daten mit einem Server mit REST synchronisieren. Ich

In meinem WelcomeController haben:

.... 
SyncButton.TouchUpInside += async (object sender, EventArgs e) => { 
      SyncButton.Enabled = false; 

      await welcomeDelegate.syncButtonCore (cred, iOSErrorAlert); 

      SyncButton.Enabled = true; 
     }; 
.... 

public void iOSErrorAlert(string LoginErrorTitle, string LoginErrorMessage){ 
     var Alert = UIAlertController.Create (LoginErrorTitle, LoginErrorMessage, UIAlertControllerStyle.Alert); 
     Alert.AddAction (UIAlertAction.Create ("OK", UIAlertActionStyle.Cancel, null)); 
     PresentViewController (Alert, animated: true, completionHandler: null); 

    } 

Warnungen passieren soll, wenn es wirklich ein Timeout oder ein anderer Fehler ist.

Die SyncButtonCore() in einem Delegat-Klasse enthalten, die wie folgt aussieht:

public async Task syncButtonCore(UserCredentials cred, RequestWithAlertDelegate.ErrorAlert NativeAlert){ 
     await Task.Run (async()=>{ 
      RequestWithAlertDelegate requestWithAlert = new RequestWithAlertDelegate(); 
      string URL = URLs.BASE_URL + URLs.CASELOAD + "/" + cred.PID; 
      await requestWithAlert.RequestWithRetry(URL, cred.UserID, cred.Password, NativeAlert, null, async delegate (string Response1){...}, 1); 

Wo ist mein RequestWithAlert Klasse:

public async Task RequestWithRetry (string URL, string UserID, string Password, ErrorAlert NativeAlert, SyncAction Action, AsyncAction Action2, int times) 
    { 
     ...make sure legit credentials... 
     if (LoginError) { 
      NativeAlert (LoginErrorTitle, LoginErrorMessage); 
     } 

Wo erhalte ich am NativeAlert meine Fehler() Funktion in das letzte Bit des Codes. Welche wirft schließlich die UIKit Fehler am Anfang in meinem Code erwähnt bei

var Alert = UIAlertController.Create (LoginErrorTitle, LoginErrorMessage, UIAlertControllerStyle.Alert); 

Ich bin nicht sicher, was ich falsch hier tue und warum darf ich nicht diese Warnung schaffen, weil ich es in meinem WelcomeController definieren die Ist mein UIThread korrekt?

+3

Ihr Netzbetrieb auf einem Hintergrundthread wird abgeschlossen. Sie müssen Ihre UI-Vorgänge explizit im Haupt/UI-Thread ausführen. – Paulw11

+0

@ Paulw11 Danke, um mit 'InvokeOnMainThread' umgeben hat den Trick –

+0

@ user3470987 Wenn Sie eine Antwort veröffentlichen, die zeigt, wie Sie 'InvokeOnMainThread' verwendet haben, wird es wahrscheinlich ein paar Leute auf dem Weg helfen. –

Antwort

1

Problem war in meiner iOSErrorAlert() Funktion. Ich musste es mit dem InvokeOnMainThread() umgeben, weil UI-Aktionen im Hauptthread ausgeführt werden sollten (was ich nicht tat, weil ich es an andere Klassen/Threads weitergab). Danke @ Paulw11 für den Kommentar.

Wäre dies zu ersetzen:

public void iOSErrorAlert(string LoginErrorTitle, string LoginErrorMessage){ 
    var Alert = UIAlertController.Create (LoginErrorTitle, LoginErrorMessage, UIAlertControllerStyle.Alert); 
    Alert.AddAction (UIAlertAction.Create ("OK", UIAlertActionStyle.Cancel, null)); 
    PresentViewController (Alert, animated: true, completionHandler: null); 
} 

mit diesem:

public void iOSErrorAlert(string LoginErrorTitle, string LoginErrorMessage){ 
    InvokeOnMainThread (() => { 
     var Alert = UIAlertController.Create (LoginErrorTitle, LoginErrorMessage, UIAlertControllerStyle.Alert); 
     Alert.AddAction (UIAlertAction.Create ("OK", UIAlertActionStyle.Cancel, null)); 
     PresentViewController (Alert, animated: true, completionHandler: null); 
    }); 
}