Proof-of-concept `WKWebview.evaluateJavaScript(...)` replacement for WebSocket-based Javascript execution.

Overview

Sidewalk

Proof-of-concept WKWebview.evaluateJavaScript(...) replacement for WebSocket-based Javascript execution.

Goals

Notes

  • The project is experimental and full of TODOs !
  • Use it for your own risk, test it carefully !
  • To send through big amount of data, you need to use sidewalkJavaScript(data: Data, ...) method and handle the data in Javascript by yourself. (customMessageHandler)
  • There is no HTTPS/WSS support yet. If you inject Sidewalk into a page with HTTPS base URL, the connection will fail due to mixed content error
  • There is no completionHandler implementation yet ---> not possible to access JS execution result
  • There is no bidirectional communication yet ---> you can only execute Javascript
  • To receive messages from Javascript, you still have to use WKScriptMessageHandler

TODOs

  • add HTTPS/WSS support
  • add bidirectional messaging
  • add completion handler for script evaluation results (async/await with message ID on top of bidirectional messaging)
  • add reconnection logic in case of exceptional socket close
  • here will be the collection of TODOs from the code

Sample project

This project highlights the problem with WKWebview.evaluateJavaScript(...) and shows how to overcome the issue with Sidewalk. https://github.com/Danesz/SidewalkExample.git

How to use

  1. Install the Swift package
...
dependencies: [
    .package(url: "https://github.com/Danesz/Sidewalk.git", from: "0.0.1"),
],
...
  1. A) Attach it to the webview before it loads the page
import Sidewalk
...

Sidewalk.shared().attachToWebView(webview, when: .atDocumentStart)
webview.loadHTMLString(...)
  1. B) Or, inject the Javascript manually when needed on the already loaded page
import Sidewalk
...

Sidewalk.shared().injectNow(webview)
  1. Execute Javascript via Sidewalk on your WKWebview instance. (Sidewalk defines and extension on the WKWebview class)
import Sidewalk
...

//old way
//webview.evaluateJavaScript("console.log('I am here')")

//new way
webview.sidewalkJavaScript("console.log('I am here')")
  1. Tell to Sidewalk to forget your webview once you don't need the webview anymore. (to avoid memory leaks)
import Sidewalk
...

Sidewalk.shared().forgetWebview(webview)
  1. (optional) Use custom messaging between JS and Swift. In this example we send JSON messages to Javascript and inside the webview we can decide how to react based on the message type.

In Swift:

import Sidewalk
...

struct SidewalkSocketDirectBodyUpdateMessage: Codable {
    let type: String = "bodyUpdate"
    var content: String
}

class SidewalkSocketMessageHandlerJSON: SidewalkSocketMessageHandler {
        
    func didReceive(message: WebSocketMessage, onSocket socket: WebSocket) {
        fatalError("not supported")
    }
    
    func send(data: Data, onSocket socket: WebSocket) {
        fatalError("not supported")
    }
    
    func send(text: String, onSocket socket: WebSocket) {
        do {
            let data = try JSONEncoder().encode(SidewalkSocketDirectBodyUpdateMessage(content: text))
            if let message = String(data: data, encoding: String.Encoding.utf8) {
                socket.send(text: message)
            }
        } catch let error {
            print("SidewalkSocketMessageHandlerJSON error", error.localizedDescription)
        }
    }
    
    func send(message: WebSocketMessage, onSocket socket: WebSocket) {
        fatalError("not supported")
    }

}

And receive it in Javascript:

Sidewalk.customMessageHandler = function(event){
    let parsed = JSON.parse(event.data);
    if (parsed.type === "bodyUpdate") {
        document.body.innerHTML = parsed.content;
    }
}

Contribution

Any contribution is welcome!

You might also like...
JSPatch bridge Objective-C and Javascript using the Objective-C runtime. You can call any Objective-C class and method in JavaScript by just including a small engine. JSPatch is generally used to hotfix iOS App.

