summaryrefslogtreecommitdiff
path: root/extension/safari/TabFS/TabFS Extension/FSProcessManager.swift
blob: d17d9346a00ce83e351688ca1a1ff83f031a008a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//
//  FSProcessManager.swift
//  TabFS
//
//  Created by Omar Rizwan on 1/31/21.
//

import Foundation

import SafariServices.SFSafariApplication

let extensionBundleIdentifier = "com.rsnous.TabFS-Extension"

class FSProcessManager {
    static let shared = FSProcessManager()
    
    // FIXME: should accept XPC connection to extension
    // so it can get replies (??)
    
    var fs: Process!
    var fsInput: FileHandle!
    var fsOutput: FileHandle!
    
    func start() {
        fs = Process()
        fs.executableURL = URL(fileURLWithPath: "/Users/osnr/Code/tabfs/fs/tabfs")
        fs.arguments = []
        
        let inputPipe = Pipe(), outputPipe = Pipe()
        fs.standardInput = inputPipe
        fs.standardOutput = outputPipe
        
        try! fs.run()
        
        fsInput = inputPipe.fileHandleForWriting
        fsOutput = outputPipe.fileHandleForReading
//        
//        SFSafariApplication.dispatchMessage(
//            withName: "ToSafari",
//            toExtensionWithIdentifier: extensionBundleIdentifier,
//            userInfo: [:]
//        ) { error in
//            debugPrint("Message attempted. Error info: \(String.init(describing: error))")
//        }
        
        DispatchQueue.global(qos: .background).async {
            while true {
                let req = self.awaitRequest()
                
                SFSafariApplication.dispatchMessage(
                    withName: "ToSafari",
                    toExtensionWithIdentifier: extensionBundleIdentifier,
                    userInfo: req
                ) { error in
                    debugPrint("Message attempted. Error info: \(String.init(describing: error))")
                }
            }
        }
    }
    
    func awaitRequest() -> [String: Any] {
        let length = fsOutput.readData(ofLength: 4).withUnsafeBytes {
            $0.load(as: UInt32.self)
        }
        let data = fsOutput.readData(ofLength: Int(length))
        return try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
    }
    
    func respond(_ resp: [AnyHashable: Any]) {
        try! fsInput.write(JSONSerialization.data(withJSONObject: resp, options: []))
    }
}