Swift 4 Migration + Fixed Main Thread Checker Warnings/Crashes

This commit is contained in:
Mathias Köhnke 2017-09-23 12:47:52 +02:00
parent 58a2107758
commit 12e5b304a0
7 changed files with 84 additions and 46 deletions

View File

@ -39,7 +39,7 @@ class ViewController: NSViewController {
func getTopTrendingEntry(url: URL) {
open(url)
>>> get(by: .XPathQuery("//img[contains(@class, 'gh-octocat')]"))
>>> get(by: .XPathQuery("//img[contains(@alt, 'Github Octocat')]"))
>>> fetch
=== output
}

View File

@ -201,10 +201,12 @@
TargetAttributes = {
BF01D1421CB6DF400095BCE4 = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 0800;
DevelopmentTeam = 3FD8D4844P;
LastSwiftMigration = 0900;
};
BF01D15B1CB6DF690095BCE4 = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 0900;
};
};
};
@ -521,12 +523,16 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = 3FD8D4844P;
INFOPLIST_FILE = "Example iOS/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = de.mathiaskoehnke.Example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Example-Bridging-Header.h";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@ -536,12 +542,16 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = 3FD8D4844P;
INFOPLIST_FILE = "Example iOS/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = de.mathiaskoehnke.Example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Example-Bridging-Header.h";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Release;
};
@ -559,6 +569,8 @@
PRODUCT_BUNDLE_IDENTIFIER = "de.mathiaskoehnke.Example-OSX";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@ -576,6 +588,8 @@
PRODUCT_BUNDLE_IDENTIFIER = "de.mathiaskoehnke.Example-OSX";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Release;
};

View File

@ -1,6 +1,6 @@
PODS:
- hpple (0.2.0)
- WKZombie (1.0.8):
- WKZombie (1.1.0):
- hpple (= 0.2.0)
DEPENDENCIES:
@ -12,7 +12,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
hpple: 3b765f96fc2cd56ad1a49aef6f7be5cb2aa64b57
WKZombie: c7cd20015707cdda6b77bafa73cd095b15a69335
WKZombie: b92d04c503fd505b55f039387a54d741a775cdb6
PODFILE CHECKSUM: d530690e373e4c270897769971faa34622df5672

View File

