封装项目网络库

作者: Jacky_Yang | 来源:发表于2016-06-22 19:05 被阅读566次

    封装一个网络库的一些思路(基于YTKNetwork)

    为什么要封装网络库

    大家都知晓网络层是一个项目的灵魂,所以网络层写的是否规范、是否简洁、是否完整关系到一个项目的整体质量,甚至于项目的性能。因此在这里我给大家分享下我是如何封装一个项目所用的网络库的(其实就是把整个项目所用的接口,写成一个库,方便项目使用)。

    封装网络库的作用

    1.请求数据
    2.对每个接口都可以进行缓存时间设置
    3.利用MJExtension进行字典模型转换
    4.更加灵活方便的调用各个接口,降低了耦合性

    如何封装

    这里我列举一个用户登录的请求
    首先基于YTKRequest封装一个SuperRequest类
    @interface SuperRequestAPI : YTKRequest
    
    @property (nonatomic, strong, readonly) YSNetworkConfig *config;
    
    - (NSMutableDictionary *)signAndEncode:(NSMutableDictionary *)param;
    
    - (void)printRequestInfo;
    
    @end
    
    @implementation SuperRequestAPI
    
    - (NSMutableDictionary *)signAndEncode:(NSMutableDictionary *)params {
        NSMutableArray *paramArray = [[NSMutableArray alloc] init];
        
        NSArray *sortArray = [[params allKeys] sortedArrayUsingSelector:@selector(compare:)];
        
        for (NSString *key in sortArray) {
            NSString *param = [NSString stringWithFormat:@"%@", [params objectForKey:key]];
            if (param && ![param isEqualToString:@""]) {
                [paramArray addObject:param];
            }
        }
        
        // 获取加密字符串
        NSString *encode = [YSSecurityHelper getEncodePostMsgDataWithParams:paramArray encodeKey:self.config.encodeKey];
        
        // 将加密字符串作为参数上传
        [params setObject:encode forKey:@"sign"];
        return params;
    }
    
    #pragma mark - 配置信息
    - (YTKRequestMethod)requestMethod {
        return YTKRequestMethodPost;
    }
    
    - (NSString *)baseUrl {
        return self.config.serviceURL;
    }
    
    
    - (NSTimeInterval)requestTimeoutInterval {
        return 30;
    }
    
    - (NSInteger)cacheTimeInSeconds {
        return kCacheTime;
    }
    
    - (void)printRequestInfo {
        NSMutableString *requestString = [[NSMutableString alloc] init];
        [requestString appendString:self.baseUrl];
        [requestString appendString:self.requestUrl];
        
        NSArray *sortArray = [[self.requestArgument allKeys] sortedArrayUsingSelector:@selector(compare:)];
        
        for (NSString *key in sortArray) {
            [requestString appendString:@"&"];
            [requestString appendString:key];
            [requestString appendString:@"="];
            [requestString appendString:self.requestArgument[key]];   
        }
        
        NSLog(@"请求地址:==========%@", requestString);
    }
    
    

    这个类可以对请求参数进行签名和加密、设置缓存时间、打印请求地址等等一些操作。

    创建一个LoginRequestAPI类继承SuperRequestAPI
    #import "SuperRequestAPI.h"
    
    @interface LoginRequestAPI : SuperRequestAPI
    
    /**
     *  @brief  登录请求参数
     *
     *  @param userName 用户名
     *  @param password 密码
     *
     *  @return LoginRequestModel
     */
    - (id)initWithUserName:(NSString *)userName password:(NSString *)password;
    @end
    
    
    
    #import "LoginRequestAPI.h"
    
    @interface LoginRequestAPI ()
    
    @property (nonatomic, strong) NSString *userName;
    @property (nonatomic, strong) NSString *password;
    // 设置请求参数
    @property (nonatomic, strong) NSMutableDictionary *requestParam;
    
    @end
    
    @implementation LoginRequestAPI
    
    - (id)initWithUserName:(NSString *)userName password:(NSString *)password {
        
        if (self = [super init]) {
            _userName  = userName;
            _password = password;
        }
        return self;
    }
    
    #pragma mark - Getter && Setter
    - (NSMutableDictionary *)requestParam {
        if (_requestParam == nil) {
            
            /** 赋值参数字段 */
            _requestParam = [[NSMutableDictionary alloc] init];
           
            [_requestParam setObject:(_userName ? _userName : @"") forKey:@"userName"];
            [_requestParam setObject:(_password ? _password : @"") forKey:@"password"];
            
            //对参数进行签名和加密处理
            _requestParam = [self signAndEncode:_requestParam];
        }
        return _requestParam;
    }
    
    #pragma mark - 配置请求信息
    
    - (id)requestArgument {
        return self.requestParam;
    }
    
    @end
    
    

    在这个请求参数类里面你可以设置你的请求路径,版本号、请求参数等等。完整的封装了请求参数,需要的话可以对参数进行签名和加密处理。

    创建相应的模型类

    这里我们用到MJExtension进行字典模型转换,对字段进行了一一映射处理,MJExtension具体用法请参考https://github.com/CoderMJLee/MJExtension

    #import <Foundation/Foundation.h>
    #import <MJExtension/MJExtension.h>
    
    @interface LoginDetail : NSObject
    
    @property (nonatomic, strong) NSString *mAuthCode;
    @property (nonatomic, strong) NSString *mAvatar;
    @property (nonatomic, strong) NSString *mCae;
    @property (nonatomic, strong) NSString *mId;
    @property (nonatomic, strong) NSString *mIsThird;
    @property (nonatomic, strong) NSString *mLastLoginTime;
    @property (nonatomic, strong) NSString *mPassId;
    @property (nonatomic, strong) NSString *mToken;
    @property (nonatomic, strong) NSString *mUsername;
    @property (nonatomic, strong) NSString *mValidate;
    
    @end
    
    #import "LoginDetail.h"
    
    @implementation PhoneLoginDetail
    
    + (NSDictionary *)replacedKeyFromPropertyName {
        return @{
                 @"mAuthCode" : @"auth_code",
                 @"mAvatar" : @"avatar",
                 @"mCae" : @"cae",
                 @"mId" : @"id",
                 @"mIsThird" : @"is_third",
                 @"mLastLoginTime" : @"last_login_time",
                 @"mPassId" : @"passid",
                 @"mToken" : @"token",
                 @"mUsername" : @"username",
                 @"mValidate" : @"validate"
                 };
    }
    @end
    
    
    最后一步,就是写请求接口类了

    这个类里面可以把所有的请求接口写进去,最好用类方法。

    @interface YBNetwork : NSObject
    + (void)requestLoginDetailWithUserName:(NSString *)userName
                                       password:(NSString *)password
                                        success:(void (^)(LoginDetail * LoginDetail, BOOL success, NSDictionary *responseObject))successBlock
                                        failure:(void (^)(NSDictionary *requestParam))failureBlock;
    @end
    
    
    @implementation YBNetwork
    
    /*!
     *  请求用户登录信息
     *  @param userName    用户名
     *  @param password    密码
     *  @param successBlock 成功block
     *  @param failureBlock 失败block
     */
    + (void)requestLoginDetailWithUserName:(NSString *)userName
                                       password:(NSString *)password
                                        success:(void (^)(LoginDetail * LoginDetail, BOOL success, NSDictionary *responseObject))successBlock
                                        failure:(void (^)(NSDictionary *requestParam))failureBlock {
        
        [YBNetwork addAcceptableContentTypes];
        
        LoginRequestAPI *api = [[LoginRequestAPI alloc] initWithUserName:userName password:password];;
        
        [api startWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest *request) {
            NSDictionary *responseDictionary = [request responseJSONObject];
            NSString *status;
            if (DATA_STRING(responseDictionary[@"status"])) status = responseDictionary[@"status"];
            if (200 == status.integerValue) {
                if (DATA_DICTIONARY(responseDictionary[@"info"])) {
                    NSDictionary *info = responseDictionary[@"info"];
                    LoginDetail *phoneLoginDetail = [LoginDetail mj_objectWithKeyValues:info];
                    // 请求成功
                    successBlock(phoneLoginDetail, YES, responseDictionary);
                } else {
                    // 返回数据格式存在问题
                    successBlock(nil, YES, responseDictionary);
                }
            } else {
                // 返回的status非法
                successBlock(nil, NO, responseDictionary);
            }
        } failure:^(__kindof YTKBaseRequest *request) {
            // 网络请求失败
            failureBlock(request.requestArgument);
        }];
        [api printRequestInfo];
    }
    
    

    这里我的一个思路是基于YTKNetwork写这个接口,采用block回调形式,回调两个参数,一个是success和failure,success返回模型实例对象,success布尔值以及返回json转换后的字典,之所以还返回字典是便于项目中调试接口用。failure返回的就是失败的字典喽!
    整个封装大概就是这个思路,我这里纯粹是抛砖引玉,提供一个参考的封装方法,大家可以多多交流!收工!!!

    相关文章

      网友评论

      • zhou某某:LZ有demo吗?能给个地址吗
      • 七夜叹:还有 YSNetworkConfig
      • 七夜叹:楼主,你的YSNetworkConfig哪里来的
        七夜叹:@Jacky_Yang 能加下qq吗,我qq994463093, 我发现YTK的这个库网上根本搜不到错误的信息处理,我现在遇到一点问题,能请教下吗
        Jacky_Yang:@七夜叹 这个是我自己创建的网络请求基本信息类 里面可以放一些 baseURL vcode 等一些公共的参数
      • Emma_Zhao:继续加油
      • Emma_Zhao:腻害腻害!:kissing_heart:
        Jacky_Yang:@Emma_Zhao 么么 :kissing_heart:

      本文标题:封装项目网络库

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