iOS Ping 域名,多个动态域名修改更换

iOS Ping 域名,多个动态域名选择

因为我们的请求域名会出现一些情况导致无法使用的情况,所以在 App 发起数据请求之前,就要确定一个可使用的域名。这就是这次需求的目的。

动态域名选择条件

1、默认 IP 地址(防止基础域名和其他可选域名全都没用)。

2、基础域名(就是你默认的那个域名)。

废话不多说,看代码

- (void)pingHostURL:(NSString *)hostURL
{
    NSURL *candidate = [NSURL URLWithString:hostURL];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:candidate];
    [request setHTTPMethod:@"HEAD"];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        BOOL isSuccess = YES;
        if (error) {
            NSLog(@"pingHostURL:%@ 不可用", hostURL);
            isSuccess = NO;
        }else{
            isSuccess = YES;
            NSLog(@"pingHostURL:%@ 可用", hostURL);
        }
        [self.hostBoolDict setValue:[NSNumber numberWithBool:isSuccess] forKey:hostURL];
        [self pingSuccess:isSuccess host:hostURL];
    }];
    [task resume];
}

假如你有多个域名要去循环 ping 来进行选择,一个 for 循环,一个 NSMutableDictionary,一个 ping 的结果的处理方法。

- (void)pingSuccess:(BOOL)success host:(NSString *)hostURL
{
    NSLog(@"ping 的 hostURL = %@, 成功与否 = %i", hostURL, success);

    if (!success) { // 当前域名无法 ping 通
        NSLog(@"ping 失败的 hostURL = %@", hostURL);
        
        NSArray *valueArr = [self.hostBoolDict allValues];
        NSLog(@"VALUEARR = %@ , self.hostURLs = %@", valueArr, self.hostURLs);
        
        for (NSNumber *number in valueArr) {
            if ([number boolValue]) { // 存在成功过的域名
                return;
            }
        }
         // 全部备用域名 ping 失败之后,才选择 IP 地址
        if (valueArr.count < self.hostURLs.count) {
            return;
        }
        
        if (self.pingingType == DDHostPingPingingTypeClientInit) {
            self.startClientInitPing = NO;
            self.hasPingClientInitHost = YES;
            
        } else if (self.pingingType == DDHostPingPingingTypeOther) {
            self.startOtherPing = NO;
        }
        
      // 测试环境
        if ([HostUrlManager shareInstance].Env == TestType) {
            NSString *ipHostURL = @"http://xx.xxx.xxx.xx"; // IP 地址
            self.currentHostUrl = ipHostURL;
            [[HostUrlManager shareInstance] configIPHostURL:ipHostURL];
            
        } else if ([HostUrlManager shareInstance].Env == ReleaseType) { // 正式环境
            NSString *ipHostURL = @"http://xx.xxx.xxx.xx"; // IP 地址
            self.currentHostUrl = ipHostURL;
            [[HostUrlManager shareInstance] configIPHostURL:ipHostURL];
        }
        
     
      if (self.delegate && [self.delegate respondsToSelector:@selector(hostPingManagerCompletionWithHost:success:)]) {
                [self.delegate hostPingManagerCompletionWithHost:self.currentHostUrl success:success];
            }
 
    } else {
        if (self.pingingType == DDHostPingPingingTypeClientInit) {
            self.startClientInitPing = NO;
            self.hasPingClientInitHost = YES;
        } else if (self.pingingType == DDHostPingPingingTypeOther) {
            self.startOtherPing = NO;
        }
        
        BOOL isDebug = NO;
        if ([HostUrlManager shareInstance].Env == TestType) {
            isDebug = YES;
        } else if ([HostUrlManager shareInstance].Env == ReleaseType) {
            isDebug = NO;
        }
        
        NSLog(@"ping 成功的 hostURL = %@", hostURL);
      // 修改你的默认域名配置
        self.currentHostUrl = hostURL;
        [[HostUrlManager shareInstance] configDefaultHostURL:hostURL];
        
        if (self.delegate && [self.delegate respondsToSelector:@selector(hostPingManagerCompletionWithHost:success:)]) {
            [self.delegate hostPingManagerCompletionWithHost:self.currentHostUrl success:success];
            }
        }
}

代码解释

HostUrlManager 是一个网址单例,每次发起的请求的域名都是从它这边拿到的。所以有两个方法,第一个 configIPHostURL 第二个 configDefaultHostURL 内部会判断是否有 IP 地址,还有 default 地址,如果这两个存在,会优先 return defaultURL,目的就是尽量少使用 IP 地址。

自己遇到的难点

1、测试环境和正式环境的不同转换。

2、初始配置请求和其他网络请求的影响。

3、如果后端返回的域名能够 ping 通,但实际上他的域名不能使用,例如返回 https://www.baidu.com ,我们是能够 ping 通并替换掉默认的选项的。需要自己建立一个 reset 机制,如果使用这个域名,一分钟内请求多次不成功,就重新刷新为最初始的各个域名参数。

4、ping 在客户端的实际表达。用过 SimplePing, 也用过 Reachability 库来进行 ping 的表达。都不甚如人意。

工作较忙,文章较混乱,实在抱歉。如有建议,欢迎斧正。

你可能感兴趣的:(iOS Ping 域名,多个动态域名修改更换)