@ -28,10 +28,10 @@ import WebKit
// MARK: RenderOperation
//========================================
typealias RequestBlock = (_ operation: RenderOperation) -> Void
internal class RenderOperation : Operation {
typealias RequestBlock = (_ operation: RenderOperation) -> Void
fileprivate(set) weak var webView : WKWebView?
fileprivate var timeout : Timer?
fileprivate let timeoutInSeconds : TimeInterval
@ -91,7 +91,13 @@ internal class RenderOperation : Operation {
startTimeout()
// Wait for WKWebView to finish loading before starting the operation.
wait { [unowned self] in self.webView?.isLoading == false }
wait { [unowned self] in
var isLoading : Bool = false
dispatch_sync_on_main_thread {
isLoading = self.webView?.isLoading ?? false
}
return isLoading == false
}
setupReferences()
requestBlock?(self)
@ -150,15 +156,19 @@ internal class RenderOperation : Operation {
}
fileprivate func setupReferences() {
webView?.configuration.userContentController.add(self, name: "doneLoading")
webView?.navigationDelegate = self
dispatch_sync_on_main_thread {
webView?.configuration.userContentController.add(self, name: "doneLoading")
webView?.navigationDelegate = self
}
}
fileprivate func cleanupReferences() {
webView?.navigationDelegate = nil
webView?.configuration.userContentController.removeScriptMessageHandler(forName: "doneLoading")
webView = nil
authenticationBlock = nil
dispatch_sync_on_main_thread {
webView?.navigationDelegate = nil
webView?.configuration.userContentController.removeScriptMessageHandler(forName: "doneLoading")
webView = nil
authenticationBlock = nil
}
}
}

View File

@ -96,7 +96,7 @@ internal class Renderer {
}
#elseif os(OSX)
self.webView = WKWebView(frame: CGRect.zero, configuration: config)
if let window = NSApplication.shared().keyWindow, let view = window.contentView {
if let window = NSApplication.shared.keyWindow, let view = window.contentView {
self.webView.frame = CGRect(origin: CGPoint.zero, size: view.frame.size)
self.webView.alphaValue = 0.01
view.addSubview(self.webView)
@ -118,15 +118,17 @@ internal class Renderer {
//========================================
internal func renderPageWithRequest(_ request: URLRequest, postAction: PostAction = .none, completionHandler: @escaping RenderCompletion) {
let requestBlock : (_ operation: RenderOperation) -> Void = { operation in
if let url = request.url , url.isFileURL {
if #available(OSX 10.11, *) {
_ = operation.webView?.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
let requestBlock : (_ operation: RenderOperation?) -> Void = { operation in
DispatchQueue.main.async {
if let url = request.url , url.isFileURL {
if #available(OSX 10.11, *) {
_ = operation?.webView?.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
} else {
preconditionFailure("OSX version lower 10.11 not supported.")
}
} else {
preconditionFailure("OSX version lower 10.11 not supported.")
_ = operation?.webView?.load(request)
}
} else {
_ = operation.webView?.load(request)
}
}
let operation = operationWithRequestBlock(requestBlock, postAction: postAction, completionHandler: completionHandler)
@ -140,18 +142,24 @@ internal class Renderer {
//========================================
internal func executeScript(_ script: String, willLoadPage: Bool? = false, postAction: PostAction = .none, completionHandler: RenderCompletion?) {
var requestBlock : (_ operation : RenderOperation) -> Void
var requestBlock : RequestBlock
if let willLoadPage = willLoadPage , willLoadPage == true {
requestBlock = { $0.webView?.evaluateJavaScript(script, completionHandler: nil) }
requestBlock = { operation in
DispatchQueue.main.async {
operation.webView?.evaluateJavaScript(script, completionHandler: nil)
}
}
} else {
requestBlock = { operation in
operation.webView?.evaluateJavaScript(script, completionHandler: { result, error in
var data : Data?
if let result = result {
data = "\(result)".data(using: String.Encoding.utf8)
}
operation.completeRendering(operation.webView, result: data, error: error)
})
DispatchQueue.main.async {
operation.webView?.evaluateJavaScript(script, completionHandler: { result, error in
var data : Data?
if let result = result {
data = "\(result)".data(using: String.Encoding.utf8)
}
operation.completeRendering(operation.webView, result: data, error: error)
})
}
}
}
let operation = operationWithRequestBlock(requestBlock, postAction: postAction, completionHandler: completionHandler)

View File

@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "WKZombie"
s.version = "1.0.8"
s.version = "1.1.0"
s.summary = "WKZombie is a Swift library for iOS/OSX to browse websites without the need of User Interface or API."
s.description = <<-DESC
@ -27,5 +27,5 @@ Pod::Spec.new do |s|
s.dependency 'hpple', '0.2.0'
s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3.0' }
s.pod_target_xcconfig = { 'SWIFT_VERSION' => '4.0' }
end

View File

@ -89,7 +89,7 @@
BF1F91951CB6D9BF00A58A7F /* Hpple.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Hpple.framework; path = Carthage/Checkouts/hpple/Framework/build/Debug/Hpple.framework; sourceTree = "<group>"; };
BF1F91971CB6DC6E00A58A7F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Framework/Info.plist; sourceTree = SOURCE_ROOT; };
BF1F91981CB6DC6E00A58A7F /* WKZombie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = WKZombie.h; path = Framework/WKZombie.h; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
BF2B33921D90759E004E6621 /* ContentFetcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = ContentFetcher.swift; path = Sources/WKZombie/ContentFetcher.swift; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
BF2B33921D90759E004E6621 /* ContentFetcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = ContentFetcher.swift; path = Sources/WKZombie/ContentFetcher.swift; sourceTree = SOURCE_ROOT; };
BF2B33931D90759E004E6621 /* Definitions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Definitions.swift; path = Sources/WKZombie/Definitions.swift; sourceTree = SOURCE_ROOT; };
BF2B33941D90759E004E6621 /* Error.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Error.swift; path = Sources/WKZombie/Error.swift; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
BF2B33951D90759E004E6621 /* Functions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Functions.swift; path = Sources/WKZombie/Functions.swift; sourceTree = SOURCE_ROOT; };
@ -106,8 +106,8 @@
BF2B33A01D90759E004E6621 /* JSONPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = JSONPage.swift; path = Sources/WKZombie/JSONPage.swift; sourceTree = SOURCE_ROOT; };
BF2B33A11D90759E004E6621 /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Logger.swift; path = Sources/WKZombie/Logger.swift; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
BF2B33A21D90759E004E6621 /* Page.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Page.swift; path = Sources/WKZombie/Page.swift; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
BF2B33A31D90759E004E6621 /* Parser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Parser.swift; path = Sources/WKZombie/Parser.swift; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
BF2B33A41D90759E004E6621 /* Renderer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Renderer.swift; path = Sources/WKZombie/Renderer.swift; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
BF2B33A31D90759E004E6621 /* Parser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Parser.swift; path = Sources/WKZombie/Parser.swift; sourceTree = SOURCE_ROOT; };
BF2B33A41D90759E004E6621 /* Renderer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Renderer.swift; path = Sources/WKZombie/Renderer.swift; sourceTree = SOURCE_ROOT; };
BF2B33A51D90759E004E6621 /* RenderOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = RenderOperation.swift; path = Sources/WKZombie/RenderOperation.swift; sourceTree = SOURCE_ROOT; };
BF2B33A61D90759E004E6621 /* Snapshot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Snapshot.swift; path = Sources/WKZombie/Snapshot.swift; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
BF2B33A71D90759E004E6621 /* WKZombie.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = WKZombie.swift; path = Sources/WKZombie/WKZombie.swift; sourceTree = SOURCE_ROOT; };
@ -397,7 +397,7 @@
TargetAttributes = {
BF1F915E1CB6AF9300A58A7F = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 0800;
LastSwiftMigration = 0900;
ProvisioningStyle = Manual;
TestTargetID = BF455D9A1CEFBF99006D97D0;
};
@ -406,12 +406,12 @@
};
BF455D9A1CEFBF99006D97D0 = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 0800;
LastSwiftMigration = 0900;
ProvisioningStyle = Manual;
};
BFAECCAB1CB69C0200C87F3B = {
CreatedOnToolsVersion = 7.3;
LastSwiftMigration = 0800;
LastSwiftMigration = 0900;
};
};
};
@ -574,7 +574,8 @@
PRODUCT_BUNDLE_IDENTIFIER = de.mathiaskoehnke.WKZombieTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HostApplication.app/HostApplication";
};
name = Debug;
@ -590,7 +591,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = de.mathiaskoehnke.WKZombieTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HostApplication.app/HostApplication";
};
name = Release;
@ -659,7 +661,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = de.mathiaskoehnke.HostApplication;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = 1;
};
name = Debug;
@ -674,7 +677,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = de.mathiaskoehnke.HostApplication;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = 1;
};
name = Release;
@ -725,7 +729,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
IPHONEOS_DEPLOYMENT_TARGET = 9.1;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@ -777,7 +781,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
IPHONEOS_DEPLOYMENT_TARGET = 9.1;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
@ -813,7 +817,8 @@
SKIP_INSTALL = YES;
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@ -840,7 +845,8 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Release;
};