JSPatch 中文介绍 | 文档 | JSPatch平台 请大家不要自行接入 JSPatch,统一接入 JSPatch 平台,让热修复在一个安全和可控的环境下使用。原因详见 这里 JSPatch bridges Objective-C and JavaScript using the Object

Simple Design for Swift bridge with Javascript. Also can get javascript console.log.
Simple Design for Swift bridge with Javascript. Also can get javascript console.log.

SDBridgeOC is here. If your h5 partner confused about how to deal with iOS and Android. This Demo maybe help. YouTube video is here. bilibili Video is

The concept won first place in the Design Concept Award contest Season 1 in 2021.
The concept won first place in the Design Concept Award contest Season 1 in 2021.

TallyCounter Developed by Vladyslav Fil as part of the You are launched "Design Concept Award" contest Season #1. Tally Counter Micro-Interaction demo

The concept took third place in the Design Concept Award contest Season 1 in 2021.
The concept took third place in the Design Concept Award contest Season 1 in 2021.

SpringAnimation Developed by Yurii Sameliuk as part of the You are launched "Design Concept Award" contest Season #1. SpringAnimation demo. Inspired b

The concept took second place in the Design Concept Award contest Season 1 in 2021.
The concept took second place in the Design Concept Award contest Season 1 in 2021.

SmileRate Developed by Alex Kryvodub as part of the You are launched "Design Concept Award" contest Season #1. SmileRate demo. Inspired by Duy Luong c

The concept took third place in the Design Concept Award contest Season 1 in 2021.
The concept took third place in the Design Concept Award contest Season 1 in 2021.

SpringAnimation Developed by Yurii Sameliuk as part of the You are launched "Design Concept Award" contest Season #1. SpringAnimation demo. Inspired b

The concept won first place in the Design Concept Award contest Season 1 in 2021.
The concept won first place in the Design Concept Award contest Season 1 in 2021.

TallyCounter Developed by Vladyslav Fil as part of the You are launched "Design Concept Award" contest Season #1. Tally Counter Micro-Interaction demo

The concept won first place in the Design Concept Award contest Season 2 in December 2021.
The concept won first place in the Design Concept Award contest Season 2 in December 2021.

SwiftUI-ChristmasGift Developed by Alex Kryvodub as part of the You are launched "Design Concept Award" contest Season #2. ChristmasGift demo. alex.mp

The concept took second place in the Design Concept Award contest Season 2 December 2021.
The concept took second place in the Design Concept Award contest Season 2 December 2021.

SwiftUI-UrlaunchedMerryChristmasCard Developed by Yurii Sameliuk as part of the You are launched "Design Concept Award" contest Season #2. MerryChrist

The concept took third place in the Design Concept Award contest Season 2 in December 2021.
The concept took third place in the Design Concept Award contest Season 2 in December 2021.

SwiftUI-UrlaunchedLaunchScreen Developed by Vladyslav Fil as part of the You are launched "Design Concept Award" contest Season #2. Animated Launch Sc

PillowTalk - An iOS & SwiftUI server monitor tool for linux based machines using remote proc file system with script execution.
PillowTalk - An iOS & SwiftUI server monitor tool for linux based machines using remote proc file system with script execution.

An iOS & SwiftUI server monitor tool for linux based machines using remote proc file system with script execution.

MobilePillowTalkLite - An iOS & SwiftUI server monitor tool for linux based machines using remote proc file system with script execution       MarkdownView is a WKWebView based UI element, and internally use bootstrap, highlight.js, markdown-it.
MarkdownView is a WKWebView based UI element, and internally use bootstrap, highlight.js, markdown-it.

MarkdownView is a WKWebView based UI element, and internally use bootstrap, highlight.js, markdown-it.

A replacement for as which runs in constant time instead of O(n) when the conformance is not satisfiedA replacement for as which runs in constant time instead of O(n) when the conformance is not satisfied

ZConform A replacement for as? which runs in constant time instead of O(n) when the conformance is not satisfied. How it works ZConform does a one-tim

