拿来即用删掉即走:iOS客户端无侵入、一包任意环境切换实践篇

本文主要是介绍拿来即用删掉即走:iOS客户端无侵入、一包任意环境切换实践篇,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本篇以基于mPaaS框架的工程为例。

        在开发测试过程中需要在不同的环境中来进行,比如UAT、SIT、准生产。不同的阶段,不同的需求需要在不同环境测试。这样会引发两个问题:

1.工程庞大,源码文件好几G,每次切换环境需要修改宏定义,修改了宏定义就使得整个工程需要重新编译,而工程完整编译一次需要10多分钟,这样大大降低了开发效率;

 2.测试人员一次只能安装一个环境的测试包并且安装其他环境测试包则需要先卸载原来的安装包

网络上主流的环境切换也存在着各种各样的问题:

1. 设置Build Configuration:改变bundleid来达到一个手机安装多个测试包,每个测试包环境都不一样 这样会导致工程内比如登录中使用的安全键盘、扫描身份证的OCR插件、人脸识别的活体认证插件等需要验证bundleid的功能无法使用

 2.设置Settings.bundle :这是苹果提供的可以在iOS系统设置中添加设置选项的功能。但这样改会修改原有工程代码,上线整理生产代码会带来风险

3.开发一个切换环境的ViewController每次打开应用先选环境:这样首先会污染源代码其次如果不是100%源码工程是做不了的比如我们使用了mPaaS

本文首先先介绍两种iOS提供的比较强大的技术

1.分类(Category)Category主要作用是给原来的类添加新的方法。如果分类中的方法名与原类的方法名一致则会覆盖掉原类的这个方法。如果有两个分类都实现了与原类的方法名一样的方法则需要看编译顺序,只会调用最后编译的那个分类中的同名方法。

2.方法交换(method_exchange)主要作用是只要知道方法名就能替换任何一个类中的方法,而且替换后的方法还能继续调用原有的方法,包括系统的api。

这两种技术结合使用就能实现“拿来即用 用完即走"的环境切换理念。

这种方法不会污染源工程代码,打测试包时把关于切换环境的文件夹直接拖到工程里,打生产包把整个文件夹删掉。

之前的文章已经把思路说过了

使用mpaas的iOS客户端如何一包支持任意环境切换(理论篇)__小呵呵的博客-CSDN博客

这里更加清晰的描述一下

工程原本配置环境需要改的是

1.meta.config环境配置文件中的所有内容

2.info.plist xcode工程配置文件中的mPaaSCrypt

3.无线保镖图片(测试环境不验,不用管)

实现方法就是

1.重定向meta.config文件取值的是NSBundle-pathForResource:ofType:方法

2.重定向info.plist文件取值的是NSBundle-infoDictionary方法

准备好不同环境的config文件, 命名为metasit.config  metauat.config  meta准生产.config

然后核心代码就是

