我正在为iphone和ipad构建一个新的应用程序,我需要知道与我的API通信的最佳实践,通常我会在每个视图中调用API 1或多次。我发现我应该使用NSURLConnection
,但特别是在处理多个连接时将委托分配给self
会使组织任务和连接成为一个非常难以处理的过程。
之前有人遇到过这个问题吗?什么是最佳做法?我应该创建一个类来处理所有请求吗?
由于
答案 0 :(得分:5)
虽然理解NSURLConnection是有用的,(并且你需要),但是没有必要重新发明轮子。
只需使用AFNetworking即可。它是异步的,易于使用,并且您可以获得很好的额外功能,例如状态栏中的网络活动微调器,只要有网络活动就会显示。
答案 1 :(得分:0)
我很久以前就已经完成了这个教条。解决方案是使用块和& AFNetworking
使用块的优点是它允许从同一个控制器调用相同的API,而不需要区分每个调用,因为每个调用都有自己的块要执行。
如果您需要这样一个应用程序的完整架构,只需遵循基本的OOP原则,将网络通信逻辑分成一个单独的类(AFHTTPClient的扩展),然后如果数据密集型应用程序或控制器可以从Model类调用否则。
我创建的示例客户端扩展如下。
#import <Foundation/Foundation.h>
#import <AFNetworking.h>
@interface CRLClient : AFHTTPClient
+ (CRLClient*) sharedClient;
+ (void) setBaseURL:(NSString*)url;
- (void) uploadFiles:(NSArray*)files
path:(NSString*)path
parameters:(NSDictionary*)parameters
progressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block
success:(void (^)(AFHTTPRequestOperation *, id))success failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure;
@end
#import "CRLClient.h"
@implementation CRLClient
static NSString *CRLBaseURL = nil;
+ (void) setBaseURL:(NSString*)url;
{
CRLBaseURL = [url copy];
}
+ (CRLClient*) sharedClient
{
static CRLClient* sharedInstance = nil;
// dispatch_once_t dispOnce;
@synchronized (sharedInstance) {
if (!sharedInstance) {
// dispatch_once(&dispOnce, ^{
sharedInstance = [[CRLClient alloc] initWithBaseURL:[NSURL URLWithString:CRLBaseURL]];
}
// });
}
return sharedInstance;
}
- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (!self) {
return nil;
}
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
[self setDefaultHeader:@"Accept" value:@"application/json"];
self.parameterEncoding = AFJSONParameterEncoding;
return self;
}
- (void) uploadFiles:(NSArray*)files
path:(NSString*)path
parameters:(NSDictionary*)parameters
progressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block
success:(void (^)(AFHTTPRequestOperation *, id))success failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure
{
NSMutableURLRequest *request =
[self multipartFormRequestWithMethod:@"POST"
path:path
parameters:parameters
constructingBodyWithBlock:
^(id <AFMultipartFormData>formData) {
for (CRLMultiPartFile *file in files) {
NSAssert(file.name, @"Name cannot be nil");
NSAssert(file.file, @"Nothing found to upload");
NSAssert(file.filename, @"FileName cannot be nil");
NSAssert(file.mimeType, @"Must set Mime-Type for %@", file.filename);
[formData appendPartWithFileData:file.file name:file.name fileName:file.filename mimeType:file.typeString];
}
}];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:block];
[operation setCompletionBlockWithSuccess:success failure:failure];
[self enqueueHTTPRequestOperation:operation];
}