2016-06-27 4 views
0

Ich werde mein Bestes in Englisch tun, um das Problem zu erklären. Ich versuche gerade Xamarin zu überprüfen, ob wir unsere iOS App und Android App auf diese migrieren werden, denn es scheint wirklich nett zu sein.Xamarin IOS kann keine asynchrone Task-Steuerung erstellen

Der kleine Test, den ich mache, ist nur meine einfache Login-Seite zu testen.

Ich bin wirklich neu in CSharp, so sorry im Voraus, wenn ich dumm und einfache Fragen stellen ...

werde ich zunächst die Umsetzung einführen, dann das Problem an, dann von diesem Post beenden.

[UMSETZUNG]

Also das ist, was ich habe RestSharp (Rest library client) Bibliothek von Nuggets getan werden. Ich habe ein gemeinsames Projekt, das in Android App und IOs App verwendet wird (um den Job nur einmal zu machen). Ich arbeite mit Xamarin Studio auf Mac.

In meinem LoginApiManager.cs Ich habe eine „Basis“ Umsetzung wie folgt aus:

public interface UserConnectionStates 
    { 
     //Regroup all state created above 
     void userIsConnected(User user); 
     void userConnectionFailed(IRestResponse<User> response); 
     void userDisconnected(); 
} 

public class LoginApiManager : RestManager 
{ 
    //Used for instance and shared element 
    public static LoginApiManager instance; 

    //Permits to store the information about the current loged in user 
    private User loggedInUser; 

    //All listeners for that class 
    private List<UserConnectionStates> userConnectionStatesListeners = new List<UserConnectionStates>(); 

    public LoginApiManager() 
    { 
     //Create the the Rest Client to make Api Calls 
     base.client = new RestClient(); 
     client.BaseUrl = new Uri(apiPath); 
     client.Authenticator = new HttpBasicAuthenticator(null, null); 
    } 

    public static LoginApiManager getInstance() 
    { 
     if (instance != null) 
     { 
      return instance; 
     } 
     else 
     { 
      return new LoginApiManager(); 
     } 
    } 

    //------- UserConnectionStates Listeners accessors -------- 
    public void addUserConnectionStatesListener(UserConnectionStates listener) 
    { 

     if (!userConnectionStatesListeners.Contains(listener)) 
     { 
      userConnectionStatesListeners.Add(listener); 
     } 

    } 

    public void removeUserConnectionStatesListener(UserConnectionStates listener) 
    { 
     if (userConnectionStatesListeners.Contains(listener)) 
     { 
      userConnectionStatesListeners.Remove(listener); 
     } 
    } 

    /* 
    * Permits to connect a user with a given username and password. It will 
    * call the API and return a User Object containing all information needed 
    * for connection, including token. 
    */ 
    public void connectUserWithUserNameAndPassword(string username, string password) 
    { 

     var request = new RestRequest(Method.POST); 
     request.Resource = "/myApiEndpoints/"; 

     //Add it to the request 
     request.AddParameter("username", username); 
     request.AddParameter("password", password); 

     //Execute the query 
     client.ExecuteAsync<User>(request, (response) => 
     { 
      if (response.StatusCode == System.Net.HttpStatusCode.OK) 
      { 
       //We serialize the user from response 
       loggedInUser = response.Data; 
       foreach (var l in this.userConnectionStatesListeners) 
       { 
        l.userIsConnected(response.Data); 
       } 

      } 
      else 
      { 
       //We send error to the code 
       foreach(var l in this.userConnectionStatesListeners) 
       { 
        l.userConnectionFailed(response); 
       } 
      } 

     }); 
    } 
} 

... Ok, lassen Sie uns weiter, meine LoginViewController implementieren die Schnittstelle UserConnectionStates und sich auf die Zuhörer Liste, um verweisen über die verschiedenen Verbindungsstatusänderungen informiert werden. Genau wie folgt aus:

in meinem LoginController.cs

public partial class LoginController : UIViewController, UserConnectionStates 
{ 
    //Some code here ... 

    public override void ViewDidLoad() 
    { 
     base.ViewDidLoad(); 
     loginManager = LoginApiManager.getInstance(); 
     loginManager.addUserConnectionStatesListener(this); //we create a listener for information about user connection 

    } 

    //Here comme the interface methods... 

    //Interface for listening user connection state 
    public void userIsConnected(User user) 
    { 
     var alertController = UIAlertController.Create("Connexion", "Connexion Success!",UIAlertControllerStyle.Alert); 
     alertController.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Cancel, null)); 
     this.PresentViewController(alertController, true, null); 

    } 

    public void userConnectionFailed(IRestResponse<User> response) 
    { 
     var alert= UIAlertController.Create("Connexion", "Unable to connect", UIAlertControllerStyle.Alert); 
     alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Cancel, null)); 
     PresentViewController(alert, animated: true, completionHandler: null); 
    } 

    public void userDisconnected() 
    { 

    } 

} 

[PROBLEM]

... Hier ist mein Problem, wenn die client.ExecuteAsync (Anfrage, (Antwort)) wird aufgerufen, als Beispiel für einen Erfolg, wird es die Interface-Methode durch das Listener-Objekt öffentliche void userIsConnected (Benutzer Benutzer) von meinem LoginController aufgerufen, aber weil es in einem anderen Thread aufgerufen wird stoppt es bei

var alertController = UIAlertController.Create("Connexion", "Connexion Success!",UIAlertControllerStyle.Alert); 

nos stürzt einfach ab und nichts tun.

machte ich einen Test durch ein einfaches

IRestResponse response = client.Execute(request); 

verwenden und es funktioniert, weil das Verfahren in dem gleichen Thema Synchron- und genannt, aber es sperrt die UI bis Aufgabe erledigt ist ...

Was ist der beste Weg in CSharp oder Xamarin, diese Art von Mustern zu implementieren? Wenn es einen anderen Weg gibt, Dinge wie diesen zu tun, werde ich es lernen, aber weil ich neu darin bin, weiß ich nicht, was die beste Praxis für diese Art von Dingen ist, und ich fand das nicht in der Dokumentation (es ist sicher drin, finde es aber nicht leid).

Vielen Dank im Voraus für Ihre Hilfe,

Grüße, Kevin

+0

Vielleicht wird Ihnen das helfen: https://msdn.microsoft.com/en-us/magazine/dn605875.aspx?f=255&MSPPError=-2147217396 –

+0

Danke, ich werde einen Blick darauf werfen! – kevzzz

Antwort

0

Um ehrlich zu sein, ich Ihre aktuelle Codestruktur überdenken würde.Zunächst einmal möchte ich mit RestSharp stoppen und gehen für: Refit

Dies ist ein ziemlich cool Post, die auf etwas Licht kann wie Code zu strukturieren richtig: Mobile resiliency with Xamarin

Verwenden MVVM in Ihrem iOS und Android-Anwendungen. Auf diese Weise können Sie die ViewModels freigeben und mehr Code haben, der wiederverwendbar und getrennt ist.

+0

Nur Awsome, vielen Dank für Ihre Hilfe und die Post. Ich gehe tief in diesen Ansatz, verbunden mit @TomaszKowalczyk Antwort. Ich stoppte meine Migration in einem frühen Stadium, um den besten Ansatz gemäß Ihrem Ratschlag zu übernehmen, jetzt gehen wir zurück zum Code :-). – kevzzz

+0

@kevzzz happy coding1 :-) – Mittchel

Verwandte Themen