IM & NetworkiOS网络相关swift学习

iOS网络层设计-Engine 实现

2017-05-13  本文已影响158人  3697d6c42285

iOS 网络层设计


iOS 网络层 Engine 的功能

Engine 是使用层调用的,连接着 Client 和使用者。使用者通过 Engine 进行初步处理之后调用 Client。

iOS 网络层 Engine 的分类

Engine 会通过不同的分类,还会额外实现一些特殊的功能:每次都只会请求一次、不允许取消的、多次请求的等。以此,我将 Engine 暂时分类以下几类:

数据上传的 Engine:由于取消请求并不能把你的请求从网络中取消掉,只能取消掉着陆点,所以上传的时候,不允许取消请求。而获取服务器固定数据的话,通过实例化的对象,以最后一次的调用为准,之前的请求全部取消。
获取服务器固定数据的 Engine:如果需要获取服务器的数据,一般都是以最后一次操作为准,如刷新或者加载更多,如果一次性多个请求,在 tableView 刷新数据的时候,有可能会发生刷新过程中,数据源被代替导致崩溃。
需要多次请求的 Engine:在例如多张图片上传的时候,需要判断哪个请求成功,哪个请求失败。在全部请求结束之后做什么操作。

iOS 网络层 Engine 的功能实现

首先是 BaseAPIConfig 的实现:


@interface BaseAPIConfig : NSObject
/// 地址
@property (nonatomic, copy) NSString *url;
/// 方法
@property (nonatomic, copy) NSString *method;
/// 参数
@property (nonatomic, copy) NSDictionary *param;

@end

BaseAPIConfig 是方法接口配置的参数,后面回根据需求或者分类不同而增加或减少。将参数提取出来单独归类是为了让方法的参数减少,并且在以后增加参数的时候,不需要增加方法,只需修改原先方法即可。
url 是请求地址,是所有的请求都需要的基础条件之一,不过有些情况会将url写死。
method 是请求的方法;
param 是请求的参数,也是最核心的部分。可以上传的包括字典、数组、字符串等。
其余的参数可以根据需求进行更改,如果是图片或者文件或者其他的,也可以增加image等参数。

其次是 BaseEngine 的实现

/**
 基础请求
 */
@interface BaseEngine : NSObject <NetClientDelegate>
/// 成功回调
@property (nonatomic, strong) void (^success)(NSDictionary* dict);
/// 失败回调
@property (nonatomic, strong) void (^fail)(NSDictionary* dict);
/// 数据任务
@property (nonatomic, strong) NSURLSessionDataTask *task;
/// 接口配置
@property (nonatomic, strong) BaseAPIConfig *config;

#pragma mark- method
/**
 上传并返回数值
 */
- (void)startRequestWithConfig:(BaseAPIConfig *)config
                 successBlock:(void(^)(NSDictionary* dict))successBlock
                    failBlock:(void(^)(NSDictionary* dict))failBlock;

/**
 上传并返回数值
 */
- (void)startRequestWithConfig:(BaseAPIConfig *)config
                  successBlock:(void(^)(NSDictionary* dict))successBlock;

/**
 取消任务
 */
- (void)cancleTask;
@end

#import "BaseEngine.h"

@implementation BaseAPIConfig
@end

@implementation BaseEngine

#pragma mark- <NetClientDelegate>
- (void)netClientSuccess:(NSDictionary *)successDict WithTask:(NSURLSessionDataTask *)task {
    self.task = nil;
    if (self.success) {
        self.success(successDict);
    }
}

- (void)netClientFail:(NSDictionary *)failDict WithTask:(NSURLSessionDataTask *)task {
    self.task = nil;
    if (self.fail) {
        self.fail(failDict);
    }
}

#pragma mark- public method
- (void)cancleTask {
    if (self.task && [self.task respondsToSelector:@selector(cancel)]) {
        [[NetClient shareNetClient] cancleTask:self.task];
        self.task = nil;
    }
    
}

- (void)startRequestWithConfig:(BaseAPIConfig *)config
                  successBlock:(void(^)(NSDictionary* dict))successBlock {
    [self startRequestWithConfig:config successBlock:successBlock failBlock:nil];
}

