最近项目处于测试阶段,所以免不了每天都得打包给测试人员,由于我们公司规模比较大,项目环境也分为了三种:测试环境、预上线(预生产)环境、上线(生产)环境。所以每到了测试后期,每天打包的时间也占了不少,遇见笔记本内存不足、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 = @""; //预生产
static NSString *const prodConfig = @""; //生产
//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:] range:NSMakeRange(, 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:] range:NSMakeRange(, 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:@""]) {
NSLog(@"测试环境。。。。。。。");
//测试环境
KYMWriteUserDefaults(@"test.", kBaseUrlSubStringKey);
KYMWriteUserDefaults(@"ws://tws.rt.xywy.com/websocket", kApp_WebSocket_URLKey);
KYMSaveUserDefaults;
}else if ([[YimaiChangeEnvironment sharedInstance].currentEnvironment isEqualToString:@""]) {
//预上线环境
KYMWriteUserDefaults(@"", kBaseUrlSubStringKey);
KYMWriteUserDefaults(@"ws://testws.rt.xywy.com/websocket", kApp_WebSocket_URLKey);
KYMSaveUserDefaults; NSLog(@"预生产环境.........");
}
} @end

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

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

  

iOS如何在一个包上切换正式环境和测试环境的更多相关文章

  1. 转 通过 spring 容器内建的 profile 功能实现开发环境、测试环境、生产环境配置自动切换

                                      软件开发的一般流程为工程师开发 -> 测试 -> 上线,因此就涉及到三个不同的环境,开发环境.测试环境以及生产环境,通常 ...

  2. vue cli3配置开发环境、测试环境、生产(线上)环境

    cli3创建vue项目是精简版的少了build和config这2个文件,所以配置开发环境.测试环境.生产环境的话需要自己创建env文件. 需要注意2点: 1.cli2创建项目生成的config文件里的 ...

  3. 项目开发过程中什么是开发环境、测试环境、生产环境、UAT环境、仿真环境?

    项目开发过程中什么是开发环境.测试环境.生产环境.UAT环境.仿真环境? 最近在公司项目开发过程中总用到测试环境,生产环境和UAT环境等,然而我对环境什么的并不是很理解它的意思,一直处于开发阶段,出于 ...

  4. linux环境下测试环境搭建

    一.linux环境下测试环境搭建过程简述: 1.前端后台代码未分离情况下: 主要步骤为:安装jdk,安装mysql,安装tomcat,将项目代码部署到tomcat/webapps/下. 2.前端后台代 ...

  5. angular 配置开发环境、测试环境、生产环境

    1. 配置开发环境.测试环境.生产环境 (1). environment.ts - 开发环境: 用于程序开发 (创建项目时自动生成) export const environment = { prod ...

  6. 第一篇 Postman的初级使用之设置环境快速切换生成环境与测试环境

    POSTMAN是有谷歌的开源工具,在开发调试.测试执行过程中使用频率非常广泛,本文将记录一些postman在测试中常见的一些配置和使用方法 一.基本的页面区域 略,很简单,大家都会看,再有,学习下面的 ...

  7. Rails的三种环境----开发环境,生产环境和测试环境

    Rails 的三个环境 Rails 的应用程序预设提供了三种不同的执行模式: development environment 开发模式,用在你的开发的时候 test environment 测试模式, ...

  8. SpringBoot的Profiles根据开发环境和测试环境载入不同的配置文件

    参考:https://www.cnblogs.com/bjlhx/p/8325374.html 1.需要有一个默认的配置文件,然后一个正式的配置文件,一个测试的配置文件.激活配置项,默认的配置文件ap ...

  9. 什么是 开发环境、测试环境、生产环境、UAT环境、仿真环境

    开发环境:开发环境是程序猿们专门用于开发的服务器,配置可以比较随意, 为了开发调试方便,一般打开全部错误报告. 测试环境:一般是克隆一份生产环境的配置,一个程序在测试环境工作不正常,那么肯定不能把它发 ...

随机推荐

  1. JQuery和原生JavaScript实现网页定位导航特效

    慕课网的一个小课程,练习了一遍,不足之处,欢迎指正(照片在本地,大家可以着重看代码哈): <!DOCTYPE html> <html lang="en"> ...

  2. 【linux】扒站命令之利用wget快速扒站利用wget快速扒站

    在Linux下,通过一个命令就可以把整个站相关的文件全部下载下来. wget -r -p -k -np 参数说明: -r : 递归下载 -p : 下载所有用于显示 HTML 页面的图片之类的元素 -k ...

  3. git 上传文件到仓库上提示:origin does not to be a git repository

    最近上传代码到GitHub的时候,当我输入 git push -u origin master的时候,它提示: origin does not to be a git repository 在网上找到 ...

  4. frame shiro 概述

    权限管理 权限管理包括用户身份认证和授权两部分,简称认证授权. 身份认证包括用户口令登陆.指纹验证.刷卡等方式. 授权即访问控制,控制谁能访问哪些资源,主体身份认证后分配权限以访问自己可以访问的资源. ...

  5. select2加载远程数据示例

    核心js $("#query_pack_code").select2({ language: "zh-CN", allowClear: true, width: ...

  6. Maven安装及MyEclipse中使用Maven

    Step1:下载mavenhttp://maven.apache.org/download.cgi,下载好后解压到一个路径中 Step2:配置环境变量, 新建变量名:MAVEN_HOME 变量值:D: ...

  7. 相关与卷积(数字信号处理)的数学原理及 Python 实现

    数学原理 在数字信号处理中,相关(correlation)可以分为互相关(cross correlation)和自相关(auto-correlation). 互相关是两个数字序列之间的运算:自相关是单 ...

  8. [翻译] MotionBlur

    MotionBlur https://github.com/fastred/MotionBlur MotionBlur allows you to add motion blur effect to ...

  9. ajax Post数据,并得到返回结果,密码加密(Select,checkbox)

    使用ajax Post数据到后台Server,并从后台返回数据给前端WEB: urls.py: from django.conf.urls import url from aptest import ...

  10. 工具类-vim在shell中卡死的情况

    time:2015/11/35 在xshell下面使用vim编辑,有时候会出现突然卡死的情况.但是如果重新开一个终端的话,打开文件又是一大堆问题,今天又碰到了,搜了一下就找到一个帮助了[1] 原因:按 ...