ISO框架设计之登录超时、未登录设计和断网重连的设计。。。。。

来源:互联网 发布:python怎么多线程并发 编辑:程序博客网 时间:2024/06/06 00:13

=======公用头文件,pch的设计========

颜色,url地址,配置开关,屏幕尺寸,固定的大小;

公用block:

#ifndef Header_h


#define Header_h

typedef void(^ProgressBlock) (NSProgress* progress);

typedef void(^SuccessBlock) (NSURLSessionDataTask *task,id responseObject);

typedef void(^FailureBlock) (NSURLSessionDataTask *task,NSError *error);

typedef void(^SuccessHandleBlock) (NSString *msg,id responseObject);

typedef void(^FailureHandleBlock) (NSString *msg,NSInteger errorCode);

#endif


枚举:

typedef enum {

    waitPay     = 1,    //待付款

    waitSend    = 2,    //待发货

    waitReceive = 3,    //待收货

    waitComment = 4,    //待评价

    commented   = 5,    //已评价

    returned    = 6,    //已退货

    all         = 7     //全部订单

    

}OrderStatus;

+(NSString*)getOrderTitlteWithOrderStatus:(OrderStatus)orderStatus{

    

    switch (orderStatus) {

        casewaitPay:

            return@"待付款";

            break;

        casewaitSend:

            return@"待发货";

            break;

        casewaitReceive:

            return@"待收货";

            break;

        casewaitComment:

            return@"待评价";

            break;

        casecommented:

            return@"已评价";

            break;

        casereturned:

            return@"已退货";

            break;

        caseall:

            return@"全部订单";

            break;

    }

    return@"全部订单";

}


============不同功能类的配置文件===========

=========网络请求框架的封装设计=======

一般封装成两级或三级

调用:

  [SPPersonRequesterManagermodifyPasswordWithOldPassword:oldPwdnewPassword:pwdsuccess:^(NSString *msg,id responseObject) {

       

    } failure:^(NSString *msg,NSInteger errorCode) {

            

    }];   

}

一级封装:

+(void)modifyPasswordWithOldPassword:(NSString*)oldPwd newPassword:(NSString*)newPwd success:(SuccessHandleBlock)success failure:(FailureHandleBlock)failure{

    

    CommonDataService *request = [superPostRequestService];

    NSString* url = [requestGetUrlWhitController:@"User"action:@"password"];

    

    NSString* md5OldPwd = [SPUtilsmd5WithAuthCode:oldPwd];

    NSString* md5NewPwd = [SPUtilsmd5WithAuthCode:newPwd];

    

    NSDictionary* params = @{

                             @"old_password":md5OldPwd,

                             @"new_password":md5NewPwd

                             };

    

    [request requestWithUrl:urlparams:paramssuccessBlock:^(NSURLSessionDataTask *operation,id responseObject) {

        

        

        NSInteger status = [[responseObjectobjectForKey:@"status"]integerValue];

        NSString *msg = [responseObjectobjectForKey:@"msg"];

        NSLog(@"-修改密码-status--%tu",status);

        NSLog(@"-修改密码-msg--%@",msg);

        if(status > 0)

        {

            //传递对象

            if(success)

            {

                success(msg,@"success");

            }

            /* End 数据结果解析区 */

        }

        else

        {

            if(failure)

            {

                failure(msg,-1);

            }

        }

        

    } failureBlock:^(NSURLSessionDataTask *operation,NSError *error) {

        

        NSLog(@" failureBlock :%@", [error description]);

        

        if(failure)

        {

            failure(kNetworkError,-1);

        }

        

    }];

}

二级封装:

