iOS:网络应用程序的最佳实践

时间:2013-04-25 02:51:19

标签: iphone ios ipad

我正在为iphone和ipad构建一个新的应用程序,我需要知道与我的API通信的最佳实践,通常我会在每个视图中调用API 1或多次。我发现我应该使用NSURLConnection,但特别是在处理多个连接时将委托分配给self会使组织任务和连接成为一个非常难以处理的过程。

之前有人遇到过这个问题吗?什么是最佳做法?我应该创建一个类来处理所有请求吗?

由于

2 个答案:

答案 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];
}