最早执行的load方法中写{Method originalMethod = class_getInstanceMethod([NSBundle class], @selector(pathForResource:ofType:));Method swizzledMethod = class_getInstanceMethod([NSBundle class], @selector(pathForResource:ofTypeS:));method_exchangeImplementations(originalMethod, swizzledMethod);}{Method originalMethod = class_getInstanceMethod([NSBundle class], @selector(infoDictionary));Method swizzledMethod = class_getInstanceMethod([NSBundle class], @selector(infoDictionaryS));method_exchangeImplementations(originalMethod, swizzledMethod);}
NSBundle+YYY.h#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface NSBundle (YYY)@endNS_ASSUME_NONNULL_END
NSBundle+YYY.m#import "NSBundle+YYY.h"
#import <objc/runtime.h>
@implementation NSBundle (YYY)
- (NSDictionary*)infoDictionaryS{NSMutableDictionary *dicc = [self infoDictionaryS].mutableCopy;//防止其他环境残留 影响[dicc removeObjectForKey:@"mPaaSInternal"];[dicc removeObjectForKey:@"mPaaS"];if ([[YYYPlistDataManage getCurrentEnvironmentFromPlist] containsString:@"uat"]){[dicc setObject:@{@"Crypt":@YES,@"GWWhiteList":@[@"http://*.*.*.*/mgw.htm",@"http://*.*.*.*/mgw.htm",@"http://*.*.*.*/mgw.htm",@"http://*.*.*.*/mgw.htm",@"http://*.*.*.*/mgw.htm",@"PubKey":@"-----BEGIN PUBLIC KEY-----\n******\n-----END PUBLIC KEY-----",@"RSA/ECC/SM2":@"SM2",} forKey:@"mPaaSCrypt"];}else if ([[YYYPlistDataManage getCurrentEnvironmentFromPlist] containsString:@"sit"]){[dicc setObject:@{@"Crypt":@YES,@"GWWhiteList":@[@"http://*.*.*.*/mgw.htm",],@"PubKey":@"-----BEGIN PUBLIC KEY-----\n*********\n-----END PUBLIC KEY-----",@"RSA/ECC/SM2":@"SM2",} forKey:@"mPaaSCrypt"];}else if ([[YYYPlistDataManage getCurrentEnvironmentFromPlist] containsString:@"准生产"]){[dicc setObject:@{@"Crypt":@YES,@"GWWhiteList":@[@"http://#.#.#.#/mgw.htm"],@"PubKey":@"-----BEGIN PUBLIC KEY-----\n#######\n-----END PUBLIC KEY-----",@"RSA/ECC/SM2":@"SM2",} forKey:@"mPaaSCrypt"];}
}- (nullable NSString *)pathForResource:(nullable NSString *)name ofTypeS:(nullable NSString *)ext;
{if ([name containsString:@"Settings"]) {//排除掉蚂蚁提供的环境配置对功能的影响name = @"";}if([name containsString:@"meta"] && ([ext isEqualToString:@"config"])){if ([[YYYPlistDataManage getCurrentEnvironmentFromPlist] isEqualToString:@"uat"]) {name = @"metauat";}else if ([[YYYPlistDataManage getCurrentEnvironmentFromPlist] isEqualToString:@"sit"]){name = @"metasit";}else if ([[YYYPlistDataManage getCurrentEnvironmentFromPlist] isEqualToString:@"准生产"]){name = @"meta准生产";}return [self pathForResource:name ofTypeS:ext];
}

注意事项:

1.mpaas框架是在load方法中读取的配置信息,因此需要保证把我们的交换方法先执行。

2.mpaas也提供了环境切换方法,在我们代码里已经屏蔽掉了

3.再配置个弹框来选择切换哪个环境,选完后清数据并且exit,重新打开客户端切换完成

4.彻底清数据的方法,其他博客有写

5.蚂蚁官网demo中的两个文件字段样式是

6.展示效果示例

这篇关于拿来即用删掉即走:iOS客户端无侵入、一包任意环境切换实践篇的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/421024

相关文章

Spring Retry 实现乐观锁重试实践记录

《SpringRetry实现乐观锁重试实践记录》本文介绍了在秒杀商品SKU表中使用乐观锁和MybatisPlus配置乐观锁的方法,并分析了测试环境和生产环境的隔离级别对乐观锁的影响,通过简单验证,... 目录一、场景分析 二、简单验证 2.1、可重复读 2.2、读已提交 三、最佳实践 3.1、配置重试模板

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N

Spring Boot 3 整合 Spring Cloud Gateway实践过程

《SpringBoot3整合SpringCloudGateway实践过程》本文介绍了如何使用SpringCloudAlibaba2023.0.0.0版本构建一个微服务网关,包括统一路由、限... 目录引子为什么需要微服务网关实践1.统一路由2.限流防刷3.登录鉴权小结引子当前微服务架构已成为中大型系统的标

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

python实现简易SSL的项目实践

《python实现简易SSL的项目实践》本文主要介绍了python实现简易SSL的项目实践,包括CA.py、server.py和client.py三个模块,文中通过示例代码介绍的非常详细,对大家的学习... 目录运行环境运行前准备程序实现与流程说明运行截图代码CA.pyclient.pyserver.py参

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、

使用Java实现获取客户端IP地址

《使用Java实现获取客户端IP地址》这篇文章主要为大家详细介绍了如何使用Java实现获取客户端IP地址,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 首先是获取 IP,直接上代码import org.springframework.web.context.request.Requ

在Mysql环境下对数据进行增删改查的操作方法

《在Mysql环境下对数据进行增删改查的操作方法》本文介绍了在MySQL环境下对数据进行增删改查的基本操作,包括插入数据、修改数据、删除数据、数据查询(基本查询、连接查询、聚合函数查询、子查询)等,并... 目录一、插入数据:二、修改数据:三、删除数据:1、delete from 表名;2、truncate