欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

iOS WKWebview 白屏檢測(cè)實(shí)現(xiàn)的示例

 更新時(shí)間:2020年10月20日 11:48:12   作者:BBTIME  
這篇文章主要介紹了iOS WKWebview 白屏檢測(cè)實(shí)現(xiàn)的示例,幫助大家更好的進(jìn)行ios開發(fā),感興趣的朋友可以了解下

前言

    自ios8推出wkwebview以來(lái),極大改善了網(wǎng)頁(yè)加載速度及內(nèi)存泄漏問題,逐漸全面取代笨重的UIWebview。盡管高性能、高刷新的WKWebview在混合開發(fā)中大放異彩表現(xiàn)優(yōu)異,但加載網(wǎng)頁(yè)過(guò)程中出現(xiàn)異常白屏的現(xiàn)象卻仍然屢見不鮮,且現(xiàn)有的api協(xié)議處理捕捉不到這種異常case,造成用戶無(wú)用等待體驗(yàn)很差。
    針對(duì)業(yè)務(wù)場(chǎng)景需求,實(shí)現(xiàn)加載白屏檢測(cè)??紤]采用字節(jié)跳動(dòng)團(tuán)隊(duì)提出的webview優(yōu)化技術(shù)方案。在合適的加載時(shí)機(jī)對(duì)當(dāng)前webview可視區(qū)域截圖,并對(duì)此快照進(jìn)行像素點(diǎn)遍歷,如果非白屏顏色的像素點(diǎn)超過(guò)一定的閾值,認(rèn)定其為非白屏,反之重新加載請(qǐng)求。

獲取快照

    ios官方提供了簡(jiǎn)易的獲取webview快照接口,通過(guò)異步回調(diào)拿到當(dāng)前可視區(qū)域的屏幕截圖。

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

其中snapshotConfiguration 參數(shù)可用于配置快照大小范圍,默認(rèn)截取當(dāng)前客戶端整個(gè)屏幕區(qū)域。由于可能出現(xiàn)導(dǎo)航欄成功加載而內(nèi)容頁(yè)卻空白的特殊情況,導(dǎo)致非白屏像素點(diǎn)數(shù)增加對(duì)最終判定結(jié)果造成影響,考慮將其剔除。

- (void)judgeLoadingStatus:(WKWebView *)webview {
  if (@available(iOS 11.0, *)) {
    if (webView && [webView isKindOfClass:[WKWebView class]]) {

      CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height; //狀態(tài)欄高度
      CGFloat navigationHeight = webView.viewController.navigationController.navigationBar.frame.size.height; //導(dǎo)航欄高度
      WKSnapshotConfiguration *shotConfiguration = [[WKSnapshotConfiguration alloc] init];
      shotConfiguration.rect = CGRectMake(0, statusBarHeight + navigationHeight, _webView.bounds.size.width, (_webView.bounds.size.height - navigationHeight - statusBarHeight)); //僅截圖檢測(cè)導(dǎo)航欄以下部分內(nèi)容
      [_webView takeSnapshotWithConfiguration:shotConfiguration completionHandler:^(UIImage * _Nullable snapshotImage, NSError * _Nullable error) {
        //todo
      }];
    }
  }
}

縮放快照

為了提升檢測(cè)性能,考慮將快照縮放至1/5,減少像素點(diǎn)總數(shù),從而加快遍歷速度。

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

縮小前后性能對(duì)比(實(shí)驗(yàn)環(huán)境:iPhone11同一頁(yè)面下):

縮放前白屏檢測(cè):

耗時(shí)20ms

縮放后白屏檢測(cè):

耗時(shí)13ms

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

遍歷快照

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

- (BOOL)searchEveryPixel:(UIImage *)image {
  CGImageRef cgImage = [image CGImage];
  size_t width = CGImageGetWidth(cgImage);
  size_t height = CGImageGetHeight(cgImage);
  size_t bytesPerRow = CGImageGetBytesPerRow(cgImage); //每個(gè)像素點(diǎn)包含r g b a 四個(gè)字節(jié)
  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āng)前像素點(diǎn)數(shù):%d,白色像素點(diǎn)數(shù):%d , 占比: %f",totalCount , whiteCount , proportion );
  if (proportion > 0.95) {
    return YES;
  }else{
    return NO;
  }
}

總結(jié)

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; //狀態(tài)欄高度
      CGFloat navigationHeight = webview.viewController.navigationController.navigationBar.frame.size.height; //導(dǎo)航欄高度
      WKSnapshotConfiguration *shotConfiguration = [[WKSnapshotConfiguration alloc] init];
      shotConfiguration.rect = CGRectMake(0, statusBarHeight + navigationHeight, webview.bounds.size.width, (webview.bounds.size.height - navigationHeight - statusBarHeight)); //僅截圖檢測(cè)導(dǎo)航欄以下部分內(nèi)容
      [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);
        }
      }];
    }
  }
}

