diff --git a/XWebView/XWebView.swift b/XWebView/XWebView.swift index d1f0d79..c231529 100644 --- a/XWebView/XWebView.swift +++ b/XWebView/XWebView.swift @@ -102,19 +102,34 @@ extension WKWebView { // See http://nshipster.com/swift-objc-runtime/ private static var initialized: dispatch_once_t = 0 public override class func initialize() { - //if #available(iOS 9, *) { return } guard self == WKWebView.self else { return } dispatch_once(&initialized) { - let selector = Selector("loadFileURL:allowingReadAccessToURL:") - let method = class_getInstanceMethod(self, Selector("_loadFileURL:allowingReadAccessToURL:")) - assert(method != nil) - if class_addMethod(self, selector, method_getImplementation(method), method_getTypeEncoding(method)) { - print("iOS 8.x") - method_exchangeImplementations( - class_getInstanceMethod(self, Selector("loadHTMLString:baseURL:")), - class_getInstanceMethod(self, Selector("_loadHTMLString:baseURL:")) - ) - } + let loadFileURLSelector = Selector("loadFileURL:allowingReadAccessToURL:") + let loadHTMLStringSelector = Selector("loadHTMLString:baseURL:") + let customLoadHTMLStringSelector = Selector("_loadHTMLString:baseURL:") + let customLoadFileURLSelector = Selector("_loadFileURL:allowingReadAccessToURL:") + + let loadFileURLMethod = class_getInstanceMethod( + self, + customLoadFileURLSelector + ) + let loadHTMLStringMethod = class_getInstanceMethod( + self, + customLoadHTMLStringSelector + ) + + assert(loadFileURLMethod != nil && loadHTMLStringMethod != nil) + + class_addMethod( + self, + loadFileURLSelector, + method_getImplementation(loadFileURLMethod), + method_getTypeEncoding(loadFileURLMethod) + ) + method_exchangeImplementations( + class_getInstanceMethod(self, loadHTMLStringSelector), + class_getInstanceMethod(self, customLoadHTMLStringSelector) + ) } } @@ -137,12 +152,18 @@ extension WKWebView { return nil } + // Although iOS 9.x loadHTMLString and loadData can't use baseURL with file protocol access. + // But for Simulator you can use loadHTMLString and loadData with file:/// as baseURL and access + // all of your resources. Accessing local data is restricted for devices and the unique folder + // that you can access is tmp folder. + // + // It continues to be necessary with you pretend to render pages such as dynamic templates. @objc private func _loadHTMLString(html: String, baseURL: NSURL) -> WKNavigation? { guard baseURL.fileURL else { // call original method implementation return _loadHTMLString(html, baseURL: baseURL) } - + let fileManager = NSFileManager.defaultManager() var isDirectory: ObjCBool = false if fileManager.fileExistsAtPath(baseURL.path!, isDirectory: &isDirectory) && isDirectory { diff --git a/XWebViewTests/XWebViewTests.swift b/XWebViewTests/XWebViewTests.swift index 4c88b71..ca7d1c5 100644 --- a/XWebViewTests/XWebViewTests.swift +++ b/XWebViewTests/XWebViewTests.swift @@ -48,4 +48,28 @@ class XWebViewTests: XWVTestCase { waitForExpectationsWithTimeout(2, handler: nil) } } + + func testLoadHtmlStringWithNoBaseURL() { + expectationWithDescription("about:blank") + webview.loadHTMLString("", baseURL: nil) + waitForExpectationsWithTimeout(2, handler: nil) + } + + func testLoadHtmlStringWithFileAsBaseURL() { + let bundle = NSBundle(identifier:"org.xwebview.XWebViewTests") + let baseURL = bundle?.bundleURL.URLByAppendingPathComponent("www") + let split = "/:\\/\\/|:/" + let replace = "/\\./g" + expectationWithDescription("127001") //Original: http://127.0.0.1 + webview.loadHTMLString( + "" + + "" + + "" + + "" + + "", + baseURL: baseURL) + waitForExpectationsWithTimeout(2, handler: nil) + } }