Skip to content

Instantly share code, notes, and snippets.

@tearfulDalvik
Last active July 16, 2024 12:00
Show Gist options
  • Save tearfulDalvik/e656177d3df7521cd61dffdc24ef3ec3 to your computer and use it in GitHub Desktop.
Save tearfulDalvik/e656177d3df7521cd61dffdc24ef3ec3 to your computer and use it in GitHub Desktop.
Chrome Native Messaging in Swift 5
// MARK: Chrome Part
func getInt(_ bytes: [UInt]) -> UInt {
let lt = (bytes[3] << 24) & 0xff000000
let ls = (bytes[2] << 16) & 0x00ff0000
let lf = (bytes[1] << 8) & 0x0000ff00
let lz = (bytes[0] << 0) & 0x000000ff
return lt | ls | lf | lz
}
func getIntBytes(for length: Int) -> [UInt8] {
var bytes = [UInt8](repeating: 0, count: 4)
bytes[0] = UInt8((length & 0xFF));
bytes[1] = UInt8(((length >> 8) & 0xFF));
bytes[2] = UInt8(((length >> 16) & 0xFF));
bytes[3] = UInt8(((length >> 24) & 0xFF));
return bytes
}
func chromeRead() -> String? {
let stdIn = FileHandle.standardInput
var bytes = [UInt](repeating: 0, count: 4)
guard read(stdIn.fileDescriptor, &bytes, 4) != 0 else {
return nil
}
let len = getInt(bytes)
return String(data: stdIn.readData(ofLength: Int(len)), encoding: .utf8)
}
func chromeWrite(_ txt: String) {
let stdOut = FileHandle.standardOutput
let len = getIntBytes(for: txt.utf8.count)
stdOut.write(Data(bytes: len, count: 4))
stdOut.write(txt.data(using: .utf8)!)
}
func chromeLoop() {
while let req = chromeRead() {
// ... Your stuff
}
}
if CommandLine.argc == 2 && CommandLine.arguments[1] == "chrome-extension://...." {
chromeLoop()
}
@iwan-ua
Copy link

iwan-ua commented Jul 16, 2024

This doesn't work for receiving messages longer than 255 symbols
To make it work you probably need to change var bytes = [UInt](repeating: 0, count: 4) to var bytes = [UInt8](repeating: 0, count: 4)

I went a different way and simplified this to:

private func writeMessage(string: String) {
    let stdOut = FileHandle.standardOutput

    var messageLength = UInt32(string.utf8.count)
    stdOut.write(Data(bytes: &messageLength, count: 4))
    stdOut.write(string.toUTF8Data())
}

private func readMessage() -> Data? {
    let stdIn = FileHandle.standardInput
    var messageLength: UInt32 = 0
    guard read(stdIn.fileDescriptor, &messageLength, 4) != 0 else {
        return nil
    }

    return stdIn.readData(ofLength: Int(messageLength))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment