0

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

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

谢谢

4

2 回答 2

5

虽然理解 NSURLConnection 很有用,但(你需要)没有必要重新发明轮子。

只需使用AFNetworking。它是异步的,易于使用,并且您会获得不错的附加功能,例如状态栏中的网络活动微调器会在有网络活动时显示。

于 2013-04-25T03:10:02.300 回答
0

我很久以前就经历过这个教条,解决方案是使用 blocks 和AFNetworking

使用块的优点是它允许从同一个控制器调用相同的 API,而无需区分每个调用,因为每个调用都有自己的要执行的块。

如果您需要此类应用程序的完整架构,只需遵循基本的 OOP 原则,将网络通信逻辑分离到一个单例类(AFHTTPClient 的扩展)中,然后可以从模型类中调用,如果是数据密集型应用程序或控制器。

我创建的示例客户端扩展如下。

#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];
}
于 2013-04-25T04:54:11.807 回答