zoukankan      html  css  js  c++  java
  • iOS如何在一个包上切换正式环境和测试环境

      最近项目处于测试阶段,所以免不了每天都得打包给测试人员,由于我们公司规模比较大,项目环境也分为了三种:测试环境、预上线(预生产)环境、上线(生产)环境。所以每到了测试后期,每天打包的时间也占了不少,遇见笔记本内存不足、xcode闹脾气或者有紧急解决的bug,打包更是一件很折磨人的活。最近两天测试到了尾声,终于有了时间,突然有个想法,那就是有没有什么办法,一份源码打包可以快速的切换环境供测试人员测试。而且在上家公司,也出现过这个需求,只是当时没怎么重视,慢慢的就被忽略了。简单说明下,我们公司预上线环境和上线环境源码是一套的,只不过预上线环境在hosts增加了绑定的地址。所以下面只讲切换测试环境和预上线环境,了解了下面的方法,有多少种环境的切换都不是问题。

      原先我的项目切换环境,是根据pch文件里的一个宏定义,手动改为0或者1来决定是什么环境,然后在一个专门放项目请求地址基础url串的文件里,根据不同的环境拼接出不同的url,所以才会有不同的环境有不同的请求url。所以为了避免每次切换环境都得重新打包,网上也看了不少方法,但是都好复杂,还需要动项目target中的设置,觉得太麻烦,最终想到的解决思路是,在登录页面放一个按钮,点击这个按钮显示UIAlertSheet,可以手动选择切换需要的环境,并且着重显示当前所处的环境。将切换好的环境保存在偏好设置里,然后在专门放项目请求地址基础url串的文件里,取出存放在偏好设置的值并且拼接出需要的url,考虑到在登录页面出现之前就有了接口请求或者对接口请求url的基本设置,所以最好是在选择所需的环境后,重启app以确保切换成功。不再多说,上代码:

    1.在pch文件里,定义一些常用的宏

    /***************单例模式宏**************/
    #define MACRO_SHARED_INSTANCE_INTERFACE +(instancetype)sharedInstance;
    #define MACRO_SHARED_INSTANCE_IMPLEMENTATION(CLASS) 
    +(instancetype)sharedInstance 
    { 
    static CLASS * sharedInstance = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
    sharedInstance = [[CLASS alloc] init]; 
    }); 
    return sharedInstance; 
    }
    
    #define APPDelegate ((AppDelegate*)[UIApplication sharedApplication].delegate)
    
    #define kBaseUrlSubStringKey @"kBaseUrlSubStringKey"
    #define kApp_WebSocket_URLKey @"kApp_WebSocket_URLKey"
    #define kServerFBKey @"serverFBKey"
    
    #pragma mark - 偏好读写/****************************/
    #define KYMWriteUserDefaults(value, key)     [[NSUserDefaults standardUserDefaults] setObject:value forKey:key]
    #define KYMReadUserDefaults(key) [[NSUserDefaults standardUserDefaults]objectForKey:key]
    #define KYMRemoveUserDefaults(key)     [[NSUserDefaults standardUserDefaults] removeObjectForKey:key]
    #define KYMSaveUserDefaults [[NSUserDefaults standardUserDefaults] synchronize]

    2.创建一个工具类,用来切换环境和获得当前环境

    #import <Foundation/Foundation.h>
    
    @interface YimaiChangeEnvironment : NSObject
    MACRO_SHARED_INSTANCE_INTERFACE
    
    //切换环境
    - (void)changeEnvironment;
    
    //获得当前环境
    - (NSString *)currentEnvironment;
    @end
    #import "YimaiChangeEnvironment.h"
    #import "AppDelegate.h"
    #import "IQUIWindow+Hierarchy.h"
    //TEST
    static NSString *const devConfig = @"0";
    
    //预生产
    static NSString *const prodConfig = @"1";
    
    //生产
    //static NSString *const prodConfig1 = @"2";
    
    
    @implementation YimaiChangeEnvironment
    MACRO_SHARED_INSTANCE_IMPLEMENTATION(YimaiChangeEnvironment)
    
    //切换环境
    - (void)changeEnvironment {
        
        NSLog(@"change environment start");
        NSString *title=@"切换环境";
        
        NSString *subTitle=@"重启后生效, 非测试人员请点击cancel";
        
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:subTitle preferredStyle:UIAlertControllerStyleActionSheet];
        
        //修改title
        NSMutableAttributedString *alertControllerStr = [[NSMutableAttributedString alloc] initWithString:title];
    //    [alertControllerStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, alertControllerStr.length)];
        [alertControllerStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:20] range:NSMakeRange(0, alertControllerStr.length)];
        [alert setValue:alertControllerStr forKey:@"attributedTitle"];
        
        //修改message
        NSMutableAttributedString *alertControllerMessageStr = [[NSMutableAttributedString alloc] initWithString:subTitle];
    //    [alertControllerMessageStr addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(0, alertControllerMessageStr.length)];
        [alertControllerMessageStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:16] range:NSMakeRange(0, alertControllerMessageStr.length)];
        [alert setValue:alertControllerMessageStr forKey:@"attributedMessage"];
        
        NSString *currentEnvironment=@"";
        if ([[self currentEnvironment] isEqualToString:devConfig]) {
            currentEnvironment=@"当前环境为 TEST";
            [alert addAction:[UIAlertAction actionWithTitle:@"TEST" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
            //测试环境
            [[NSUserDefaults standardUserDefaults] setObject:devConfig forKey:kServerFBKey];
            //重置请求的基url
            [self resetRequestBaseUrl];
            }]];
            
            [alert addAction:[UIAlertAction actionWithTitle:@"预生产" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                //预生产环境
                [[NSUserDefaults standardUserDefaults] setObject:prodConfig forKey:kServerFBKey];
                //重置请求的基url
                [self resetRequestBaseUrl];
            }]];
            
    //        [alert addAction:[UIAlertAction actionWithTitle:@"生产" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    //            //生产环境
    //            [[NSUserDefaults standardUserDefaults] setObject:prodConfig1 forKey:kServerFBKey];
    //        }]];
        } else if ([[self currentEnvironment] isEqualToString:prodConfig]) {
            
            currentEnvironment=@"当前环境为 预生产";
    
            [alert addAction:[UIAlertAction actionWithTitle:@"TEST" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                //测试环境
                [[NSUserDefaults standardUserDefaults] setObject:devConfig forKey:kServerFBKey];
                //重置请求的基url
                [self resetRequestBaseUrl];
            }]];
            
            [alert addAction:[UIAlertAction actionWithTitle:@"预生产" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
                //预生产环境
                [[NSUserDefaults standardUserDefaults] setObject:prodConfig forKey:kServerFBKey];
                //重置请求的基url
                [self resetRequestBaseUrl];
            }]];
            
    //        [alert addAction:[UIAlertAction actionWithTitle:@"生产" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    //            //生产环境
    //            [[NSUserDefaults standardUserDefaults] setObject:prodConfig1 forKey:kServerFBKey];
    //        }]];
        }
        
        [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            //
        }]];
        
        NSLog(@"currentEnvironment = %@", currentEnvironment);
        //当前选择的视图控制器需要自己赋值,比如tabbar的didSelectViewController里
        [KeyWindow.currentViewController presentViewController:alert animated:YES completion:^{
        }];
        
    }
    
    
    //获得当前环境
    - (NSString *)currentEnvironment{
        //默认测试环境
        NSString *currentEnvironment=devConfig;
        if ([[NSUserDefaults standardUserDefaults] objectForKey:kServerFBKey]) {
            currentEnvironment=[[NSUserDefaults standardUserDefaults] objectForKey:kServerFBKey];
        }return currentEnvironment;
    }
    
    - (void)resetRequestBaseUrl {
    #pragma mark - 切换测试线和预生产环境
        if ([[YimaiChangeEnvironment sharedInstance].currentEnvironment isEqualToString:@"0"]) {
            NSLog(@"测试环境。。。。。。。");
            //测试环境
            KYMWriteUserDefaults(@"test.", kBaseUrlSubStringKey);
            KYMWriteUserDefaults(@"ws://tws.rt.xywy.com/websocket", kApp_WebSocket_URLKey);
            KYMSaveUserDefaults;
        }else if ([[YimaiChangeEnvironment sharedInstance].currentEnvironment isEqualToString:@"1"]) {
            //预上线环境
            KYMWriteUserDefaults(@"", kBaseUrlSubStringKey);
            KYMWriteUserDefaults(@"ws://testws.rt.xywy.com/websocket", kApp_WebSocket_URLKey);
            KYMSaveUserDefaults;
            
            NSLog(@"预生产环境.........");
        }
    }
    
    
    @end

    3.在登录页面加入切换环境的入口

    //点击切换开发环境
    - (IBAction)didClickChangeEnvironment:(id)sender {
        
        [[YimaiChangeEnvironment sharedInstance]changeEnvironment];
        
        return;
    }

      

  • 相关阅读:
    Lua Coroutine详解
    Lua IO库详解
    vue 组件基本使用
    js 发送异步请求
    小程序保存图片到相册
    js 学习四 对象应用 吃货游戏
    js 学习三 Array
    js 学习二 字符串常用方法
    js 学习一 猜数字游戏
    phpmyadmin导入大容量.sql文件
  • 原文地址:https://www.cnblogs.com/jingxin1992/p/8969091.html
Copyright © 2011-2022 走看看