iOS开发之如何优雅的切换环境(以万能包对客服功能重定向plist文件为例)

1.原工程已经能切换不同的环境进行测试:测试1,测试2,测试3,生产。通过全局变量即可实现

2.客服功能不仅和第一步修改的有关,它还有自己的一些网关配置,放在客户端的一个plist文件里

3.打包后第一步的全局变量可以改,但第三方读取的plist却不能改了

下边对这个文件重定向,就是把这个plist放在客户端里四份,每份对应一个环境,然后根据第一步设置的全局服务器地址来重定向客服的配置文件。

4.工程中添加fishhook的相关文件,代码

static int (*orig_open)(const char *, int, ...);
int my_open(const char *path, int oflag, ...) {
    va_list ap = {0};
    mode_t mode = 0;

    if ((oflag & O_CREAT) != 0) {
        // mode only applies to O_CREAT
        va_start(ap, oflag);
        mode = va_arg(ap, int);
        va_end(ap);
        printf("Calling real open('%s', %d, %d)\n", path, oflag, mode);
        return orig_open(path, oflag, mode);
    } else {
        printf("Calling real open('%s', %d)\n", path, oflag);
        return orig_open(path, oflag, mode);
    }
}



        rebind_symbols((struct rebinding[1]){ {"open", my_open, (void *)&orig_open}}, 1);
        int fd = open(argv[0], O_RDONLY);
        uint32_t magic_number = 0;
        read(fd, &magic_number, 4);
        printf("Mach-O Magic Number: %x \n", magic_number);
        close(fd);

4.通过fishhook系统的open方法,得知读取的绝对路径还有读取方法

读取方法是
+[NSDictionary(NSDictionary) dictionaryWithContentsOfFile:]
路径是

"/var/containers/Bundle/Application/5EA79A8E-EC3B-4E5C-B44B-6E9E58E413FD/XXX.app/XXXConfig.plist"

5.这个都有了,然后就可以重定向了,把四个plist文件准备好,对应各自的环境,并改名

6.my_open方法内进行判断

int my_open(const char *path, int oflag, ...) {
    va_list ap = {0};
    mode_t mode = 0;
    
    if ((oflag & O_CREAT) != 0) {
        // mode only applies to O_CREAT
        va_start(ap, oflag);
        mode = va_arg(ap, int);
        va_end(ap);
        printf("Calling real open('%s', %d, %d)\n", path, oflag, mode);
        return orig_open(path, oflag, mode);
    } else {
        printf("Calling real open('%s', %d)\n", path, oflag);
        
        NSString *pathOri = [[NSString alloc]initWithUTF8String:path];
        
        //
        //读取的是客服配置文件 然后替换
        //
        if([pathOri rangeOfString:@"XXXConfig.plist"].length > 0){
            
            if(([globalServerUrl isEqualToString:@"https://xxx.com"])){
                //生产
                
            }else if ([globalServerUrl isEqualToString:@"http://testxxx.com"]) {
                //测试1
                path = [[pathOri stringByReplacingOccurrencesOfString:@"XXXConfig.plist" withString:@"XXXConfigVali.plist"] UTF8String];
            }else if ([globalServerUrl isEqualToString: @"https://xxxtest.com"]){
                //测试2
                path = [[pathOri stringByReplacingOccurrencesOfString:@"XXXConfig.plist" withString:@"XXXConfigDis.plist"] UTF8String];
            }else{
                //测试3
                path = [[pathOri stringByReplacingOccurrencesOfString:@"XXXConfig.plist" withString:@"XXXConfigDev.plist"] UTF8String];
                
            }
        }
        
        return orig_open(path, oflag, mode);
    }
}

7.完美解决。

8.其实只要知道了fishhook,这个很简单, 如果不知道可能都找不到调用的这个方法 dictionaryWithContentsOfFile。

发布了120 篇原创文章 · 获赞 15 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/qq_15509071/article/details/82893073