美文网首页iOS iOS Developer
从零开始设计搭建ios App框架(六)

从零开始设计搭建ios App框架(六)

作者: 潇水渔翁 | 来源:发表于2016-09-23 16:19 被阅读259次

网络接口请求


基本上目前市面上所有app都需要有的功能模块,通过网络接口从服务器获取业务数据。
网络请求模块尽可能与UI界面逻辑分开,在Controller请求数据时尽可能简单。此文将对接口请求模块作一简单地封装。

简要分析
1、API接口请求需要统一入口统一管理。
2、具体的http任务请求(即单个的请求任务HttpClient,不带业务相关逻辑)。
3、跟业务相关的接口定义如接口标识,接口地址。
4、接口请求数据需要签名或者加密。
5、服务器响应后的数据需要按业务解析成UI能用的数据结构对象。
6、接口请求完成后回调。

对象模型

  • PGRequestManager 接口请求管理,为所有业务数据请求提供统一的入口
  • PGHttpClient 封装具体的网络http请求逻辑
  • PGAPI 封装业务相关的接口地址与解析数据入口
  • PGEncrypt 封装一些加密操作,如接口签名等
  • PGDataParseManager 接口请求的回来的数据进行解析
  • PGResultObject 接口请求解析完成后返回给View的数据

PGAPI
定义相关的业务数据接口标识Type,如登录、注册等。

typedef NS_ENUM(NSUInteger, PGApiType) {
    API_TYPE_LOGIN = 1,//登录
    API_TYPE_REGIEST,//注册
    API_TYPE_PRODUCT_LIST,//产品列表
};

定义Api委托协议

@protocol PGApiDelegate <NSObject>
@required
- (void)dataRequestSuccess:(PGResultObject *)resultObj;
- (void)dataRequestFailed:(PGResultObject *)resultObj;
@end

添加获取接口地址与接口数据解析的统一入口。

@interface PGAPI : NSObject

/*
 获取相应的接口地址
 */
+ (NSString *)urlStringWithType:(PGApiType)type;

/*
 解析数据入口
 */
+ (id)parseDataWithType:(PGApiType)type data:(id)data;

@end

//PGAPI.m
@implementation PGAPI

+ (NSString *)urlStringWithType:(PGApiType)type
{
    NSString *urlString = nil;
    switch(type)
    {
        case API_TYPE_LOGIN: {
            urlString = [NSString stringWithFormat:@"%@%@",BASE_URL,@"/u/user/login"];
            break;
        }
        case API_TYPE_REGIEST: {
            urlString = [NSString stringWithFormat:@"%@%@",BASE_URL,@"/u/user/regiest"];
            break;
        }
        default:
            break;
    }
    return urlString;
}

+ (id)parseDataWithType:(PGApiType)type data:(id)data
{
    NSObject *result = nil;
    switch(type)
    {
        case API_TYPE_LOGIN: {
            result = [PGDataParseManager parseLogin:data];
            break;
        }
        case API_TYPE_REGIEST: {
            break;
        }
        default:
            break;
    }
    return result;
}

@end

PGHttpClient 封装具体的网络http请求逻辑

@class PGHttpClient;
@protocol PGHttpClientDelegate <NSObject>
@required
- (void)dataRequestSuccess:(PGResultObject *)resultObj client:(PGHttpClient *)client;
- (void)dataRequestFailed:(PGResultObject *)resultObj client:(PGHttpClient *)client;
@end

/*
 根据业务封装Api接口数据
 */
@interface PGHttpClient : NSObject
@property(nonatomic, assign, readonly)PGApiType apiType;
@property(nonatomic, weak)id<PGApiDelegate> apiDelegate;
@property(nonatomic, weak)id<PGHttpClientDelegate> delegate;
@property(nonatomic, copy)NSString *requestMethod;
/*
 请求策略所用的key值,缓存接口数据与读取接口数据时用。
 */
@property(nonatomic, copy)NSString *strategyKey;

/**
 type: API接口类型
 dicParam: 请求参数
 */
- (instancetype)initWithType:(PGApiType)type requestParam:(NSDictionary *)dicParam;

/**
 开始请求数据
 */
- (void)startRequest;

/**
 取消数据请求
 */
- (void)cancelRequest;

/**
 解析接口返回的json字符数据
 */
- (void)parseData:(NSString *)szString;

@end

PGEncrypt 封装一些加密操作,如接口签名等

@interface PGEncrypt : NSObject

/*
 创建接口签名
 */
+ (NSString *)createSignWith:(NSDictionary *)dictionary;

@end

PGResultObject

#import <Foundation/Foundation.h>

@interface PGResultObject : NSObject
/*
 错误编号
 */
@property(nonatomic, assign)NSInteger nCode;
/*
 错误描述
 */
@property(nonatomic, strong)NSString *szErrorDes;
/*
 接口返回的数据
 */
@property(nonatomic, strong)id dataObject;

@end

PGDataParseManager 所有的业务数据解析,统一一个地方方便修改。

/**
 数据解析管理器,api所有的接口数据都在此文件中解析,方便维护
 */
@interface PGDataParseManager : NSObject

/**
 登录数据解析
 */
+ (id)parseLogin:(NSDictionary *)dictionary;

@end


PGRequestManager 接口请求管理,为所有业务数据请求提供统一的入口

@interface PGRequestManager : NSObject

//普通接口请求
+ (void)startPostClient:(PGApiType)type param:(NSDictionary *)param target:(id<PGApiDelegate>)target tag:(NSString *)tag;
+ (void)startGetClient:(PGApiType)type param:(NSDictionary *)param target:(id<PGApiDelegate>)target tag:(NSString *)tag;

//取消请求
+ (void)cancelClientWithTarget:(id)target tag:(NSString *)tag;

@end

调用示例

  [self showWaitingView:nil viewStyle:EWaitingViewStyle_Rotation];

    [PGRequestManager startPostClient:API_TYPE_LOGIN
                                param:@{@"userName":@"name",@"password":@"123456"}
                               target:self
                                  tag:@"login"];

回调处理

- (void)dataRequestSuccess:(PGResultObject *)resultObj
{
    [self hideWaitingView];
}

- (void)dataRequestFailed:(PGResultObject *)resultObj
{
    [self hideWaitingView];
    [self showMsg:resultObj.szErrorDes];
}

当然也可以设计用Block回调,我这采用delegate主要是考虑到Controller的延迟销毁问题。也就是说Controller已经推出,但接口请求还没停止。block设计方案:

    WEAKSELF
    [PGRequestManager startPostClient:EUCClientType_Login param:@{@"userName":@"name",@"password":@"123456"} target:self tag:@"login" success:^(PGResultObject *resultObj) {
        [weakSelf asyncOnMainQueue:^{
        }];
    } faile:^(UCResultObject *resultObj) {
        [weakSelf asyncOnMainQueue:^{
            [weakSelf showMsg:resultObj.szErrorDes];
        }];
    }];

共同学习进步!

相关文章

网友评论

    本文标题:从零开始设计搭建ios App框架(六)

    本文链接:https://www.haomeiwen.com/subject/devtyttx.html