2012-03-05 2 views
2

현재 .NET RESTful 웹 서비스를 사용하여 데이터 업데이트를 제공하는 iOS 5 iPhone 앱을 디자인 중입니다. 응용 프로그램이 처음 설치되면 WS에 연결되어 모든 데이터를 JSON 형식으로 다운로드합니다. 그 후에는 업데이트 만 수행합니다. WS는 각 테이블에 대해 GetAllTableRecords() 및 GetLastUpdatedTableRecords()와 같은 POST 메서드를 제공합니다.iOS 5 NSURLConnection - UI 피드백을 통한 다중 연결 만들기

iOS 5를 사용 중이며 NSURLConnection 및 JSON 직렬화/직렬화가 네이티브 라이브러리에서 올바르게 작동합니다. 각 WS POST 메서드 호출은 현재 모든 대리자 메서드를 사용하여 자체 Obj-C 클래스에 있습니다. 또한 각 클래스는 로컬 데이터 저장소 삽입 및 업데이트를 처리합니다.

각 NSURLConnection은 비동기이며 모든 WS 호출은 뷰 컨트롤러의 버튼 이벤트로 인해 구동됩니다.

내 질문은 :

  1. 이 코드 캡슐화의 관점에서 올바른 설정되고 다시?
  2. UI를 통해 사용자에게 을 알리는 동시에 여러 WS 호출을 처리하는 방법은 무엇입니까?

현재 두 가지 테이블을 다운로드 할 수 있습니다. 이는 앱이 초기 데이터를 얻으려면 WS를 두 번 호출하고 새로 고침하는 동안 WS는 두 번 다시 호출 함을 의미합니다. 각 NSURLConnection은 비동기이므로 연결은 요청을하지만 UI는 대리자가 데이터 다운로드를 처리하는 동안 계속됩니다. 나는 GCD와 NSOperation/Queue에 대한 연구를 해왔지만 솔루션을 코딩하거나 올바른 솔루션인지 알기에는 충분하지 않습니다.

어떤 통찰력이 가장 도움이 될 것입니다!

편집 # 1 : UI에 실시간 업데이트를 다시 제공하는 것은 어떻습니까? Mint 앱은 트랜잭션과 계정을 업데이트 할 때 비슷한 기능을합니다. 요청이 진행되는 동안 하단에 팝업되는 작은 상태 표시 줄이 있습니다.

편집 # 2 : 좋아, 나는 약간 진전이 있다고 생각한다. 우리는 스토리 보드를 사용하고 있으며 엔트리 포인트는 로그인 뷰/컨트롤러입니다. 로그인 버튼을 클릭하면 NSURLConnection이 웹 서비스에 만들어집니다. connectionDidFinishLoading : (NSURLConnection *) 연결에서 응답 상태 코드가 200이면 연결이 수행되어 데이터 동기화보기로 이동합니다. 이 뷰의 목적은 사용자에게 피드백을 제공하면서 데이터베이스를 초기화하거나 업데이트하는 것입니다. 업데이트 또는 초기화 중 두 가지 추가 웹 서비스 호출이 필요합니다. 이것이다 나는 데

@synthesize pvStatus, lbStatus; 

// pvStatus = progress indicator 
// lbStatus = label 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view from its nib. 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
    [self StartDataSync]; 
} 

- (void)StartDataSync 
{  
    [lbStatus setText:@"Syncing data..."]; 
    [pvStatus setProgress:0.0f]; 

    // TODO: Determine if database is popuplated 
    [self PerformInitialSync]; 

    // Next screen 
    [self performSegueWithIdentifier:@"SegueFromSync" sender:self]; 
} 

// Populates data store will data from web service 
- (void)PerformInitialSync 
{ 
    // Kicks off a series of synchronous requests 
    [self DownloadAllEmployeeDataA]; 
} 

