我正在尝试构建一个调用rest API的MonoTouch应用程序,然后处理它返回的数据。我已经成功地完成了这项工作,但我现在正试图使其异步,并在处理时显示“等待”叠加层。我现在已经使用RestSharp ExecuteAsync方法调用了工作,但是我不知道如何使用响应来更新我的UI。
这是在我调用我的API类的ViewController中:
public partial class TestViewController : UIViewController
{
partial void LoginButton_click(UIButton sender)
{
hud = new MTMBProgressHUD(View)
{
LabelText = "Waiting...",
RemoveFromSuperViewOnHide = true,
};
View.AddSubview(hud);
hud.Show(animated: true);
APIClient ApiClient = new APIClient();
TestAPI cd = new TestAPI(ApiClient);
cd.TestApiCall(1, 123); //Could send this as sender parameter
//Need to call this once the API call is complete
//hud.Hide(animated: true);
}
}
这是我的TestAPI类,其中调用了api:
class TestAPI
{
APIClient API;
public TestAPI(APIClient APIClient)
{
this.API = APIClient;
}
public void TestApiCall(int userId, int PIN)
{
RestRequest request = new RestRequest("TestCall", Method.POST);
OpenRequest obj = new OpenRequest
{
User = userId,
PIN = PIN
};
request.AddObject(obj);
API.client.ExecuteAsync(request, response =>
{
callback(response.Content);
});
}
private void callback(string p)
{
//Could pass through the sender from the API call then do: sender.DismissHUD();
throw new NotImplementedException();
}
}
我已经阅读了很多关于异步,任务和等待但我似乎无法让他们以我想要的方式使用RestSharp。我可以将调用ViewController方法作为sender参数发送,当创建TestAPI类,然后在回调函数中引用它时,但这不会使代码在应用程序的其他地方非常可重用。
答案 0 :(得分:2)
我们可以做的是将RestClient.ExecuteAsync<T>
包装在返回Task<T>
的方法中,并在TaskCompletionSource
的帮助下使用任务异步模式实现
首先,让我们将ExecuteAsync<T>
调用包装在TestAPI类中:
class TestAPI
{
APIClient API;
public TestAPI(APIClient APIClient)
{
this.API = APIClient;
}
public Task<T> ExecuteAsync<T>() where T : new()
{
var client = new RestClient();
var taskCompletionSource = new TaskCompletionSource<T>();
RestRequest request = new RestRequest("TestCall", Method.POST);
OpenRequest obj = new OpenRequest
{
User = userId,
PIN = PIN
};
request.AddObject(obj);
try
{
client.ExecuteAsync<T>(request, (response) => taskCompletionSource.SetResult(response.Data));
}
catch (Exception e)
{
taskCompletionSource.SetException(e);
}
return taskCompletionSource.Task;
}
}
现在,您可以在控制器内await
进行呼叫:
public partial class TestViewController : UIViewController
{
// I Assume this is a top level event handler, hence why
// it returns void and not Task
public async void LoginButton_click(UIButton sender)
{
hud = new MTMBProgressHUD(View)
{
LabelText = "Waiting...",
RemoveFromSuperViewOnHide = true,
};
View.AddSubview(hud);
hud.Show(animated: true);
APIClient ApiClient = new APIClient();
TestAPI cd = new TestAPI(ApiClient);
var apiResponse = await cd.ExecuteAsync<YourType>();
hud.Hide(animated: true);
}
}