Kommander is a Swift library to manage the task execution in different threads.
Kommander is a Swift library to manage the task execution in different threads.

A lightweight, pure-Swift library for manage the task execution in different threads. Through the definition a simple but powerful concept, Kommand.

Pretty GCD calls and easier code execution.

Threader Pretty GCD calls and easier code execution. Overview Threader makes GCD calls easy to read & write. It also provides a simple way to execute

Easy background refresh registration, scheduling, execution, and completion. BGTaskScheduler for the lazy.

EasyBackgroundRefresh Easy background refresh registration, scheduling, execution, and completion. BGTaskScheduler for the lazy. Usage For fast refres

⏲ A tiny package to measure code execution time. Only 20 lines of code.

Measure ⏲ A tiny package to measure code execution time. Measure.start("create-user") let user = User() Measure.finish("create-user") Console // ⏲ Mea

Erik is an headless browser based on WebKit. An headless browser allow to run functional tests, to access and manipulate webpages using javascript.
Erik is an headless browser based on WebKit. An headless browser allow to run functional tests, to access and manipulate webpages using javascript.

Erik Erik is a headless browser based on WebKit and HTML parser Kanna. An headless browser allow to run functional tests, to access and manipulate web

Owner
Daniel Dallos
Daniel Dallos
SwiftUI TextEdit View - A proof-of-concept text edit component in SwiftUI & CoreText.

A proof-of-concept text edit component in SwiftUI & CoreText. No UIKit, No AppKit, no UITextView/NSTextView/UITextField involved.

Marcin Krzyzanowski 80 Dec 1, 2022
A very basic proof-of-concept Swift HTTP server that does not require Foundation

Swift Server Introduction This is very rough and basic HTTP server written in Swift without using Foundation. This is partially based on the Swifter r

Cezary Wojcik 55 Apr 27, 2022
A network extension app to block a user input URI. Meant as a network extension filter proof of concept.

URIBlockNE A network extension app to block a user input URI. Meant as a network extension filter proof of concept. This is just a research effort to

Charles Edge 5 Oct 17, 2022
Proof concept of modularized app with SwiftPackages built over MVI + Combine + SwiftUI in a single repo

PKDex-iOS Proof concept of modularized app with SwiftPackages built over MVI + Combine + SwiftUI in a single repo Introduction This project is a proof

Miguel Angel Zapata 13 Nov 22, 2022
QR2Pass: a proof of concept for an alternative (passwordless) authentication system to a web server

QR2Pass This is a proof of concept for an alternative (passwordless) authenticat

null 4 Dec 9, 2022
A proof of concept of the VIPER architecture

This project contains a proof of concept of the VIPER architecture. For this we are going to make use of the public API tmdb, with which we will implement a search engine, a list and a view detail.

Luis Martínez Zarza 2 Feb 18, 2022
TCC ClickJacking - A proof of concept for a clickjacking attack on macOS

A proof of concept for a ClickJacking attack on macOS. Why? TCC (Transparency, Consent, and Control) restricts and control applicatio

BreakPoint Technologies 65 Nov 29, 2022
Proof of concept app for trying to integrate passkeys and WebAuthn into Vapor

Vapor Passkey Demo Proof of concept app for trying to integrate passkeys and WebAuthn into Vapor Usage Clone the project, then in Terminal run swift r

Tim Condon 70 Dec 20, 2022
A SwiftUI proof-of-concept, and some sleight-of-hand, which adds rain to a view's background

Atmos A SwiftUI proof-of-concept, and some sleight-of-hand, which adds rain to a view's background. "Ima use this in my app..." Introducing Metal to S

Nate de Jager 208 Jan 2, 2023
A proof-of-concept WebURL domain renderer, using a port of Chromium's IDN spoof-checking logic to protect against confusable domains

WebURLSpoofChecking A proof-of-concept WebURL.Domain renderer which uses a port of Chromium's IDN spoof-checking logic (Overview, Implementation) to p

Karl 3 Aug 6, 2022