Best architecture for an iOS application that makes many network requests?
我正在重新思考我正在开发的一个大型应用程序的请求架构的方法。我目前正在使用asihttpRequest来实际发出请求,但是由于在不同的视图控制器中采取了许多不同的操作,所以我需要许多不同类型的请求,所以我正在尝试建立组织这些请求的最佳系统。
我目前正在构建由应用程序代理保留的单例"请求者",他们坐在那里倾听需要发出请求信号的nsnotifications;他们发出请求,倾听响应,并发送带有响应数据的新nsnotification。这解决了我的大部分问题,但不能优雅地处理失败的请求或同时向同一个单例请求者发出的请求。
有谁能成功地设计出一个清晰的OO架构来在iOS应用程序中提出许多不同类型的请求?
在尝试了几种方法之后,这是一种能够给我带来出色结果、易于记录、理解、维护和扩展的体系结构:
- 我有一个处理网络连接的对象,我们称它为"网络管理器"。通常,这个对象是一个单例(使用MattGallagher的CocoaSingleton宏创建)。
- 由于您使用AsiHTTPRequest(我一直这样做,非常好的API),所以我在我的网络管理器中添加了一个AsInetWorkQueueIvar。我使网络管理器成为该队列的代理。
- 我为我的应用程序所需的每种网络请求(通常,对于每个后端REST交互或SOAP端点)创建AsiHTTPRequest的子类。这还有另一个好处(请参阅下面的详细信息:)
- 每当我的某个控制器需要某些数据(刷新、视图显示等)时,网络管理器都会创建所需asihttpRequest子类的实例,然后将其添加到队列中。
- asinetWorkQueue负责处理带宽问题(取决于您是使用3G、EDGE还是GPRS或WiFi,您有更多的带宽,并且可以处理更多的请求等)。这是由队列完成的,它很酷(至少,这是我理解这个队列所做的事情之一,我希望我没有弄错)。
- 每当请求完成或失败时,都会调用网络管理器(记住,网络管理器是队列的委托)。
- 网络管理器不知道如何处理每个请求的结果;因此,它只对请求调用一个方法!请记住,请求是asihttpRequest的子类,因此您只需将管理请求结果的代码(通常,将JSON或XML反序列化为真实对象,触发其他网络连接,更新核心数据存储等)。将代码放入每个单独的请求子类中,使用具有通用名称的多态方法Accross请求类,可以非常容易地调试和管理IMHO。
- 最后,我使用通知通知通知上面的控制器有关有趣的事件;使用委托协议不是一个好主意,因为在您的应用程序中,通常有许多控制器与您的网络管理器通信,然后通知更灵活(您可以有多个控制器响应同一通知等)。
不管怎样,这就是我做了一段时间的方式,坦率地说,它工作得很好。我可以水平扩展系统,根据需要添加更多的asihttpRequest子类,并且网络管理器的核心保持不变。
希望它有帮助!
这是我通常的做法。我也有一个用于发出网络请求的单例对象。对于必须经常发出的请求,我有一个nsOperationQueue,它接受afhttpRequestOperations(或afjsonRequestOperations),因为我通常使用afNetworking来发出请求。对于这些,在请求成功或失败时执行CompletionBlock和FailureBlock属性。在我的singleton对象上,我将有一个方法来启动一个特定的网络请求,作为该方法的参数,我将包括一个成功和失败块,它可以传递到方法中定义的块中。这样,整个应用程序就可以发出一个网络请求,此时的应用程序范围对于传递给该方法的块中的单个对象是可用的。例如…(使用弧)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | @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 |
你可以让成功模块接受你需要传递的任何参数。
尝试stnettaskqueue,它可以使您的请求可重用和可维护。
完全加载的项目是一个很好的读物。