【问题标题】:SwiftUI execute script on click and return output on view windowSwiftUI 在单击时执行脚本并在视图窗口上返回输出
【发布时间】:2022-01-19 05:51:06
【问题描述】:

我是 SwiftUI 的新手。我对 Python 和 Shell 脚本有中级知识。试图制作一个基本上运行备份作业的应用程序,将数据从我的 MacOS 复制到网络驱动器。我之前能够使用 AppleScript 集成 Python 脚本来实现这一点,但现在我正尝试用一个有趣的视图来实现相同的功能。

使用下面的代码,我正在尝试创建一个函数,该函数可以从任何位置(不幸的是在 SwiftUI 中没有看到 Python 的任何本机解决方案)单击时调用 shell 脚本(最好将脚本存储在应用程序中)并返回实时输出在视图窗口上。我正在编写的代码基本上是针对 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()
    }
}

【问题讨论】:

    标签: xcode macos swiftui


    【解决方案1】:

    我假设你想要一些东西,比如

    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
         }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 2018-11-11
      • 2021-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-14
      相关资源
      最近更新 更多