// 遍歷像素點(diǎn) 白色像素占比大于95%認(rèn)定為白屏
- (BOOL)searchEveryPixel:(UIImage *)image {
  CGImageRef cgImage = [image CGImage];
  size_t width = CGImageGetWidth(cgImage);
  size_t height = CGImageGetHeight(cgImage);
  size_t bytesPerRow = CGImageGetBytesPerRow(cgImage); //每個(gè)像素點(diǎn)包含r g b a 四個(gè)字節(jié)
  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āng)前像素點(diǎn)數(shù):%d,白色像素點(diǎn)數(shù):%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生命周期內(nèi)回調(diào)使用該函數(shù)方法即可檢測(cè)出頁(yè)面狀態(tài)是否白屏,且性能損耗可忽略不計(jì)。

聲明

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

以上就是iOS WKWebview 白屏檢測(cè)實(shí)現(xiàn)的示例的詳細(xì)內(nèi)容,更多關(guān)于iOS WKWebview 白屏檢測(cè)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • IOS 常見的循環(huán)引用總結(jié)

    IOS 常見的循環(huán)引用總結(jié)

    這篇文章主要介紹了IOS 常見的循環(huán)引用總結(jié)的相關(guān)資料,循環(huán)引用,指的是多個(gè)對(duì)象相互引用時(shí),使得引用形成一個(gè)環(huán)形,導(dǎo)致外部無(wú)法真正是否掉這塊環(huán)形內(nèi)存。其實(shí)有點(diǎn)類似死鎖,需要的朋友可以參考下
    2017-03-03
  • 關(guān)于ios配置微信config出現(xiàn)驗(yàn)簽失敗的問題解決

    關(guān)于ios配置微信config出現(xiàn)驗(yàn)簽失敗的問題解決

    這篇文章主要介紹了關(guān)于ios配置微信config出現(xiàn)驗(yàn)簽失敗的問題解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • iOS 中使用tableView實(shí)現(xiàn)右滑顯示選擇功能

    iOS 中使用tableView實(shí)現(xiàn)右滑顯示選擇功能

    這篇文章主要介紹了iOS 中使用tableView實(shí)現(xiàn)右滑顯示選擇功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • iOS tableView實(shí)現(xiàn)單選和多選的實(shí)例代碼

    iOS tableView實(shí)現(xiàn)單選和多選的實(shí)例代碼

    本篇文章主要介紹了iOS tableView實(shí)現(xiàn)單選和多選的實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • IOS實(shí)現(xiàn)圖片輪播無(wú)限循環(huán)效果

    IOS實(shí)現(xiàn)圖片輪播無(wú)限循環(huán)效果

    這篇文章主要為大家詳細(xì)介紹了IOS實(shí)現(xiàn)圖片輪播無(wú)限循環(huán)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-03-03
  • iOS逆向開發(fā)之微信自動(dòng)添加好友功能

    iOS逆向開發(fā)之微信自動(dòng)添加好友功能

    這篇文章主要介紹了iOS逆向開發(fā)之微信自動(dòng)添加好友功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-04-04
  • iOS中UIScrollView嵌套UITableView的實(shí)踐教程

    iOS中UIScrollView嵌套UITableView的實(shí)踐教程

    在UIScrollView嵌套UITableView的問題相信大家都遇到過(guò),小編最近在工作中就遇到了這個(gè)問題,所以這篇文章主要介紹了iOS中UIScrollView嵌套UITableView的相關(guān)資料,文中介紹的方法是通過(guò)自己的實(shí)踐所得來(lái)的,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-05-05
  • iOS中監(jiān)聽UITextField值改變事件的方法實(shí)例

    iOS中監(jiān)聽UITextField值改變事件的方法實(shí)例

    UITextField 是一個(gè)用來(lái)處理文本輸入和現(xiàn)實(shí)的控件,在我們的開發(fā)當(dāng)中也是經(jīng)常被用到。下面這篇文章主要給大家介紹了關(guān)于iOS中監(jiān)聽UITextField值改變事件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-07-07
  • iOS打電話、發(fā)短信、發(fā)郵件實(shí)例代碼

    iOS打電話、發(fā)短信、發(fā)郵件實(shí)例代碼

    這篇文章主要為大家詳細(xì)介紹了iOS打電話、發(fā)短信、發(fā)郵件實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • iOS使用GCDSocketManager實(shí)現(xiàn)長(zhǎng)連接的方法

    iOS使用GCDSocketManager實(shí)現(xiàn)長(zhǎng)連接的方法

    下面想就為大家分享一篇iOS使用GCDSocketManager實(shí)現(xiàn)長(zhǎng)連接的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12

最新評(píng)論