SwiftUI 在点击时执行脚本并在视图 window 上 return 输出
SwiftUI execute script on click and return output on view window
我是 SwiftUI 的新手。我对 Python 和 Shell 脚本有中级知识。尝试制作一个基本上 运行 备份作业的应用程序,以将数据从我的 MacOS 复制到网络驱动器。我能够使用 AppleScript 早些时候集成 Python 脚本来实现这一点,但现在我正在尝试用一个有趣的视图实现相同的功能。
使用下面的代码,我正在尝试创建一个函数,该函数可以在从任何位置单击时调用 shell 脚本(更喜欢将脚本存储在应用程序中)(不幸的是,没有看到 Python 在 SwiftUI 中)和 return 视图上的实时输出 window。我正在编写的代码是针对 MacOS 而不是 iPhone 基本上。
谁能帮我指引正确的方向。
import SwiftUI
import Foundation
enum ViewState {
case DefaultView
case BackupTaskView
}
struct BackupView : View {
@State var showing : ViewState = .DefaultView
var body: some View {
HeaderView()
VStack {
if showing == .DefaultView {
DefaultView(showing:$showing)
}
if showing == .BackupTaskView {
BackupTaskView(showing:$showing)
}
}
.frame(width: 700, height: .infinity, alignment: .topLeading)
.padding(8)
Spacer()
FooterView()
}
}
private struct DefaultView: View {
@Binding var showing : ViewState
@State var navigated = false
@State var result : String = ""
var body: some View {
VStack {
Text(
"Hello, World!"
)
}
.frame(width: 700, height: .infinity, alignment: .topLeading)
.padding(8)
Spacer()
VStack {
Button(
action: { self.showing = .BackupTaskView }
)
{
Image("backup")
.resizable()
.frame(maxWidth: 180, maxHeight: 180)
}
.buttonStyle(PlainButtonStyle())
}
Spacer()
}
}
private struct BackupTaskView : View {
@Binding var showing : ViewState
@State var result : String = ""
@State var script = "/Users/samiron/Documents/Backup.sh"
@State var isRunning = false
var body: some View {
VStack {
Form {
Section {
Text("\(result)")
}
.onAppear{self.executeCommand()}
}
}
}
func executeCommand() -> (String?) {
let task = Process()
task.launchPath = "/bin/sh"
task.arguments = [ script ]
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let result = String(data: data, encoding: .utf8)
task.waitUntilExit()
return result
}
}
struct BackupView_Previews: PreviewProvider {
static var previews: some View {
BackupView()
}
}
我假设你想要一些东西,比如
Section {
Text("\(result)")
}
.onAppear{
self.result = "Executing..."
DispatchQueue.global(qos: .background).async {
let output = self.executeCommand() // << run in background
DispatchQueue.main.async {
self.result = output ?? "Failed" // << update UI on main
}
}
}
我是 SwiftUI 的新手。我对 Python 和 Shell 脚本有中级知识。尝试制作一个基本上 运行 备份作业的应用程序,以将数据从我的 MacOS 复制到网络驱动器。我能够使用 AppleScript 早些时候集成 Python 脚本来实现这一点,但现在我正在尝试用一个有趣的视图实现相同的功能。
使用下面的代码,我正在尝试创建一个函数,该函数可以在从任何位置单击时调用 shell 脚本(更喜欢将脚本存储在应用程序中)(不幸的是,没有看到 Python 在 SwiftUI 中)和 return 视图上的实时输出 window。我正在编写的代码是针对 MacOS 而不是 iPhone 基本上。
谁能帮我指引正确的方向。
import SwiftUI
import Foundation
enum ViewState {
case DefaultView
case BackupTaskView
}
struct BackupView : View {
@State var showing : ViewState = .DefaultView
var body: some View {
HeaderView()
VStack {
if showing == .DefaultView {
DefaultView(showing:$showing)
}
if showing == .BackupTaskView {
BackupTaskView(showing:$showing)
}
}
.frame(width: 700, height: .infinity, alignment: .topLeading)
.padding(8)
Spacer()
FooterView()
}
}
private struct DefaultView: View {
@Binding var showing : ViewState
@State var navigated = false
@State var result : String = ""
var body: some View {
VStack {
Text(
"Hello, World!"
)
}
.frame(width: 700, height: .infinity, alignment: .topLeading)
.padding(8)
Spacer()
VStack {
Button(
action: { self.showing = .BackupTaskView }
)
{
Image("backup")
.resizable()
.frame(maxWidth: 180, maxHeight: 180)
}
.buttonStyle(PlainButtonStyle())
}
Spacer()
}
}
private struct BackupTaskView : View {
@Binding var showing : ViewState
@State var result : String = ""
@State var script = "/Users/samiron/Documents/Backup.sh"
@State var isRunning = false
var body: some View {
VStack {
Form {
Section {
Text("\(result)")
}
.onAppear{self.executeCommand()}
}
}
}
func executeCommand() -> (String?) {
let task = Process()
task.launchPath = "/bin/sh"
task.arguments = [ script ]
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let result = String(data: data, encoding: .utf8)
task.waitUntilExit()
return result
}
}
struct BackupView_Previews: PreviewProvider {
static var previews: some View {
BackupView()
}
}
我假设你想要一些东西,比如
Section {
Text("\(result)")
}
.onAppear{
self.result = "Executing..."
DispatchQueue.global(qos: .background).async {
let output = self.executeCommand() // << run in background
DispatchQueue.main.async {
self.result = output ?? "Failed" // << update UI on main
}
}
}