-(NSURLSessionDataTask *)requestWithUrl:(NSString *)url

                                        params:(NSDictionary *)params

                                  successBlock:(SuccessBlock)successBlock

                                  failureBlock:(FailureBlock)failureBlock {

    

    //构建公共请求参数

    if (!params) {

        params = [NSMutableDictionarydictionary];

    }else{

        params = [NSMutableDictionarydictionaryWithDictionary:params];

    }

   

    

     if([SPMobileApplicationsharedInstance].isLogined)//登录状态

    {

        SPUser *loginUser = [SPMobileApplicationsharedInstance].loginUser;

        [params setValue:loginUser.userIDforKey:@"user_id"];//用户ID

        if (loginUser.token) {

            [params setValue:loginUser.tokenforKey:@"token"];


        }

        

    }

    

    if ([[SPMobileApplicationsharedInstance]getPhoneDeviceID]) {

        [params setValue:[[SPMobileApplicationsharedInstance]getPhoneDeviceID]forKey:@"unique_id"];

//        NSLog(@"-最终参数没签名前--%@",params);

    }

    

//     NSLog(@"-最终参数parama--%@-",params);

    /* params=@{

     @"sign":@"d8ded4324c37a4b43ab4b197a78fcded",

     @"time":@"1492495675",

     @"unique_id":@"891F1CCA-E4A7-4F35-BA03-688CD5314686";

     }

     

     */

    params = [selfconfigSign:paramsurl:url];//签名后的参数

//    NSLog(@"-最终参数--签名后params--%@",params);

    

//    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    

    

        //待超时时间

        NSURLSessionConfiguration *config = [NSURLSessionConfigurationdefaultSessionConfiguration];

        config.timeoutIntervalForRequest = 30.0;

        AFHTTPSessionManager *manager = [[AFHTTPSessionManageralloc]initWithSessionConfiguration:config];

    


    manager.securityPolicy = [AFSecurityPolicypolicyWithPinningMode:AFSSLPinningModeNone];//安全策略

    manager.securityPolicy.allowInvalidCertificates =YES;


    manager.responseSerializer.acceptableContentTypes=[NSSetsetWithObjects:@"application/json",@"text/json",@"text/javascript",@"text/html",@"text/xml",@"text/plain; charset=utf-8",nil];

    

//    manager.requestSerializer=[AFJSONRequestSerializer serializer];//ly*******

    

    if(self.isJsonResponse) {

        manager.responseSerializer = [AFJSONResponseSerializerserializer];

    } else {

        manager.responseSerializer = [AFHTTPResponseSerializerserializer];

    }

 

    //SPSaveData保存用户信息类

    [SPSaveDatasaveDataWithData:urlkey:@"domain"];

   

    

    if(self.requestMethod ==RequestMethodGet)

    {

        [manager GET:urlparameters:paramsprogress:nilsuccess:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {

            

            if (successBlock) {

                

                if ([responseObjectobjectForKey:@"status"]) {

                    NSInteger status = [[responseObjectobjectForKey:@"status"]integerValue];

//                    NSLog(@"statue---%tu",status);

                //token过期

                    if ((status ==RESPONSE_CODE_TOKENN_LOST || status ==RESPONSE_CODE_TOKENN_INALIDE || status ==RESPONSE_CODE_TOKENN_EXPIRE) && ![selfskipTokenNotification:url]) {

                        

                        //发送通知//token过期,失效通知

                        

                        [[NSNotificationCenterdefaultCenter]postNotificationName:NotificationTokenExpireobject:nil];

                        

                        //token过期的接口统一设置超时提示

                        NSMutableDictionary* dict = [NSMutableDictionarydictionaryWithDictionary:responseObject];

                        [dict setValue:@"登录超时,正在重新登录"forKey:@"msg"];

                        responseObject = dict;

                        

                    }

                }

                successBlock(task , responseObject);

            }

            

        } failure:^(NSURLSessionDataTask *_Nullable task,NSError *_Nonnull error) {

            NSLog(@"get错误信息】:\n%@",[error description]);

            

            [selfsendErrorLog:[errordescription] url:urlparameter:nil];

            

            if(failureBlock){

                failureBlock(task,error);

            }

        }];

        

    }

    elseif(self.requestMethod ==RequestMethodPost)

    {

        //NSInteger status = [[responseObject objectForKey:@"status"] integerValue];

        

        [manager POST:urlparameters:paramsprogress:^(NSProgress *_Nonnull uploadProgress) {

            

        } success:^(NSURLSessionDataTask *_Nonnull task,id _Nullable responseObject) {

           

            if (successBlock) {


//*********************//如果不是标准的json数据,就需要用到下面的方法;

//                NSString *str=[[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding];//网页二进制数据转换成字符串

//                NSLog(@"---responseStr---%@",str);

//                NSData *data=[[NSData alloc]initWithData:[str dataUsingEncoding:NSUTF8StringEncoding]];

//        NSDictionary *responseObject=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];

  //*******************************


                

                if ([responseObjectobjectForKey:@"status"]) {

                    NSInteger status = [[responseObjectobjectForKey:@"status"]integerValue];

                    

//                    NSLog(@"statue---%tu",status);

                    

                    if ((status ==RESPONSE_CODE_TOKENN_LOST || status ==RESPONSE_CODE_TOKENN_INALIDE || status ==RESPONSE_CODE_TOKENN_EXPIRE) && ![selfskipTokenNotification:url]) {

                        

                        //发送通知//token过期,失效通知

                        [[NSNotificationCenterdefaultCenter]postNotificationName:NotificationTokenExpireobject:nil];

                        

                        //token过期的接口统一设置超时提示

                        NSMutableDictionary* dict = [NSMutableDictionarydictionaryWithDictionary:responseObject];

                        [dict setValue:@"登录超时,正在重新登录"forKey:@"msg"];

                        responseObject = dict;

                        

                    }

                    

                }

                

                

                successBlock(task , responseObject);

            }

            

        } failure:^(NSURLSessionDataTask *_Nullable task,NSError *_Nonnull error) {

            NSLog(@"post错误信息】:\n%@",[error description]);

            [selfsendErrorLog:[errordescription] url:urlparameter:nil];//发送错误日志报告到服务器

            if(failureBlock){

                

                //发送通知

                failureBlock(task,error);

            }

        }];

 

    }

    

    returnnil;

}



