国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

iOS WKWebview 白屏檢測實現的示例

瀏覽:33日期:2022-09-17 08:22:41

前言

自ios8推出wkwebview以來,極大改善了網頁加載速度及內存泄漏問題,逐漸全面取代笨重的UIWebview。盡管高性能、高刷新的WKWebview在混合開發中大放異彩表現優異,但加載網頁過程中出現異常白屏的現象卻仍然屢見不鮮,且現有的api協議處理捕捉不到這種異常case,造成用戶無用等待體驗很差。 針對業務場景需求,實現加載白屏檢測。考慮采用字節跳動團隊提出的webview優化技術方案。在合適的加載時機對當前webview可視區域截圖,并對此快照進行像素點遍歷,如果非白屏顏色的像素點超過一定的閾值,認定其為非白屏,反之重新加載請求。

獲取快照

ios官方提供了簡易的獲取webview快照接口,通過異步回調拿到當前可視區域的屏幕截圖。

- (void)takeSnapshotWithConfiguration:(nullable WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void (^)(UIImage * _Nullable snapshotImage, NSError * _Nullable error))completionHandler API_AVAILABLE(ios(11.0));

其中snapshotConfiguration 參數可用于配置快照大小范圍,默認截取當前客戶端整個屏幕區域。由于可能出現導航欄成功加載而內容頁卻空白的特殊情況,導致非白屏像素點數增加對最終判定結果造成影響,考慮將其剔除。

