2016-05-11 13 views
1

を呼び出すときに、私はiOSのXamarinのプロジェクトを持っているが、私は次のエラーを取得していました:UIの一貫性エラーのiOSアラート

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

このエラーは、次のコードで発生します。私は私のウェルカムビューページで

クリックされたボタンSyncButtonが表示されます。このボタンをクリックすると、RESTを使用してサーバーとデータを同期させることになります。私WelcomeControllerで

私が持っている:タイムアウトまたは他のエラーが本当に存在するとき

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

    } 

アラートが起こるはず。

SyncButtonCore()はこのようになりますデリゲートクラスに含まれています。

RequestWithAlertクラスがある
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); 

私はNativeAlert()関数で私のエラーを取得しています
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); 
     } 

そのコードの最後のビット。これは最終的に私は私がここで間違ってやっているかわからないんだけど、なぜ私は私WelcomeControllerでそれを定義しているため、このアラートを作成することは許されないのです

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

で私のコードでは冒頭で述べたのUIKitエラーがスローされ私のUIThreadは正しいはずですか?

+3

:これにより

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

はこれを交換するために持っていました。メイン/ UIスレッドで明示的にUI操作を実行する必要があります。 – Paulw11

+0

@ Paulw11 'InvokeOnMainThread'で囲んでいただきありがとうございました –

+0

@ user3470987' InvokeOnMainThread'の使い方を示す回答を投稿すると、途中で数人の人に役立つでしょう。 –

答えて

1

問題は私のiOSErrorAlert()にありました。私はInvokeOnMainThread()でそれを囲む必要がありました。なぜなら、UIアクションはメインスレッド(他のクラス/スレッドに渡していたのでやっていない)で実行する必要があるからです。コメントありがとう@ Paulw11。お使いのネット​​ワーク操作は、バックグラウンドスレッドで完了します

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); 
    }); 
} 
関連する問題