2014-06-11 5 views
2

나머지 API를 호출 한 MonoTouch 응용 프로그램을 빌드하고 다시 가져 오는 데이터를 처리하려고합니다. 이 모든 것이 성공적으로 수행되었지만 이제는 비동기로 만들고 처리하는 동안 '대기중인'오버레이를 표시하려고합니다. RestSharp ExecuteAsync 메서드를 사용하여 작동하도록 전화를 받았지만 UI로 응답을 업데이트하는 방법을 모르겠습니다. 내가 비동기에 대한 꽤 읽은비동기 대기 및 작업 작업

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

:이 API가 호출 내 TestAPI 클래스는

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

    } 
} 

입니다 :

내가 내 API 클래스 호출의 ViewController 안에 , 작업 및 기다리고 있지만, 나는 그들이 내가 원하는 방식으로 RestSharp와 함께 일하도록 할 수는 없다. TestAPI 클래스를 생성하고 콜백 함수에서이를 다시 참조 할 때 호출 측 ViewController 메서드를 보낸 사람 매개 변수로 보낼 수 있습니다. 그러나이 코드를 응용 프로그램의 다른 곳에서 재사용 할 수 없습니다.

+1

RestSharp는 현재 TAP 형태로 비동기 지원을 제공하고 있습니다. 그렇지 않은 경우, 랩퍼를 작성하십시오. 그런 다음 async/await를 평소처럼 사용하십시오. – usr

답변

2

우리가 할 수있는 것은 Task<T>을 반환하고 TaskCompletionSource

최초의 도움으로 작업 비동기 패턴를 사용하여 구현되면, TestAPI 클래스 내부의 ExecuteAsync<T> 전화를 포장 할 수있는 방법 내부 RestClient.ExecuteAsync<T> 포장입니다 : 이제

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

    } 
} 
+0

도움을 주셔서 감사합니다. 더 나은 접근 방법 인 것 같습니다. 나는 지금 그것을 GET 요청에 적용하고 응답을 역 직렬화하려고 시도했지만 아무 것도 반환하지는 않는다. GET 할 필요가있는 특별한 것이 있습니까? – Joseph

+0

아니요, 객체가 JSON과 일치하는지 확인해야합니다. –