How to run executable in macOS

Issue #176

Enable executable

1
chmod +x executable

Add executable file to target
Use Process with correct launchPad

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
73
74
75
import Foundation

protocol TaskDelegate: class {
func task(task: Task, didOutput string: String)
func taskDidComplete(task: Task)
}

class Task {

weak var delegate: TaskDelegate?
let process = Process()

func run(arguments: [String]) {
DispatchQueue.background.async {
let launchPath = Bundle.main.path(forResource: "executable", ofType: "")!
self.run(launchPath: launchPath, arguments: arguments)
}
}

func stop() {
DispatchQueue.background.async {
if self.process.isRunning {
self.process.terminate()
}
}
}

// MARK: - Helper

private func run(launchPath: String, arguments: [String]) {
let process = Process()
process.launchPath = launchPath
process.arguments = arguments

let stdOut = Pipe()
process.standardOutput = stdOut
let stdErr = Pipe()
process.standardError = stdErr

let handler = { [weak self] (file: FileHandle!) -> Void in
let data = file.availableData
guard let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue) else {
return
}

guard let strongSelf = self,
let string = output.components(separatedBy: "\n").first else {
return
}

DispatchQueue.main.async {
strongSelf.delegate?.task(task: strongSelf, didOutput: string)
}
}

stdErr.fileHandleForReading.readabilityHandler = handler
stdOut.fileHandleForReading.readabilityHandler = handler

process.terminationHandler = { [weak self] (task: Process?) -> () in
stdErr.fileHandleForReading.readabilityHandler = nil
stdOut.fileHandleForReading.readabilityHandler = nil

guard let strongSelf = self else {
return
}

DispatchQueue.main.async {
strongSelf.delegate?.taskDidComplete(task: strongSelf)
}
}

process.launch()
process.waitUntilExit()
}
}

Comments