===========


======未登录设计=======

设置一个单利的属性isLogin来存储是否登录,登录成功后设为YES,退出登录后设置为NO;

程序刚启动或者在点击游客游客登录按钮后设置为NO;一般在涉及到与个人信息数据有关的时候,提醒登录;可以只设提醒,也可以提醒后跳转到登录界面;




==登录超时======在网络请求中根据约定好的status状态码,来判断是否token过期,发送token过期的消息,在基础类的控制器中接收token过期的消息;所有继承基础类的控制器都可以接收到消息,

    [manager POST:urlparameters:paramsprogress:nilsuccess:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {

        

        

        if (successBlock) {

            NSDictionary *dict=[NSJSONSerializationJSONObjectWithData:responseObjectoptions:NSJSONReadingAllowFragmentserror:nil];

            

            NSInteger status=[dict[@"status"]integerValue];

            NSLog(@"status02%tu",status);

            if ((status ==RESPONSE_CODE_TOKENN_LOST || status ==RESPONSE_CODE_TOKENN_INALIDE || status ==RESPONSE_CODE_TOKENN_EXPIRE) ) {

                

                //发送通知//token过期,失效通知

                [[NSNotificationCenterdefaultCenter]postNotificationName:NotificationTokenExpireobject:nil];

                


            }

                    

    } failure:^(NSURLSessionDataTask *_Nullable task,NSError * _Nonnull error) {

       

        if(failureBlock){

            failureBlock(task,error);

        }

    }];



}


//基础控制器,接收登录超时和网络监控的消息,在基础类的控制器中接收断网的消息,在网络请求的fail的方法中block调用返回,提示断网。

#import "LYBaseVC.h"

#import <Reachability.h>



@interface LYBaseVC ()


@end


@implementation LYBaseVC


- (void)viewDidLoad {

    [superviewDidLoad];

 

    [selfaddbackBtn];

    [[NSNotificationCenterdefaultCenter]addObserver:self

                                             selector:@selector(tokenExpireChanged:)

                                                 name:NotificationTokenExpire

                                               object:nil];//接收通知token丢失/过期/失效

    

    

    [[NSNotificationCenterdefaultCenter]addObserver:self

                                             selector:@selector(reachabilityChanged:)

                                                 name:kReachabilityChangedNotification

                                               object:nil];//网络状态监听

}


/**

 *  网络状态监听

 *

 *  @param noti noti description

 */

- (void)reachabilityChanged:(NSNotification *)noti {

    Reachability * reach = [notiobject];

    if([reachisReachable]) {

        [selfsetMBProgressWithNumTip:@"网络已连接"];

        NSLog(@"网络已经连接");

        [LYCommanManagersharedManager].isreachable=[reachisReachable];


        [[NSNotificationCenterdefaultCenter]postNotificationName:@"startloading"object:nil];//开始加载网页

    } else {

        NSLog(@"网络未连接");

         [selfsetMBProgressWithNumTip:@"网络未连接"];

        [LYCommanManagersharedManager].isreachable=[reachisReachable];


        [[NSNotificationCenterdefaultCenter]postNotificationName:@"endloading"object:nil];//发送结束加载的通知

    }

}

//token丢失/过期/失效

-(void)tokenExpireChanged:(NSNotification *)notify{

    [selfsetMBProgressWithNumTip:@"登录超时,请重新登录"];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)),dispatch_get_main_queue(), ^{

        [MBProgressHUD hideAllHUDsForView:self.viewanimated:YES];

        SPLoginViewController* loginVC = [[SPLoginViewControlleralloc]init];

        //loginVC.hidesBottomBarWhenPushed =YES;

        //[self.navigationControllerpushViewController:loginVCanimated:YES];//这个方法会可能会产生几个连续的push;

[UIApplicationsharedApplication].delegate.window.rootViewController=loginVC;//设置跟控制器的方式


    });

    

   

    }


    



//返回按钮

-(void)addbackBtn{

    

    UIButton *bbtn=[[UIButtonalloc]initWithFrame:CGRectMake(0, 0, 60, 30)];

    [bbtn setImage:[UIImageimageNamed:@"icon_navigation_back"]forState:UIControlStateNormal];

    [bbtn addTarget:selfaction:@selector(backBtn)forControlEvents:UIControlEventTouchDown];

    UIBarButtonItem *fixBtn=[[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpacetarget:selfaction:nil];

    fixBtn.width=-30;

    UIBarButtonItem *backbtn=[[UIBarButtonItemalloc]initWithCustomView:bbtn];

    NSArray *btnArr=@[fixBtn,backbtn];

    self.navigationItem.leftBarButtonItems=btnArr;

}

-(void)backBtn{

   

        

    [self.navigationControllerpopViewControllerAnimated:YES];

   

}


//设置提示---

-(void)setMBProgressWithNumTip:(NSString * )num{

    

    MBProgressHUD *hud=[[MBProgressHUDalloc]initWithView:self.view];

    [self.viewaddSubview:hud];

    

    hud.color=[UIColorblackColor];

    hud.labelColor=[UIColorwhiteColor];

    hud.mode=MBProgressHUDModeText;

    hud.animationType=MBProgressHUDAnimationZoomOut;

    hud.minSize=CGSizeMake(200,100);///////

    hud.labelText=[NSStringstringWithFormat:@"%@",num];

    [hud show:YES];

    [hud hide:YESafterDelay:2];

}


//设置提示---

-(void)setMBProgressWithNum:(NSString * )num{

    

    MBProgressHUD *hud=[[MBProgressHUDalloc]initWithView:self.view];

    [self.viewaddSubview:hud];

    hud.mode=MBProgressHUDModeIndeterminate;

    hud.detailsLabelFont = [UIFontsystemFontOfSize:17];

    hud.labelText=@"";

    hud.color=[hud.colorcolorWithAlphaComponent:0.6];

    

    hud.animationType=MBProgressHUDAnimationZoomIn;

    hud.minSize=CGSizeMake(100,100);///////

    hud.detailsLabelText=[NSStringstringWithFormat:@"%@",num];

    //    hud.dimBackground=YES;

    [hud show:YES];

    //    [hud hide:YES afterDelay:3];

    NSLog(@"执行了");

}


-(void)viewWillAppear:(BOOL)animated{

    if(![LYCommanManagersharedManager].isreachable){

        [selfsetMBProgressWithNumTip:@"网络连接失败"];

    }

}

@end


在APPdelegate   didfinishlaunch方法中加入网络监控:

//AFN监控有没有网络----苹果原声的 ---需要导入Reachability.hReachability.m

- (void)monitorReachability {

    Reachability *reach = [ReachabilityreachabilityForInternetConnection];

    reach.reachableOnWWAN =YES;

    [reach startNotifier];

    [LYCommanManagersharedManager].isreachable=[reachisReachable];//保存成一个单利的属性,必须保证登录的时候有网,否则无意义----所以这里可定会有网络(如果这里不设置,如果一直都有网,则启动后isreach取默认值0,会导致MBPRogress显示成相反的;如果在登录的时候才打开网络,则会发送通知,能获取当前正确的网络状态)

//    NSLog(@"appdel----isreach---%d",[reach isReachable]);

    

}