WKWebView使用過程的遇到的一些問題記錄/webView結合Safari調試

WKWebView加載問題

- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;

- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL API_AVAILABLE(macosx(10.11), ios(9.0));

- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;

- (nullable WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL API_AVAILABLE(macosx(10.11), ios(9.0));

baseURL須要注意javascript

  • 其中2個方式是ios9之後提供的
  • 方法參數baseURL,此參數是html加載的資源是基於的基礎路徑,也能夠理解爲資源加載引入的相對路徑,通常爲[[NSBundle mainBundle] bundleURL], 若是設置的是bundleURL那麼html中使用的資源引用相對路徑,相對路徑相對於bundle路徑 好比:<img src="base.png">,base.png就會在bundle資源中查找;
  • 若是baseURL設置的爲bundleURL,也能夠寫絕對路徑,絕對路徑爲bundle資源的絕對路徑. 好比html中引入了一些Js. css,png文件,如:
    <script type="text/javascript" src="/Users/HJiang/Library/Developer/CoreSimulator/Devices/BFE72029-56CE-4768-8312-05CA50250212/data/Containers/Bundle/Application/02F79F9E-AE1C-4BCA-9F2F-F9B253113E2C/xxxx.app/jquery.js">

    baseURL設置爲bundleURL後,引入資源方式css

  • 相對路徑
    <img src="tab.png">

     

  • 絕對路徑
    <img src="/Users/HJiang/Library/Developer/CoreSimulator/Devices/BFE72029-56CE-4768-8312-05CA50250212/data/Containers/Bundle/Application/02F79F9E-AE1C-4BCA-9F2F-F9B253113E2C/xxxx.app/tab.png">

     

WebKit訪問沙盒資源問題

baseURL設置爲bundleURLhtml

若是資源訪問的是沙盒中的資源,如:前端

模擬器目錄java

<body isAutoLoadImage ='1' background = '/Users/HJiang/Library/Developer/CoreSimulator/Devices/BFE72029-56CE-4768-8312-05CA50250212/data/Containers/Data/Application/6CD99493-3C89-40F0-A7C4-353DBA7893F3/Documents/waterfile/6005001463_2025.jpg'>

真機路徑jquery

<body isAutoLoadImage ='1' background = '/var/xxxx/Library//Devices/BFE72029-56CE-4768-8312-05CA50250212/data/Containers/Data/Application/6CD99493-3C89-40F0-A7C4-353DBA7893F3/Documents/waterfile/6005001463_2025.jpg'>

使用的是沙盒中絕對路徑,經測試此方式在模擬器上資源能夠正常訪問,真機沒法訪問資源ios

因webkit框架訪問沙盒資源存在bug,沒法加載經過絕對路徑訪問到資源.web

本人是經過如下方式解決的macos

webkit能夠經過路徑爲服務器方式就能夠加載服務器

GitHub上有個神器:GCDWebServer,此次就用的這個
經過pod集成

pod "GCDWebServer", "~> 3.0"

,直接上代碼

// 官方給的示例是在AppDelegate裏啓動本地服務器,可是我這個並無必要在APP啓動時就啓動本地服務器,因此我放在了核心功能控制器的viewDidLoad方法內
// 1.導入頭文件
#import <GCDWebServer/GCDWebDAVServer.h>
// 2.定義全局屬性
@property (nonatomic,strong) GCDWebServer *webSever;

// 3. 主要代碼
_webSever = [[GCDWebServer alloc] init];
[_webSever addGETHandlerForBasePath:@"/" directoryPath:NSHomeDirectory() indexFilename:nil cacheAge:3600 allowRangeRequests:YES];
[_webSever startWithPort:8007 bonjourName:nil];
// 說明:上面代碼就會在沙盒的根目錄中創建服務,端口爲8007;經過startWithPort就已經建立了服務

// 好了,這就結束了!WTF,這就完了,是的,能夠這麼說
// 比方說文件存在Library下有一個123的文件
NSString *basePath = @"http://localhost:8007/Library/water"; // 這樣就能夠訪問到這個文件了,我只須要把個人文件名拼上localhost路徑而後傳給前端,他們拿到這個連接直接訪問就能夠拿到這個文件了
.這樣就能夠訪問沙盒中的任何資源,填寫好路徑就OK
好比訪問Library目錄下water文件夾下的123.jpg,那麼路徑能夠爲<img src="http://localhost:8007/Library/water/123.jpg"
.若是想把服務的根路徑修改成沙盒的Documents目錄能夠修改directoryPath:參數路徑 [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]

這樣就模擬器和真機均可以訪問沙盒中的資源.

在不用的時候須要中止服務

[[ZTELocalResourceServer sharedLocalResourceServer] stop];

 

抽取了一個管理類

/**
 本地資源服務
 */
@interface LocalResourceServer : ZTEManagerBase

+ (instancetype)sharedLocalResourceServer;

- (void)start;
- (void)stop;

@end
#import "LocalResourceServer.h"

#import <GCDWebServer/GCDWebServer.h>

#import "LocalResourceDefine.h"

@interface LocalResourceServer ()

@property (nonatomic,strong) GCDWebServer *webSever;

@end

@implementation LocalResourceServer

+ (instancetype)sharedLocalResourceServer{
    static LocalResourceServer *localResourceServer = nil;
    
    static dispatch_once_t predicatemail;
    dispatch_once(&predicatemail, ^{
        
        localResourceServer = [[LocalResourceServer alloc] init];

    });
    
    return localResourceServer;
}

- (void)start{
    // 3. 啓動服務
    
    self.webSever = [[GCDWebServer alloc]init]; // NSHomeDirectory() or  [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
    [self.webSever addGETHandlerForBasePath:@"/" directoryPath:kDocumentsPath indexFilename:nil cacheAge:3600 allowRangeRequests:YES];
    [self.webSever startWithPort:kLocalServerPort bonjourName:nil];
}

- (void)stop{
    // 中止服務
    [self.webSever stop];
  self.webSever = nil; }

 WKWebView建立方法

+ (instancetype)sharedWebView:(CGRect)frame configuration:(WKWebViewConfiguration *)config{
    ZTEWebView *webView = nil;
    if(config == nil){
        // 禁止選擇CSS
        NSString *css = @"body{-webkit-user-select:none;}";
        
        // CSS選中樣式取消 此方式可能會影響dataDetectorTypes屬性
        NSMutableString *javascript = [NSMutableString string];
        [javascript appendString:@"var style = document.createElement('style');"];
        [javascript appendString:@"style.type = 'text/css';"];
        [javascript appendFormat:@"var cssContent = document.createTextNode('%@');", css];
        [javascript appendString:@"style.appendChild(cssContent);"];
        [javascript appendString:@"document.body.appendChild(style);"];
        
        // javascript注入
        WKUserScript *noneSelectScript = [[WKUserScript alloc] initWithSource:javascript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
        WKUserContentController *userContentController = [[WKUserContentController alloc] init];
//        [userContentController addUserScript:noneSelectScript];
        
        WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
        configuration.userContentController = userContentController;
//        if(greaterIOS10){
//            configuration.dataDetectorTypes = WKDataDetectorTypePhoneNumber | WKDataDetectorTypeLink | WKDataDetectorTypeCalendarEvent;
//        }
        
        WKPreferences *preferences = [[WKPreferences alloc] init];
        preferences.javaScriptCanOpenWindowsAutomatically = YES; // 不經過用戶交互,是否能夠打開窗口
        preferences.javaScriptEnabled = YES; //是否支持JavaScript
        preferences.minimumFontSize = 15.0; // 最小字體大小
        configuration.preferences = preferences; // 偏好設置
        webView = [[self alloc] initWithFrame:frame configuration:configuration];
    }else{
        webView = [[self alloc] initWithFrame:frame configuration:config];
    }
    
    return webView;
}

 

WebView調試

打開通用設置->Safari->高級->Web 檢查器 (模擬器和真機都同樣)

 

而後打開Mac Safari 偏好設置->高級

 

運行app,打開webView,而後打開safari開發菜單,選擇模擬器仍是iPhone,選擇對應的app就能夠跳出Html調試界面,此處就不調試截圖.

相關文章
相關標籤/搜索