1

I am running a binary file using a swift process() in my DataModel class. The user can see the process running from the ViewTasks() struct. How can I give the user the ability to cancel (terminate) the process?

Here is what I have tried:

DataModel class:

class DataModel : ObservableObject {
    
    @Published var task = Process()

    func RunTask() {
         // add arguments to task here
         do {
         task.arguments = [args]
         try task.run()
         } catch {}
    }

Here is the ViewTask() class:

struct ViewTask: View {
    
    @ObservedObject var datamodel: DataModel
    
    var body: some View {
          ///if user presses a cancel button, cancel the task running
          datamodel.task.terminate()
    }

This doesn't work because the task can't find the arguments. But when I don't make task an @Published variable, and it only exists locally in that Do loop, it works fine.
Maybe I need to declare/initialize it differently in the datamodel?

Thanks

  • What do you mean by `as the task isn't able to run`? you are terminating task – Nirav D Sep 21 '22 at 02:42
  • I edited for clarification. Basically the task itself stops finding the "arguments" once I try and make it a @Published variable. – perchlorious Sep 21 '22 at 02:53
  • one more question you have declared the task as `@Published` property, what kind of changes are you listening to SwiftUI View for this task property? – Nirav D Sep 21 '22 at 04:17

1 Answers1

0

Ok I figured out how to have a process (on background or main thread) visible through an observable object.

class DataModel : ObservableObject {
    
    @Published var task = Process()

    func RunTask() {
         // add arguments to task here
         do {
             let temptask = Process()
             temptask.arguments = [args]
             // set observable object to this process
             self.task = temptask
             try task.run()
         } catch {}
    }

This will allow any other view to call datamodel.task.terminate() and it works just fine. If the process is in a background thread, simply use DispatchQueue.main.async{self.task = temptask} to set the observable task as the locally made process.

  • Suggestion, instead of making `task` as published property, you can add some state property with an enum to manage state of your task – Nirav D Sep 22 '22 at 06:21