- (void)startRequestWithConfig:(BaseAPIConfig *)config
                 successBlock:(void(^)(NSDictionary* dict))successBlock
                    failBlock:(void(^)(NSDictionary* dict))failBlock {
    self.success = successBlock;
    self.fail = failBlock;
    self.task = [[NetClient shareNetClient] postToMethod:config.method WithDict:config.param delegate:self];
}
@end

这是最基础的实现,实现的是普通的请求、也可以单独使用。
处理了以下几件事情:

  1. config进行解析,并传到client中进行处理。
  2. 将接口的回调进行处理,并判断通过block返回到使用层。
  3. 允许使用层取消任务。

其他的几种分类都是为了实现不同方向的功能,在base之上做的修改。

部分分类功能实现

// 数据获取
// DownLoadEngine

#pragma mark- public method
- (void)startRequestWithConfig:(BaseAPIConfig *)config
                  successBlock:(void(^)(NSDictionary* dict))successBlock
                     failBlock:(void(^)(NSDictionary* dict))failBlock {
    // 只保存一次的task
    if (self.task && [self.task respondsToSelector:@selector(cancel)]) {
        [self.task cancel];
    }
    
    [super startRequestWithConfig:config successBlock:successBlock failBlock:failBlock];
}
// 数据上传
// UpLoadEngine

- (void)cancleTask {
    return;
}

+ (void)startRequestWithConfig:(BaseAPIConfig *)config
                  successBlock:(void(^)(NSDictionary* dict))successBlock {
    
    [[UploadEngine new] startRequestWithConfig:config successBlock:successBlock failBlock:nil];
}

+ (void)startRequestWithConfig:(BaseAPIConfig *)config
                  successBlock:(void(^)(NSDictionary* dict))successBlock
                     failBlock:(void(^)(NSDictionary* dict))failBlock {
    [[UploadEngine new] startRequestWithConfig:config successBlock:successBlock failBlock:failBlock];
}
// 多次请求 Engine
// MultipleEngine

#import "MultipleEngine.h"

@implementation MultipleEngine

#pragma mark- <NetClientDelegate>
- (void)netClientSuccess:(NSDictionary *)successDict WithTask:(NSURLSessionDataTask *)task {
    if ([self.tasksArray containsObject:task]) {
        [self.tasksArray removeObject:task];
    }
    
    if (self.success) {
        self.success(successDict);
    }
}

- (void)netClientFail:(NSDictionary *)failDict WithTask:(NSURLSessionDataTask *)task {
    if ([self.tasksArray containsObject:task]) {
        [self.tasksArray removeObject:task];
    }
    if (self.fail) {
        self.fail(failDict);
    }
}
#pragma mark- public method
- (void)cancleAllTask {
    for (NSURLSessionDataTask *task in self.tasksArray) {
        [[NetClient shareNetClient] cancleTask:task];
    }
    [self.tasksArray removeAllObjects];
}

- (void)cancleTaskAtIndex:(NSInteger)index {
    if (index >= self.tasksArray.count) {
        return;
    }
    [[NetClient shareNetClient] cancleTask:self.tasksArray[index]];
    [self.tasksArray removeObjectAtIndex:index];
}

- (void)cancleTask {
    if (self.task && [self.task respondsToSelector:@selector(cancel)]) {
        [[NetClient shareNetClient] cancleTask:self.task];
        self.task = nil;
        [self.tasksArray removeObject:self.task];
    }
    
}
- (void)startRequestWithConfig:(BaseAPIConfig *)config
                  successBlock:(void(^)(NSDictionary* dict))successBlock
                     failBlock:(void(^)(NSDictionary* dict))failBlock {
    // 只保存一次的task
    [super startRequestWithConfig:config successBlock:successBlock failBlock:failBlock];
    [self.tasksArray addObject:self.task];
}

#pragma mark - getter/setter
- (NSMutableArray *)tasksArray {
    if (!_tasksArray) {
        _tasksArray = [NSMutableArray array];
    }
    return _tasksArray;
}
@end

多次请求的修改的比较多,原因是他需要从单个任务转换为任务数组,所有跟任务有关的都需要重写导致的。

至此,大致的Engine功能已经实现。

上一篇 下一篇

猜你喜欢

热点阅读