🐞 Insidious Bugs #2
Wait for Executable to be Launched
Insidious Bugs is an occasional series in which we share stories of overcoming obscure issues in iOS development with the goal of saving you the time we lost, should you encounter the issues yourself.
When setting up a scheme to wait until the app is launched to attach the debugger, performing a “Build & Run” will build the app and prepare it to be launched, but will not deploy a new app bundle. Because of that, you won’t see bug fixes or the effects of other code changes you may have just made.
To make sure that any changes we make are deployed, we first need to set up the scheme to automatically launch the app, perform a “Build & Run” to deploy our changes, and then switch the scheme back to waiting for the app to launch to attach the debugger.
How We Got There
We came across this issue while expanding on the Today Extension built out in our first Insidious Bugs post. To recap, we had built a Today Extension that is given a set of tweets from its host application, and then displays those tweets in a table view. This has been working well, but we want to give the user a way to see more details about the tweet in the host application. Thus, we went about adding functionality to open a tweet when you tap on it in the Today Extension.
To achieve this, we came up with a URL scheme for our host application to support, along with a URL structure to allow deep linking to a specific tweet. Upon receiving the deep link, the host application would create a view controller to show the tweet and push it onto the navigation stack.
To test this functionality, we switched the “Launch” setting in the scheme to “Wait for executable to be launched,” built and ran the app, opened the widget, and then tapped on a tweet. The app launched, but the details on the tweet we tapped in the widget didn’t show up.
This was certainly not what we expected so we set a breakpoint at the start of our
[application(\_:open:options:)](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application) delegate method, and re-ran the app. Sure enough, our delegate method wasn’t being called. Wait, what?
This definitely didn’t seem right. The first thing to do was double check documentation and confirm that we implemented deep linking correctly. The docs confirmed that we had implemented the correct delegate method, and added the appropriate information to our Info.plist.
After consulting documentation, we tried reverting how the app launched when we did a build and run, switching back to having the app launch automatically. The app launched, we minimized it, went to our widget, and tapped a tweet.
Huzzah! Deep linking was successfully implemented. However, we were still unsure of why it didn’t work when we waited to attach the debugger until the app was launched. This required further investigation.
The first step was to switch back the launch setting. Then, we changed the background color of the tweet detail view controller (a low effort change to make, but one with a big impact that was easy to verify). We built and ran the app and tapped on a tweet in the widget. The app deep linked into the detail view controller and, as we expected, it did not have the new background color.
This seemed to confirm suspicions that if we had the “Wait for executable to be launched” option selected, while Xcode would build the app, it would not actually deploy the newly built app. To confirm our hunch, there was one last thing we could do: we could delete the app from the simulator. If our suspicions were true, then doing a build and run with “Wait for executable to be launched” should not install the app, which means we shouldn’t see its icon anywhere on the home screen.
We deleted the app from the simulator, built and ran, and took a look at the home screen. Lo and behold, the app was nowhere to be found. With this final bit of confirmation, we felt confident that our hypothesis was true.
We’ve filed a bug report with Apple to get this issue fixed: