ios基于webview混合开发偶现页面刷新问题

一、问题场景

App 打开,放置在测试中心,偶尔会出现从B页面刷新跳转到A页面。

二、问题分析

1、刚开始怀疑是否前端业务应用中有定时器,或者因为token 失效会进行跳转处理,和前端确认后没有此类代码。并且此问题在Web和 Android 端都没有,苹果端也只在那一台手机上出现。

2、fiddler 抓包

根据 全网最详细,Fiddler抓包实战 - 手机APP端https请求(超详细)_fiddler抓包手机app-CSDN博客

进行fiddler 配置和手机端代理配置,刚开始手机端使用默认的8888 端口总是无法上网,后续将fiddler 的默认端口换成了 8088 , 手机端同样配置,似乎正常了。

接着又出现:

!SecureClientPipeDirect failed: System.IO.IOException 由于远程方已关闭传输流,身份验证失败。 for pipe (CN=gateway.icloud.com.cn, O=DO_NOT_TRUST, OU=Created by http://www.fiddler2.com)

17:19:34:2393 HTTPSLint> Warning: ClientHello record was 508 bytes long. Some servers have problems with ClientHello's greater than 255

想了想是不是换了端口,这个fiddler 的ssl 证书需要重新安装更新,并且手机端也需要安装对应的证书进行信任。

这样正常可以抓包后,其实还是遇到了某些接口无法正常抓到的问题

此时可能是因为调用的接口中有对证书进 验证,发现证书的域名可能和实际的fiddler 这个证书不一致,从而导致接口返回失败造成的。这种情况的抓包还不知道要怎么处理,不过目前没有时间关注这个问题,最后确实抓到了一次页面刷新,看到的接口请求地址都是首页。

3、为了排除问题,刚开始想到的是在所有webview 有可能reload 的地方加入日志进行处理,并记录到手机沙盒里面:

复制代码
#import "WebViewLogger.h"

@implementation WebViewLogger


+ (void)logWebRequest:(NSURLRequest *)request from:(NSString *)sourcePage {
    NSString *logStr = @"";
    if(nil == request){
        logStr = [NSString stringWithFormat:@"[%@] %@ | From: %@ | URL: %@\n",
                            [self currentTimeString],
                            @"非请求",
                            sourcePage,
                            request.URL.absoluteString];
    }else{
        logStr = [NSString stringWithFormat:@"[%@] %@ | From: %@ | URL: %@\n",
                            [self currentTimeString],
                            request.HTTPMethod,
                            sourcePage,
                            request.URL.absoluteString];
    }
    NSLog(@"=====debug %@", logStr);
    [self writeLogToFile:logStr];
}

+ (NSString *)currentTimeString {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSS"];
    return [formatter stringFromDate:[NSDate date]];
}

+ (void)writeLogToFile:(NSString *)log {
    NSString *filePath = [self logFilePath];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    if (![fileManager fileExistsAtPath:filePath]) {
        [fileManager createFileAtPath:filePath contents:nil attributes:nil];
    }
    
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
    [fileHandle seekToEndOfFile];
    [fileHandle writeData:[log dataUsingEncoding:NSUTF8StringEncoding]];
    [fileHandle closeFile];
}

+ (NSString *)logFilePath {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [paths firstObject];
    return [documentsDir stringByAppendingPathComponent:@"webview_requests.log"];
}

@end

但是复现问题后发现都是正常加载逻辑,没有任何异常地方会去重新刷新。然后自己还在某个地方手机添加了一次reload 的操作,抓取日志后,发现即使reload 也不会到首页,而是带有菜单路由的当前页面,所以排除是异常导致的reload 逻辑造成此问题。

4、由于问题复现的场景只在测试中心,还是怀疑到网络来了,无心中增加了网络检测的回调日志,发现果然有输出:

在网络变化十秒钟之后就出现了重载的日志。

三、破局

经过如上分析后,慢慢定位就是网络变化导致的重载,然后想起代码中之前有一个适配App首次使用网络授权的处理逻辑。
iOS 10 的坑:新机首次安装 app,请求网络权限"是否允许使用数据"(转) - 那一抹风情 - 博客园

复制代码
 CTCellularData *cellularData = [[CTCellularData alloc]init];
 CTCellularDataRestrictedState state = cellularData.restrictedState;
 if(state == kCTCellularDataNotRestricted){
}else{
 cellularData.cellularDataRestrictionDidUpdateNotifier = ^(CTCellularDataRestrictedState state) {
 if (state == kCTCellularDataRestricted) {
                       NSLog(@"networkAuthStatus 用户选择网络使用受限制");
                   } else if (state == kCTCellularDataNotRestricted) {
                       NSLog(@"networkAuthStatus 用户选择网络使用不受限制");
                   } else {
                       NSLog(@"networkAuthStatus 网络权限使用未知");
                   }
                   dispatch_async(dispatch_get_main_queue(), ^{
                       [self processViewLoadDependNetwork];
                   });
               };
}

而测试中心的那台手机在那个办公室就经常会触发这个回调,当手动开关蜂窝网络的时候也能够复现,但是具体那哪些场景会触发这个回调,这个还是不太清楚,后续让测试复测,发现关闭蜂窝网络,wifi 变化也可能会触发这个回调,只能说这个网络授权的适配还是挺让折磨人的,一个问题又耗费了将近两天的时间来分析。

相关推荐
与火星的孩子对话15 分钟前
Unity进阶课程【六】Android、ios、Pad 终端设备打包局域网IP调试、USB调试、性能检测、控制台打印日志等、C#
android·unity·ios·c#·ip
恋猫de小郭1 天前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
点金石游戏出海1 天前
每周资讯 | Krafton斥资750亿日元收购日本动画公司ADK;《崩坏:星穹铁道》新版本首日登顶iOS畅销榜
游戏·ios·业界资讯·apple·崩坏星穹铁道
旷世奇才李先生1 天前
Swift 安装使用教程
开发语言·ios·swift
90后的晨仔1 天前
Xcode16报错: SDK does not contain 'libarclite' at the path '/Applicati
ios
finger244801 天前
谈一谈iOS线程管理
ios·objective-c
Digitally1 天前
如何将大型视频文件从 iPhone 传输到 PC
ios·iphone
梅名智1 天前
IOS 蓝牙连接
macos·ios·cocoa
美狐美颜sdk2 天前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk
恋猫de小郭2 天前
Meta 宣布加入 Kotlin 基金会,将为 Kotlin 和 Android 生态提供全新支持
android·开发语言·ios·kotlin