48

나는 개발중인 대형 앱의 요청 아키텍처에 대한 내 접근 방식을 다시 생각하는 중입니다. 나는 실제로 요청을하기 위해 ASIHTTPRequest를 사용하고 있지만 다른 뷰 컨트롤러에서 수행되는 많은 다른 작업의 결과로 많은 유형의 요청이 필요하기 때문에 이러한 요청을 구성하는 최상의 시스템을 찾으려고합니다.많은 네트워크 요청을하는 iOS 응용 프로그램을위한 최고의 아키텍처?

저는 현재 앱 델리게이트에 의해 유지되고 요청 신호를 보내야하는 NSNotifications를 수신 대기하는 싱글 톤 "리퀘 스터"를 만들고 있습니다. 그들은 요청을하고, 응답을 듣고, 응답 데이터와 함께 새로운 NSNotification을 보냅니다. 이것은 대부분의 문제점을 해결하지만 실패한 요청이나 동일한 요청을 동일한 싱글 톤 요청자에게 우아하게 처리하지는 못합니다.

누구나 iOS 앱에서 다양한 유형의 요청을 만들기 위해 명확한 OO 아키텍처를 고안해도됩니다.

+2

좋은 질문 : NSURLConnection에 대한 연결 관리자를 만든 사람이 한 연결에서 제대로 작동하지만 몇 사람에게는 잘 맞지 않는 사람이기 때문에 이에 대한 답변도 연구했습니다. –

답변

69

시도 몇 가지 접근 방식을 가진 후이 나에게 우수한 결과를주고 하나의 아키텍처, 문서 이해, 유지 및 확장이 용이 :

  • 내가 네트워크 연결 돌보는 하나의 목적을 가지고하자 그것을 "네트워크 관리자"라고 부르십시오. 일반적으로이 객체는 싱글 톤 (Matt Gallagher's Cocoa singleton macro을 사용하여 생성)입니다.
  • ASIHTTPRequest (항상 훌륭한 API)를 사용하기 때문에 네트워크 관리자 내에 ASINetworkQueue ivar를 추가합니다. 네트워크 관리자를 대기열의 위임자로 지정합니다.
  • 내 애플 리케이션이 필요로하는 네트워크 요청 (일반적으로 각 백엔드 REST 상호 작용이나 SOAP 엔드 포인트)에 대한 ASIHTTPRequest의 서브 클래스를 만든다. 이것은 또 다른 이점이 있습니다. (자세한 내용은 아래 참조)
  • 내 컨트롤러 중 하나에서 데이터 (새로 고침, viewDidAppear 등)가 필요할 때마다 네트워크 관리자가 필요한 ASIHTTPRequest 서브 클래스의 인스턴스를 생성 한 다음 큐에 추가합니다 .
  • ASINetworkQueue는 3G, EDGE 또는 GPRS 또는 Wifi 중 어디에 있는지에 따라 대역폭 문제를 처리하고 대역폭이 더 많으며 더 많은 요청을 처리 할 수 ​​있습니다. 이것은 큐에 의해 행해지는데, 이것은 멋지다. 적어도 큐가 이해할 수있는 것들 중 하나이다. 나는 실수하지 않았 으면 좋겠다. :)
  • 요청이 완료되거나 실패 할 때마다 네트워크 관리자가 호출됩니다. 네트워크 관리자는 대기열의 위임자입니다.
  • 네트워크 관리자는 각 요청의 결과를 어떻게 처리해야하는지에 관해서는 알지 못합니다. 따라서 요청시 메서드를 호출합니다.! 요청은 ASIHTTPRequest의 하위 클래스이므로 요청의 결과를 관리하는 코드 (일반적으로 JSON 또는 XML의 실제 객체로의 비 직렬화, 다른 네트워크 연결 트리거, Core Data 저장소 업데이트 등)를 넣을 수 있습니다. 요청 클래스를 통해 공통 이름을 가진 다형 메소드를 사용하여 각 개별 요청 서브 클래스에 코드를 넣으면 IMHO를 디버그하고 관리하기가 매우 쉽습니다.
  • 마지막으로 알림을 사용하여 흥미로운 이벤트에 대해 위의 컨트롤러에 알립니다. 대리인 프로토콜을 사용하는 것은 좋은 생각이 아닙니다. 앱에서 일반적으로 네트워크 관리자와 대화하는 컨트롤러가 많기 때문에 알림이 더 유연합니다 (같은 알림에 여러 컨트롤러가 응답 할 수 있기 때문입니다).

어쨌든, 내가 잠시 동안 해왔 던 방법이며, 솔직히 말해서 꽤 잘 작동합니다.나는 시스템을 수평으로 확장하여 필요할 때마다 더 많은 ASIHTTPRequest 서브 클래스를 추가 할 수 있으며 네트워크 관리자의 코어는 그대로 유지됩니다.

희망이 있습니다.

+0

좋은 답변입니다! 어떻게 시스템을 테스트합니까? 또 다른 큰 관심사는 단위 테스트가 쉬운 아키텍처입니다. – kevboh

+0

감사합니다, 훌륭한 설명. – Epaga

+5

마음에 봄이 빨리 생기면 답장에 관심있는 클래스가 하나 뿐인 경우 알림 대신 블록을 사용할 수 있습니다. –

0

fully-loaded 프로젝트는 좋은 읽을 거리입니다.

+0

이전에는 제대로로드 된 적이 있지만 특정 문제를 잘 처리했지만 여러 가지 응답 유형을 가진 여러 유형의 요청을 처리하는 솔루션을 찾고 있습니다. 핸들링 요청을 완전히로드하는 방법은 nsnotifications 및 asihttprequest를 사용하여 질문에 자세히 설명한 것과 비슷합니다. 알림 및 요청을 체계적으로 구성하는 방법 일지라도 더욱 확장 가능하고 강력한 것을 찾고 있습니다. – kevboh

+1

내 생각에 다른 코드 예제는 애플의 MVCNetworking 샘플에있는'Networking' 폴더입니다. 나는 코멘트를 할 수있는 경험이 없습니다. – ohho

+0

흥미 롭습니다. 나는 이것을 조사해야 할 것이다. – kevboh

1

내가 일반적으로하는 방법은 다음과 같습니다. 나는 네트워크 요청을하기 위해 싱글 톤 객체를 사용했다. 요청을 자주 수행해야하는 경우 AFJetworking 요청을 만들기 위해 일반적으로 AFHTTPRequestOperations (또는 AFJSONRequestOperations)를 받아들이는 NSOperationQueue가 있습니다. 이를 위해 요청의 성공 또는 실패시 실행되는 completionBlock 및 failureBlock 속성이 있습니다. 내 싱글 톤 객체에는 특정 네트워크 요청을 시작하는 메소드가 있으며 그 메소드의 매개 변수로 메소드에 정의 된 블록으로 전달할 수있는 성공 및 실패 블록을 포함합니다. 이 방법으로 전체 응용 프로그램이 네트워크 요청을 할 수 있으며 해당 지점의 응용 프로그램 범위는 메서드에 전달 된 블록의 싱글 톤에서 사용할 수 있습니다. 예를 들어 ... (ARC 사용)

 @implementation NetworkManager 

    -(void)makeRequestWithSuccess:(void(^)(void))successBlock failure:(void(^)(NSError *error))failureBlock 

    { 
     NSURL *url = [NSURL URLWithString:@"some URL"]; 

     NSURLRequest *request = [NSURLRequest requestWithURL:url]; 

     AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 

     [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 
      [responseObject doSomething]; 

      if (successBlock) 
       dispatch_async(dispatch_get_main_queue(), successBlock); 

     } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 

      if (failureBlock) 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        failureBlock(error); 
       }); 
     }]; 

     [self.operationQueue addOperation:op]; 
    } 
@end 

그리고 성공 블록에는 언제든지 전달해야하는 매개 변수를 사용할 수 있습니다.

0

STNetTaskQueue을 시도해보십시오. 요청을 재사용 및 유지 관리 할 수 ​​있습니다.

관련 문제