繁体   English   中英

子类AFHTTPRequestOperationManager?

[英]Subclass AFHTTPRequestOperationManager?

我发现自己在整个代码中使用AFHTTPRequestOperationManager重复了很多代码,因此我考虑将其子类化,因此我可以将其设置为单例,并将所有代码放在子类中,而不是通过它扩展我的项目。 然而,在AFNetworking 2.0( http://nshipster.com/afnetworking-2/ )的NSHipster剧集中,它说:

2.0中的主要区别在于,您实际上将直接使用此类,而不是将其子类化,原因在“序列化”部分中进行了解释。

由于AFNetworking和NSHipster拥有相同的作者,我认为这是一个有效的论点。

所以我的问题是,人们是否将AFHTTPRequestOperationManager子类AFHTTPRequestOperationManager一个类中的大多数网络代码,或者我在使用框架时忽略了什么?

这就是我解决它的方式。

我创建了一个新的MyDBClient对象, AFHTTPRequestOperationManager是一个属性。 MyDBClient是一个单例类。 然后我从我的视图控制器调用我的MyDBClient,然后设置操作管理器并启动请求。 这样做的好处是更容易在AFHTTPRequestOperationManager (iOS7之前)和AFHTTPPSessionManager (iOS7)之间切换。

我有一个连接类的对象。 这会向任何对象广播不同的通知,可以通过[NSNotificationCenter defaultCenter]注册。

-(void) requestData
{
    [[NSNotificationCenter defaultCenter] postNotificationName:kCuriculumDataSourceFetchingStarted object:nil];

    [_sessionManager setDataTaskDidReceiveDataBlock:^(NSURLSession *session,
                                                      NSURLSessionDataTask *dataTask,
                                                      NSData *data)
     {
        if (dataTask.countOfBytesExpectedToReceive == NSURLSessionTransferSizeUnknown)
            return;

        NSUInteger code = [(NSHTTPURLResponse *)dataTask.response statusCode];
        if (!(code> 199 && code < 400))
            return;

        long long  bytesReceived = [dataTask countOfBytesReceived];
        long long  bytesTotal = [dataTask countOfBytesExpectedToReceive];

        NSDictionary *progress = @{@"bytesReceived": @(bytesReceived),
                                   @"bytesTotal":    @(bytesTotal)};

        [[NSNotificationCenter defaultCenter] postNotificationName:kCuriculumDataSourceProgress object:nil userInfo:progress];
    }];



    [self.sessionManager GET:@"recipient/"
                  parameters:nil
                     success:^(NSURLSessionDataTask *task, id responseObject)
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:kCuriculumDataSourceFetchingSucceeded
                                                            object:nil
                                                          userInfo:@{@"response": responseObject}];
    }
                     failure:^(NSURLSessionDataTask *task, NSError *error)
    {

        NSUInteger code = [(NSHTTPURLResponse *)task.response statusCode];
        NSString *msg;
        switch (code) {
            case kCuriculumDataSourceFetchErrorAPIKeyNotFound:  msg = @"Api Key not found or revoked"; break;
            case kCuriculumDataSourceFetchErrorServerDown:      msg = @"Server Down"; break;
            default:    msg = [error localizedDescription]; break;
        }


        [[NSNotificationCenter defaultCenter] postNotificationName:kCuriculumDataSourceFetchingFailed
                                                            object:nil
                                                          userInfo:@{@"error": msg}];
    }];
}

将接收到的数据写入Core Data的对象将注册kCuriculumDataSourceFetchingSucceeded并可以通过notification.userInfo[@"response"]访问收到的响应。
ViewController将注册kCuriculumDataSourceFetchingSucceededkCuriculumDataSourceFetchingFailedkCuriculumDataSourceProgress

我只实例化一个对象,如果它是单例,我不必费心。 因此,我不必对它进行子类化或做一些相关的对象技巧来获得一个返回单例对象的方法。 对从网络获取的数据感兴趣的类只会监听通知 - 他们不必知道获取数据的对象,也不必知道它是否是唯一的类型。

连接类对象本身可以注册到其他类将发布的通知以触发新的数据提取。


视图控制器可以注册通知

-(void)configure
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fetchingStarted:) name:kCuriculumDataSourceFetchingStarted object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fetchingSucceeded:) name:kCuriculumDataSourceFetchingSucceeded object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fetchingFailed:) name:kCuriculumDataSourceFetchingFailed object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataSourceProgress:) name:kCuriculumDataSourceProgress object:nil];
}

在这种情况下,视图控制器和网络控制器导入相同的配置头文件,该文件定义了像kCuriculumDataSourceFetchingSucceeded这样的标记。 但由于这些是普通的NSStrings,因此即使是这种依赖也可以轻松避免。

用于处理通知的视图控制器方法的示例

-(void)dataSourceProgress:(NSNotification *)notification
{
    float bytesReceived = (float)[notification.userInfo[@"bytesReceived"] longLongValue];
    float bytesTotal = (float)[notification.userInfo[@"bytesTotal"] longLongValue];

    float progress = bytesReceived / bytesTotal;

    dispatch_async(dispatch_get_main_queue(), ^{
        self.progressView.progress = progress;
        self.imgView.layer.mask = self.progressView.layer;

    });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM