XPC steps to lauch 3rd party command line app

Hi,


I am writing (trying at least) a GUI for a 3rd party app that runs from the command line. Running the 3rd party app from the command line is not a problem and it is located under /Applications/.../someapp. This someapp takes a list of arguments and produces a text file with a result of a computation.


I tried different methods such as NSTask (now Process()) but that doesn't work from outside XCode. It seems that the only way now to call a 3rd party command line app is to use XPC. If there are other methods that work since Sierra came out, I'll be grateful to learn about that.


Could someone please give a to-the-point steps to implement the use of XPC in Swift...really hands on steps please.


There are plenty of XPC documentation out there but none gives me the needed details to get the above done.


Also, it is not important to me if my app is signed, sandboxed or not, but I am not planning on distributing it on the App store at this stage.


Thanks for your help.

Accepted Reply

No, my app isn't sandboxed and it is not signed.

It really should be signed, even if it’s just Developer ID signed. Having said that, the lack of signing is unlikely to be causing this issue.

As I stated, NSTask works fine as long as I am testing my app from within XCode, actually it works perfectly.

There’s a bunch of environment set up by Xcode that might affect this, including:

  • The current working directory — You have to make sure you’re using a full path.

  • Standard I/O (

    stdin
    ,
    stdout
    and
    stderr
    ) — Xcode sets these a pseudo terminal that it manages, whereas in a normal app run from the Finder they’re typically set to
    /dev/null
    .

There’s a bunch of things you can do to debug this:

  • Run the app from Finder and then attach to it using Xcode. This will separate the ‘run from Xcode’ and ‘has debugging attached’ cases, and allow you to debug in general.

  • Reproduce the problem with a small test app.

  • Reproduce the problem with a built-in tool, like

    echo
    .

I got the impression that I needed to use XPC from this thread …

That thread is all about sandboxing, which you are not.

Just in case it is of any relevance, the path to the 3rd party app that I am trying to execute using NSTask is not hardcoded, the user has to point to it …

OK. That would introduce complications if you were sandboxed but, as you’re not, this is irrelevant.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

NSTask (aka

Process
) should work just fine.

Do you have app sandboxing enabled? That introduces a bunch of complexities that it’s best to avoid when getting started with this sort of thing. I recommend you create a small non-sandboxes test app to try out NSTask.

ps You wrote:

It seems that the only way now to call a 3rd party command line app is to use XPC.

I’m not sure where you got that impression but you’re way off base here. NSTask is definitely the right place to start here.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi,


Thanks for answering. No, my app isn't sandboxed and it is not signed. As I stated, NSTask works fine as long as I am testing my app from within XCode, actually it works perfectly. But, when I try the target that XCode builds (or an archived app) outside XCode it is as if the task.launch() part is skipped; whatever is before is executed and whatever is after is executed but not the call to the 3rd party command line app! I even tried to run my app from within the Applications folder.


I got the impression that I needed to use XPC from this thread: https://forums.developer.apple.com/thread/28336


Just in case it is of any relevance, the path to the 3rd party app that I am trying to execute using NSTask is not hardcoded, the user has to point to it (using NSOpen) under settings in my app, the path is then stored in Userdefaults and retrieved every time the app is launched thereafter; this is ideal as many versions exist and each has its own path. I also tried to hardcode to path so the user doesn't need to do that in setting, I still get the same outcome as above.


Regards.

No, my app isn't sandboxed and it is not signed.

It really should be signed, even if it’s just Developer ID signed. Having said that, the lack of signing is unlikely to be causing this issue.

As I stated, NSTask works fine as long as I am testing my app from within XCode, actually it works perfectly.

There’s a bunch of environment set up by Xcode that might affect this, including:

  • The current working directory — You have to make sure you’re using a full path.

  • Standard I/O (

    stdin
    ,
    stdout
    and
    stderr
    ) — Xcode sets these a pseudo terminal that it manages, whereas in a normal app run from the Finder they’re typically set to
    /dev/null
    .

There’s a bunch of things you can do to debug this:

  • Run the app from Finder and then attach to it using Xcode. This will separate the ‘run from Xcode’ and ‘has debugging attached’ cases, and allow you to debug in general.

  • Reproduce the problem with a small test app.

  • Reproduce the problem with a built-in tool, like

    echo
    .

I got the impression that I needed to use XPC from this thread …

That thread is all about sandboxing, which you are not.

Just in case it is of any relevance, the path to the 3rd party app that I am trying to execute using NSTask is not hardcoded, the user has to point to it …

OK. That would introduce complications if you were sandboxed but, as you’re not, this is irrelevant.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks a bunch for your help.


Indeed, it was a current directory problem, I didn't use .currentDirectoryPath with NSTaks (Process), adding that fixed my problem. Also, app signing didn't create any problems, so I am signing it.


Cheers