- (void)judgeLoadingStatus:(WKWebView *)webview { if (@available(iOS 11.0, *)) { if (webView && [webView isKindOfClass:[WKWebView class]]) { CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height; //狀態欄高度 CGFloat navigationHeight = webView.viewController.navigationController.navigationBar.frame.size.height; //導航欄高度 WKSnapshotConfiguration *shotConfiguration = [[WKSnapshotConfiguration alloc] init]; shotConfiguration.rect = CGRectMake(0, statusBarHeight + navigationHeight, _webView.bounds.size.width, (_webView.bounds.size.height - navigationHeight - statusBarHeight)); //僅截圖檢測導航欄以下部分內容 [_webView takeSnapshotWithConfiguration:shotConfiguration completionHandler:^(UIImage * _Nullable snapshotImage, NSError * _Nullable error) {//todo }]; } }}

縮放快照

為了提升檢測性能,考慮將快照縮放至1/5,減少像素點總數,從而加快遍歷速度。

- (UIImage *)scaleImage: (UIImage *)image { CGFloat scale = 0.2; CGSize newsize; newsize.width = floor(image.size.width * scale); newsize.height = floor(image.size.height * scale); if (@available(iOS 10.0, *)) { UIGraphicsImageRenderer * renderer = [[UIGraphicsImageRenderer alloc] initWithSize:newsize]; return [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) { [image drawInRect:CGRectMake(0, 0, newsize.width, newsize.height)]; }]; }else{ return image; }}

縮小前后性能對比(實驗環境:iPhone11同一頁面下):

縮放前白屏檢測:

iOS WKWebview 白屏檢測實現的示例

iOS WKWebview 白屏檢測實現的示例

耗時20ms

縮放后白屏檢測:

iOS WKWebview 白屏檢測實現的示例

iOS WKWebview 白屏檢測實現的示例

耗時13ms

注意這里有個小坑。由于縮略圖的尺寸在 原圖寬高*縮放系數后可能不是整數,在布置畫布重繪時默認向上取整,這就造成畫布比實際縮略圖大(混蛋啊 摔!)。在遍歷縮略圖像素時,會將圖外畫布上的像素納入考慮范圍,導致實際白屏頁 像素占比并非100% 如圖所示。因此使用floor將其尺寸大小向下取整。

遍歷快照

遍歷快照縮略圖像素點,對白色像素(R:255 G: 255 B: 255)占比大于95%的頁面,認定其為白屏。

- (BOOL)searchEveryPixel:(UIImage *)image { CGImageRef cgImage = [image CGImage]; size_t width = CGImageGetWidth(cgImage); size_t height = CGImageGetHeight(cgImage); size_t bytesPerRow = CGImageGetBytesPerRow(cgImage); //每個像素點包含r g b a 四個字節 size_t bitsPerPixel = CGImageGetBitsPerPixel(cgImage); CGDataProviderRef dataProvider = CGImageGetDataProvider(cgImage); CFDataRef data = CGDataProviderCopyData(dataProvider); UInt8 * buffer = (UInt8*)CFDataGetBytePtr(data); int whiteCount = 0; int totalCount = 0; for (int j = 0; j < height; j ++ ) { for (int i = 0; i < width; i ++) { UInt8 * pt = buffer + j * bytesPerRow + i * (bitsPerPixel / 8); UInt8 red = * pt; UInt8 green = *(pt + 1); UInt8 blue = *(pt + 2);// UInt8 alpha = *(pt + 3); totalCount ++; if (red == 255 && green == 255 && blue == 255) {whiteCount ++; } } } float proportion = (float)whiteCount / totalCount ; NSLog(@'當前像素點數:%d,白色像素點數:%d , 占比: %f',totalCount , whiteCount , proportion ); if (proportion > 0.95) { return YES; }else{ return NO; }}

總結

typedef NS_ENUM(NSUInteger,webviewLoadingStatus) { WebViewNormalStatus = 0, //正常 WebViewErrorStatus, //白屏 WebViewPendStatus, //待決};// 判斷是否白屏- (void)judgeLoadingStatus:(WKWebview *)webview withBlock:(void (^)(webviewLoadingStatus status))completionBlock{ webviewLoadingStatus __block status = WebViewPendStatus; if (@available(iOS 11.0, *)) { if (webview && [webview isKindOfClass:[WKWebView class]]) { CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height; //狀態欄高度 CGFloat navigationHeight = webview.viewController.navigationController.navigationBar.frame.size.height; //導航欄高度 WKSnapshotConfiguration *shotConfiguration = [[WKSnapshotConfiguration alloc] init]; shotConfiguration.rect = CGRectMake(0, statusBarHeight + navigationHeight, webview.bounds.size.width, (webview.bounds.size.height - navigationHeight - statusBarHeight)); //僅截圖檢測導航欄以下部分內容 [webview takeSnapshotWithConfiguration:shotConfiguration completionHandler:^(UIImage * _Nullable snapshotImage, NSError * _Nullable error) {if (snapshotImage) { CGImageRef imageRef = snapshotImage.CGImage; UIImage * scaleImage = [self scaleImage:snapshotImage]; BOOL isWhiteScreen = [self searchEveryPixel:scaleImage]; if (isWhiteScreen) { status = WebViewErrorStatus; }else{ status = WebViewNormalStatus; }}if (completionBlock) { completionBlock(status);} }]; } }}// 遍歷像素點 白色像素占比大于95%認定為白屏- (BOOL)searchEveryPixel:(UIImage *)image { CGImageRef cgImage = [image CGImage]; size_t width = CGImageGetWidth(cgImage); size_t height = CGImageGetHeight(cgImage); size_t bytesPerRow = CGImageGetBytesPerRow(cgImage); //每個像素點包含r g b a 四個字節 size_t bitsPerPixel = CGImageGetBitsPerPixel(cgImage); CGDataProviderRef dataProvider = CGImageGetDataProvider(cgImage); CFDataRef data = CGDataProviderCopyData(dataProvider); UInt8 * buffer = (UInt8*)CFDataGetBytePtr(data); int whiteCount = 0; int totalCount = 0; for (int j = 0; j < height; j ++ ) { for (int i = 0; i < width; i ++) { UInt8 * pt = buffer + j * bytesPerRow + i * (bitsPerPixel / 8); UInt8 red = * pt; UInt8 green = *(pt + 1); UInt8 blue = *(pt + 2);// UInt8 alpha = *(pt + 3); totalCount ++; if (red == 255 && green == 255 && blue == 255) {whiteCount ++; } } } float proportion = (float)whiteCount / totalCount ; NSLog(@'當前像素點數:%d,白色像素點數:%d , 占比: %f',totalCount , whiteCount , proportion ); if (proportion > 0.95) { return YES; }else{ return NO; }}//縮放圖片- (UIImage *)scaleImage: (UIImage *)image { CGFloat scale = 0.2; CGSize newsize; newsize.width = floor(image.size.width * scale); newsize.height = floor(image.size.height * scale); if (@available(iOS 10.0, *)) { UIGraphicsImageRenderer * renderer = [[UIGraphicsImageRenderer alloc] initWithSize:newsize]; return [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) { [image drawInRect:CGRectMake(0, 0, newsize.width, newsize.height)]; }]; }else{ return image; }}

僅需在合適的view生命周期內回調使用該函數方法即可檢測出頁面狀態是否白屏,且性能損耗可忽略不計。

聲明

作者:BBTime鏈接:https://juejin.im/post/6885298718174609415

以上就是iOS WKWebview 白屏檢測實現的示例的詳細內容,更多關于iOS WKWebview 白屏檢測的資料請關注好吧啦網其它相關文章!

標簽: IOS
相關文章:
主站蜘蛛池模板: 久久公开视频 | 久久久精品免费观看 | 免费看又黄又爽又猛的网站 | 欧美日韩国产在线人成dvd | 99国产成人高清在线视频 | 精品特级一级毛片免费观看 | 国产一区二区三区在线视频 | 免费看欧美一级特黄a毛片 免费看片aⅴ免费大片 | 欧美日韩亚洲成色二本道三区 | 多人伦精品一区二区三区视频 | 色综合亚洲七七久久桃花影院 | 精品国产免费观看久久久 | 欧美xxxxx毛片| 国产亚洲亚洲精品777 | 亚洲天码中文字幕第一页 | 亚洲福利视频一区二区三区 | 亚洲狠狠综合久久 | 九九51精品国产免费看 | 日本一区二区不卡久久入口 | 日韩欧美第一页 | 一级成人黄色片 | 欧美黄色a | 欧美综合视频在线观看 | 国产三级麻豆 | 午夜人成 | 中文字幕天堂最新版在线网 | 亚洲欧美久久精品一区 | 欧美成人性做爰网站免费 | 99精品在线视频观看 | 久久精品二三区 | 亚洲免费高清 | 日本无卡码一区二区三区 | 日韩18在线观看地址 | 精品国产免费一区二区三区五区 | 91欧美激情一区二区三区成人 | 杨晨晨福利视频 | 99国产精品九九视频免费看 | 91av成年影院在线播放 | 精品视频自拍 | 亚洲女精品一区二区三区 | 精品日韩在线视频一区二区三区 |