
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
wk-postmessenger
Advanced tools
Create a synced channel to send message between a webview and an iOS application.
WKPostMessenger creates a synced channel via postMessage to facilitate communication between a Swift and JavaScript.
It's kind of like Postmate, except between webview and the iOS application where it live, not between two windows.
Messages passed back and forth contain an action (analogous to a function call) and data (an optional object with a bunch of data.). These messages also send an ID that is used as a token to keep track of multiple messages and their responses.
Swift provides evaluateJavaScript and addScriptMessageHandler for communication to and from JS in a webview, but these commands do not inherently verify that messages are received by the other side.
This library defines a common format for messages sent back and forth and allows for asynchronous return values (ie. Promises).
There isn't a corresponding Swift library for this (...yet?), but here's a rough outline of how to get it working.
Add a script message handler.
class WKPostMessageScriptMessageHandler: NSObject, WKScriptMessageHandler {
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage!) {
if message.name == "wkPostMessage" {
let payload = // decoded message.body
switch action {
case .__WK_HANDSHAKE__:
// Handshake data contains global JS function for sending messages
self.wkPostMessage = // payload.data to a string
// Acknowledge the handshake
let messageID = "\"\(payload.id)\"" // needs to be unique and escaped for JS
webview?.evaluateJavaScript("\(payload.callback)(\(messageID))", completionHandler: nil)
case .__WK_CALLBACK__:
// payload.id contains the ID of the message originally sent from Swift
// payload.data contains anything returned by the callback, which can be of any type
case .yourAction:
// payload.data contains anything returned by the callback, which can be of any type
let messageID = "\"\(payload.id)\"" // needs to be unique and escaped for JS
let jsonStringResult = // whatever you want, encoded for JS
let callbackJs = "\(payload.callback)(\(messageID), \(jsonStringResult));"
webview?.evaluateJavaScript(callbackJs, completionHandler: nil)
}
}
}
}
let contentController = WKUserContentController()
let handler = WKPostMessageScriptMessageHandler()
contentController.addScriptMessageHandler(handler, name: "wkPostMessage")
if let wkPostMessage = self.wkPostMessage {
// needs to be unique and escaped for JS
let messageID = "\"\(NSUUID().UUIDString)\""
let messageAction = "\"resetForm\""
let messageDataJsonString = // whatever you want, encoded for JS
let messageJs = "\(wkPostMessage)(\(messageID), \(messageAction), \(messageDataJsonString));"
webview?.evaluateJavaScript(messageJs, completionHandler: nil)
// the __WK_CALLBACK__ you receive with messageID returned as the message ID
// is the response from JavaScript!
}
payload.data. This is the trickiest part, because JS is loosey-goosey with types. Ideally, you want to be able to handle anything gracefully on the decoding side, even if you're expecting data in a specific format.Install this library.
npm install --save wk-postmessenger
Depending on your use case, grabbing the minified build might be more convenient. Follow your heart.
Build the page that you want to use in your webview and create a WKPostMessenger instance that defines message handling behavior.
import WKPostMessenger from 'wk-postmessenger';
const postMessenger = new WKPostMessenger({
handleMessage(action, data) {
// Your code to handle messages from the iOS app
},
});
A handshake postMessage sent from the webview to the application establishes the channel. This message uses a special __WK_HANDSHAKE__ action and data containing a string indicating the global function in the webview that accept messages from the iOS side.
Call sendMessage with an action name and optional data.
postMessenger.sendMessage('doSomethingInApp', {
quickly: 'Sure, I guess.',
})
.then((results) => {
// Resolves when the app sends a response acknowledging that the message
// was received and processed. Note that it doesn't necessarily have to
// return any data, but it can!
console.log('It did something!', results);
})
.catch(() => {
// If iOS doesn't acknowledge the message within the timeout, the Promise
// automatically rejects.
});
sendMessage also takes a third parameter for a custom timeout, which might come in handy if the application has to do an asynchronous operation that takes longer than the default timeout.
The handleMessage option allows you to define the behavior for messages from the iOS app. The return value is sent back to iOS.
const postMessenger = new WKPostMessenger({
handleMessage(action, data) {
switch (action) {
case 'getDogProperties':
if (data.name === 'Clifford') {
return { color: 'red', size: 'big' };
}
return { color: 'furry', size: 'dog-sized' };
default:
// Unrecognized message?
break;
}
},
});
The return value can also be a Promise, in which case the response will be sent to iOS when it resolves.
const postMessenger = new WKPostMessenger({
handleMessage(action, data) {
switch (action) {
case 'doAsyncThing':
return new Promise((resolve) => {
setTimeout(() => resolve('at long last!'), 9000);
});
default:
break;
}
},
});
FAQs
Create a synced channel to send message between a webview and an iOS application.
The npm package wk-postmessenger receives a total of 6 weekly downloads. As such, wk-postmessenger popularity was classified as not popular.
We found that wk-postmessenger demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.