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
Vielleicht wird Ihnen das helfen: https://msdn.microsoft.com/en-us/magazine/dn605875.aspx?f=255&MSPPError=-2147217396 –
Danke, ich werde einen Blick darauf werfen! – kevzzz