- (void)DownloadAllDataA 
{ 
    // Dictonary holds POST values 
    NSMutableDictionary *reqDic = [NSMutableDictionary dictionary]; 

    // Populate POST key/value pairs 
    [reqDic setObject:passWord forKey:@"Password"]; 
    [reqDic setObject:userName forKey:@"UserName"]; 

    NSError *error = nil; 
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:reqDic options:NSJSONWritingPrettyPrinted error:&error]; 

    // Convert dictionary to JSON 
    NSString *requestJSON = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];  

    // Declare Webservice URL, request, and return data 
    NSURL *url = [[NSURL alloc] initWithString:@"http://wsurl/getalla"]; 

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; 
    NSData *postData = [NSData dataWithBytes:[requestJSON UTF8String] length:[requestJSON length]]; 

    // Build the request 
    [request setHTTPMethod:@"POST"]; 
    [request setValue:[NSString stringWithFormat:@"%d", [postData length]] forHTTPHeaderField:@"Content-Length"]; 
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 
    [request setHTTPBody:postData]; 
    [request setCachePolicy:NSURLRequestUseProtocolCachePolicy]; 
    [request setTimeoutInterval:60.0]; 

    NSURLResponse *response; 

    [lbStatus setText:@"Downloading employee data..."]; 
    [pvStatus setProgress:0.1f]; 

    // Make the response 
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 

    // If return data received 
    if(returnData) 
    { 
     // Get the response and check the code 
     NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; 
     int code = [httpResponse statusCode]; 

     // Check to make sure successful code 
     if (code == 200) 
     { 
      // Convert JSON objects to Core Data Entity 
      // Update UIProgressView and Label 

      // Call next WS call 
      [self DownloadAllEmployeeDataA]; 
     } 
    } 
} 

- (void)DownloadAllDataB 
{     
    // Same code as above but with different URL and entity 
} 

내 문제 :

은 여기 내 DataSyncView.m의 통화가 만들어지고있는 것처럼 UIProgressView와 라벨이 업데이트되지 않습니다. 앞서 언급했듯이이 호출을 수행하는 가장 좋은 방법인지는 알지 못합니다. 주 스레드를 차단하고있는 것으로 보이지는 않지만 틀릴 수 있습니다. 다시 한 번 질문을 드리겠습니다. 진행 상황을 UI로 업데이트하면서 여러 URL을 호출하는 가장 좋은 방법은 무엇입니까? 감사!!!

답변

2
// Make the response 
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 

질문에 비동기 적으로 URL 요청을로드했다고하셨습니다. 그러나 위의 코드 줄에서 동기 요청을하고 있습니까?

코드 캡슐화와 재사용 측면에서 올바른 설정입니까?

  • 코드를 보면 MVC를 준수하지 않을 수 있습니다. 보기 컨트롤러가 URL 연결로드를 관리해서는 안됩니다. 클래스를 만들어 위임자가보기 컨트롤러 에 데이터 다운로드 여부를 알려주는 클래스를 만들 수 있습니다.

UI를 통해 사용자에게 정보를 제공하면서 여러 WS 호출을 처리하는 방법은 무엇입니까?

  • 동시 URL 연결 후 NSOperation 과 NSOperationQueue를 사용하도록하십시오. GCD를 피하십시오 (WWDC 2010 세션 208 참조).

내가 겪고있는 문제점은 다음과 같습니다. UIProgressView 및 레이블이 호출이 업데이트됨에 따라 업데이트되지 않습니다.

  • 당신은 메인 스레드에서 동기 URL 요청을하고 있습니다. 코드에 따라 UIProgressView를 업데이트하면 안됩니다.

URL Loading System Programming Guide

내가 가진 또 다른 의견이 메소드 이름은 소문자로 메서드 이름을 시작입니다 참조하십시오. 나머지는 괜찮아 보인다. Coding Guidelines for Cocoa

+0

고마워, 그게 올바른 방향으로 가고있어. 다른 질문이 있지만 다른 주제로 시작하겠습니다. – Joshua