                     } as @convention(block) () -> String, to: AnyObject.self),
                     "webview": unsafeBitCast({ [unowned self] (url) in
                         print("Client:", "open", url)
-                        self.delegate.wukongRequestOpenURL(url)
+                        self.delegate?.wukongRequestOpenURL(url)
                     } as @convention(block) (String) -> Void, to: AnyObject.self),
                     "reload": unsafeBitCast({ [unowned self] () in
                         DispatchQueue.main.async {

            context?.exception = exception
            if let exception = exception?.toString() {
                print("Client:", "exception", exception)
                self.delegate.wukongDidThrowException(exception)
            }
        }
        context.evaluateScript(script)

    private func setupContext(_ version: String?, _ script: String?) {
        guard let script = script else {
            print("Client:", "failed", version ?? "n/a")
            delegate?.wukongDidFailLoadScript()
            return
        }
        print("Client:", "loaded", version ?? "n/a")
        delegate?.wukongDidLoadScript()
        cleanups.forEach { $0() }
        cleanups.removeAll()
        values.removeAll()
