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;
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM