首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是最低可行的GUI命令行Swift脚本?

什么是最低可行的GUI命令行Swift脚本?
EN

Stack Overflow用户
提问于 2019-11-15 07:44:22
回答 2查看 1K关注 0票数 4

我需要一个macOS上Swift脚本的小助手GUI。它只需要一个文本输入字段和一个OK按钮。

我不想只为了这个小弹出框而走整个臃肿的Xcode路线。然而,苹果的文档失败了,因为键盘输入没有被我的NSWindow捕获。帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-11-18 00:48:03

不,多亏了苹果的文档,我终于从一个接受键盘输入的命令行Swift应用程序中找到了一个简单的AppKit/Cocoa所需要的神奇咒语‍♂️。没有Xcode

这也需要接受WKWebViews中的文本输入。

代码语言:javascript
复制
// main.swift // Dylan Sharhon // Tested on Catalina, Nov 2019
import AppKit // import Cocoa if you also need Foundation functionality

let app = NSApplication.shared
app.setActivationPolicy(.regular) // Magic to accept keyboard input and be docked!

let window = NSWindow.init(
  contentRect: NSRect(x: 300, y: 300, width: 200, height: 85),
  styleMask:   [
    NSWindow.StyleMask.titled     // Magic needed to accept keyboard input
  ],
  backing:     NSWindow.BackingStoreType.buffered,
  defer:       false
)
window.makeKeyAndOrderFront(nil)  // Magic needed to display the window

// Text input field
let text = NSTextField.init(string: "")
text.frame = NSRect(x: 10, y: 45, width: 180, height: 25)
window.contentView!.addSubview(text)

// Button
class Target {
  @objc func onClick () {         // Magic @objc needed for the button action
    print(text.stringValue)       // Goes to stdout
    exit(0)
  }
}
let target = Target()
let button = NSButton.init(
  title:  "OK",
  target: target,
  action: #selector(Target.onClick)
)
button.frame = NSRect(x:50, y:10, width:100, height:30)
window.contentView!.addSubview(button)

app.run()

和我一样:,这是整个应用程序,您可以使用swift main.swift运行它,也可以用swiftc main.swift编译它,并将结果(仅40 KB)的可执行文件重命名为您想要在菜单中的任何内容。

票数 8
EN

Stack Overflow用户

发布于 2020-04-03 13:34:31

我写了一个小剧本,它能迅速地显示一扇窗户。目标是显示几个shell命令(brew update & brew upgrade & brew cleanup & brew doctor)的输出。如果您不每天执行这些命令,那么这些命令可能会花费大量的时间,我厌倦了不得不等待10分钟才能完成第2条命令。

我本可以简单地启动cron作业,或者用shell脚本使用launchd,但是我希望能够检查这些命令,特别是brew doctor的成功与否,以便知道是否需要执行一些操作来清理机器上的自制安装。

所以我需要一个窗口来显示这些命令的错误和标准输出,还有更多,我想要生成其中的二进制文件。

在Google和Github上搜索了一些之后,我找到了ShellOut -sh,它允许导入Github存储库(通过以标准化的方式),并在一个快速脚本中使用它并在需要时编译它;以及由同一个人编写的,它允许从一个快速脚本执行shell命令,并将命令的输出收集到一个Swift对象中。

基本上,它应该是一个在滚动视图中带有文本视图的小窗口,它显示了shell命令的输出,同时能够滚动它。

在这里,脚本:

代码语言:javascript
复制
#!/usr/bin/swift sh


import AppKit
import Foundation
// importing ShellOut from GitHub repository
// The magic of swift-sh happens
import ShellOut // @JohnSundell

// Declare the Application context
let app = NSApplication.shared

// Create the delegate class responsible for the window and crontrol creation
class AppDelegate: NSObject, NSApplicationDelegate {
    var str: String? = ""

    // Construct the window
    let theWindow = NSWindow(contentRect: NSMakeRect(200, 200, 400, 200),
                          styleMask: [.titled, .closable, .miniaturizable, .resizable],
                          backing: .buffered,
                          defer: false,
                          screen: nil)

    var output: String? = ""

    // What happens once application context launched
    func applicationDidFinishLaunching(_ notification: Notification) {

        var str = ""

        // The shell commands and the collect of output
        do {
            str =  try shellOut(to: "brew", arguments: ["update"] )
            output = output! + str
        } catch {
            let error1 = error as! ShellOutError
            //print(error1.message)
            output = output! + error1.message
        }

        do {
            str = try shellOut(to: "brew", arguments: ["upgrade"] )
            output = output! + "\n" + str
            //print("step 2")
        } catch {
            let error2 = error as! ShellOutError
            //print(error2.message)
            output = output! + "\n" + error2.message
        }

        do {
            str = try shellOut(to: "brew", arguments: ["cleanup"] )
            output = output! + "\n" + str
            //print("step 3")
        } catch {
            let error3 = error as! ShellOutError
            //print(error3.message)
            output = output! + "\n" + error3.message
        }

        do {
            str = try shellOut(to: "brew", arguments: ["doctor"] )
            output = output! + "\n" + str
             //print("step 4")
        } catch {
            let error4 = error as! ShellOutError
            //print(error4.message)
            output = output! + "\n" + error4.message
        }

        // Controls placement and content goes here
        // ScrollView...
        var theScrollview = NSScrollView(frame: theWindow.contentView!.bounds)
        var contentSize = theScrollview.contentSize
        theScrollview.borderType = .noBorder
        theScrollview.hasVerticalScroller = true
        theScrollview.hasHorizontalScroller = false
        theScrollview.autoresizingMask = NSView.AutoresizingMask(rawValue: NSView.AutoresizingMask.width.rawValue | NSView.AutoresizingMask.height.rawValue | NSView.AutoresizingMask.minYMargin.rawValue | NSView.AutoresizingMask.minYMargin.rawValue)

        // TextView...
        var theTextView = NSTextView(frame: NSMakeRect(0, 0, contentSize.width, contentSize.height))
        theTextView.minSize = NSMakeSize(0.0, contentSize.height)
        theTextView.maxSize = NSMakeSize(CGFloat.greatestFiniteMagnitude, CGFloat.greatestFiniteMagnitude)
        theTextView.isVerticallyResizable = true
        theTextView.isHorizontallyResizable = false
        theTextView.autoresizingMask = NSView.AutoresizingMask(rawValue: NSView.AutoresizingMask.width.rawValue | NSView.AutoresizingMask.height.rawValue | NSView.AutoresizingMask.minYMargin.rawValue | NSView.AutoresizingMask.minYMargin.rawValue)
        theTextView.textContainer?.containerSize = NSMakeSize(contentSize.width, CGFloat.greatestFiniteMagnitude)
        theTextView.backgroundColor = .white
        theTextView.textContainer?.widthTracksTextView = true
        theTextView.textStorage?.append(NSAttributedString(string: output!))

        theScrollview.documentView = theTextView

        theWindow.contentView = theScrollview
        theWindow.makeKeyAndOrderFront(nil)
        theWindow.makeFirstResponder(theTextView)
    }

    // What happens when we click the close button of the window
    func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
      return true;
    }
}

// Instantiation of the application delegate class
// and launching
let delegate = AppDelegate()
    app.delegate = delegate
    app.run()
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58872398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档