The Adventures with NSTask & co. (Part 2)

After preparing the archived build, I was too optimistic about the outcome that was ahead of me.

When I have started writing @UpdatesXcode, I was thinking that I would somehow be able to pass through the review process and distribute the app via the Mac App Store.

However, even at the stage of notarization, I have discovered that the included binaries must also have attributes for Hardening the Runtime in order for the app bundle as a whole to be notarized.

I, however, still believe that if I would move the Wrapper class that is responsible for handling requests and responses between Cocoa and CLI into an XPC service, I would then be able to somehow notarize the app, and maybe even upload for the Mac App Store. (but I am pretty much sure that since xcodes utility parses the undocumented, unofficial API output of the, the app would never pass the review, especially considering @Josh Holtz w/ his experience trying to pass the review for his amazing @ConnectKitApp that uses the official App Store Connect API)

Submitting TSI 

The morning prior to the #iOSDevHappyHour, I realised that I can no longer facilitate brainstorming of this problem. So I have submitted a DTS (TSI) ticket through Submission is pretty much the same as when submitting a bug through a Feedback Assistant app.

The Actual Problem

Data exchange between CLI and Cocoa is, as aforementioned, performed via NSTask (Process). 
Basic definition is that an instance of Process has:

  1. input stream
  2. output stream
  3. error stream

Process is pretty much a wrapper around CLI and printf() -like functions. So, by the means of using Pipe instances, Cocoa receives the data which command line tool provides (say, by calling Swift.print()).

When debugging Process, it’s a common practice to set an instance of Pipe() and its property “fileHandlerForReading” to Process().standardOutput, because Xcode will provide its own STDOUT that is an actual Terminal console (CMD+SHIFT+R) in the Xcode itself. 

After supplying Pipe() to Process(), everything seems to work in the Xcode when running the app.
However, as it appears, even in this case, Xcode debugger changes a way how STDOUT works, so that even though the Process uses FileHandle from the Pipe instance, the environment is still different than from when running the app in the real world.

And the readabilityHandler property of the FileHandle that is within that provided Pipe doesn’t get called. Period. 

I’ve spent about 11 hours in total on this issue prior to submitting TSI, and as a Sr. Software Developer, I for sure have “duck-ducked” enough. There was absolutely no hint on what was actually happening.

Except that my gut feeling have suggested that I would be better off using some kind of a delimiter when printing statements from the xcodes utility (child process). But the documentation already states that Swift.print() uses a default terminator that is \n.

This was not too far away from the solution. If I were to read, say, the book about Darwin or UNIX programming that I have started reading back in 2017, I now would definitely have much more basis for developing that gut feeling into an actual idea of why this was not working.



2 thoughts on “The Adventures with NSTask & co. (Part 2)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s