首页 > 解决方案 > 如何像用户在可可应用程序中使用终端一样运行脚本?

问题描述

我是 macOS 开发的新手。

我正在尝试使用 bash 脚本快速创建一个简单的 macos 应用程序来检查用户是否安装了 Tor。

以下代码是我的视图控制器:

import Cocoa

class ViewController: NSViewController {

    @IBOutlet var label: NSTextField!
    @IBOutlet var spinner: NSProgressIndicator!

    dynamic var isRunning = false
    var outputPipe:Pipe!
    var buildTask:Process!


    override func viewDidLoad() {
        super.viewDidLoad()

        checkIfTorIsInstalled()

    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    func checkIfTorIsInstalled() {

        spinner.startAnimation(self)
        runScript()

    }

    func runScript() {

        isRunning = true
        let taskQueue = DispatchQueue.global(qos: DispatchQoS.QoSClass.background)

        taskQueue.async {

            //1.
            guard let path = Bundle.main.path(forResource: "CheckForTor", ofType: "command") else {
                print("Unable to locate CheckForTor.command")
                return
            }

            //2.
            self.buildTask = Process()
            self.buildTask.launchPath = path

            //3.
            self.buildTask.terminationHandler = {

                task in
                DispatchQueue.main.async(execute: {
                    self.spinner.alphaValue = 0
                    self.spinner.stopAnimation(self)
                    self.isRunning = false
                })

            }

            self.captureStandardOutputAndRouteToTextView(self.buildTask)

            //4.
            self.buildTask.launch()

            //5.
            self.buildTask.waitUntilExit()

        }

    }

    func captureStandardOutputAndRouteToTextView(_ task:Process) {

        //1.
        outputPipe = Pipe()
        task.standardOutput = outputPipe
        task.standardError = outputPipe

        //2.
        outputPipe.fileHandleForReading.waitForDataInBackgroundAndNotify()

        //3.
        NotificationCenter.default.addObserver(forName: NSNotification.Name.NSFileHandleDataAvailable, object: outputPipe.fileHandleForReading, queue: nil) {
            notification in

            //4.
            let output = self.outputPipe.fileHandleForReading.availableData
            let outputString = String(data: output, encoding: String.Encoding.utf8) ?? ""

            //5.
            DispatchQueue.main.async(execute: {
                print("outputString = \(outputString)")
            })

            //6.
            self.outputPipe.fileHandleForReading.waitForDataInBackgroundAndNotify()

        }

    }

}

然后我的主包中有一个脚本,如下所示:

#!/bin/sh

#  CheckForTor.command
#  FullyNoded
#
#  Created by Peter on 03/10/19.
#  Copyright © 2019 Peter. All rights reserved.

tor --version

运行应用程序返回以下错误:

/Users/peter/Library/Developer/Xcode/DerivedData/FullyNoded-auhfxlayowyknmdyqlwszzkrnevb/Build/Products/Debug/FullyNoded.app/Contents/Resources/CheckForTor.command: line 9: tor: command not found

然而,当我打开终端并运行时,tor --version我得到了有效的响应。如何在 macos swift 应用程序中以编程方式运行脚本并获得与直接在我的 mac 上使用终端相同的功能?

标签: swiftxcodebashmacos

解决方案


解决方案是单击您的项目,然后在 XCode 中单击您的项目目标,然后在“功能”中关闭“应用程序沙箱”


推荐阅读