đ Insidious Bugs #1: Today Extensions
This app could not be installed at this time.
Today Lickability is relaunching Insidious Bugs on our blog. 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.
The Bug
In this first entry, we conquer an instance of Xcodeâs friendly âThis app could not be installed at this timeâ message. We encountered this when attempting to run our project that includes a Today Extension, or widget, in the iOS Simulator.
The Solution
Would you believe that all it took to solve this issue was this seemingly useless file? Well, that and many, many hours of failed attempts.
How We Got Here
âThis app could not be installed at this timeâ doesnât give us a lot to work with, but letâs explore the somewhat unique setup that got us here.
We recently added Today Extensions to multiple projects, which all share the same layout. We tend to keep things DRY (donât repeat yourself), so we made our approach generic and reusable across multiple projects via a shared framework. In our framework, the Today Extension displays an arbitrary number of cells that have a thumbnail image and two labels. The framework doesnât care what type of content is to be displayed, whether itâs social media posts, news, reminders, etc.âit simply formats and displays the data written to the shared container by the host app in the exact same way. Hereâs an example:
Hooray! This will save us time and tedious boilerplate as we add our Today Extensions to our projects. We simply need to add the framework and associate the view controller in MainâInterface.storyboard
(part of the Today Extensionâs target) with the one found in the framework. At least thatâs what we thought. Everything compiled just fine, but we couldnât debug our app. âThis app could not be installed at this time.â đ¤ Since Xcodeâs message didnât point us in any particular direction on how to resolve the bug, we searched log files for anything that was amiss. Every time weâd attempt to build and run, a message similar to the following was printed to mobile\_installation.log.0
within the simulatorâs logs folder:
This error was more descriptive, but still didnât lead us to a solution. âWhy wouldnât the app extension exist on disk after a build succeeded?â we asked, before making dozens of trial and error attempts across several hours to no avail.
Eventually, we found that moving the view controller back to the Today Extension target would resolve the issue, but we werenât satisfied with duplicating that file across multiple projects. In a stroke of genius (read: luck) we asked each other, âWait⌠is it the fact that the view controller needs to be a part of the extension target, or is it just that we linked something to the target that made the difference?â After all, our âCompile Sourcesâ build phase required nothing, since by design, any executable code used by the widget would live in our shared framework.
So we just added something to our target to see if it made any difference. A single Swift file without any code.
We thought we had it. But at least we could build and run now. On launch of the Today Extension target, Xcodeâs console would display the following:
It seemed as though despite the fact that we were selecting the appropriate view controller class from the appropriate framework within MainâInterface.storyboard
, our class was still nowhere to be found at run time. After much more trial and error, we added a bit more code to FixâEmptyâTarget.swift
. We wanted to make sure everything was properly linked. We imported our shared framework into the file to see if it built (it did) and wrote some test code to see if we could actually make reference to the view controller class (we could). đ§ âHow come we can reference this view controller from a different framework in code, but not in a storyboard?â we pondered. We tried running this, just to see if anything more helpful would print to the console with our reference to the disappearing view controller in code, andâŚ
Michael: That⌠did it?
Andrew: Itâs time to relaunch Insidious Bugs.
Simply referencing our view controller in code and adding an otherwise useless file to our target solved this mysterious series of problems, and now we finally have our Today Extension framework. The full, documented version of FixâEmptyâTarget.swift
looks like the following:
Bananas, right? We sincerely hope you donât encounter an issue like this in your travels. And if you do, we hope this post helped you get back up and running quickly!
Radars
Here are the bugs weâve filed for Apple about these issues:
- Today Extension with no linked files fails to install in the simulator (39237943, closed as intended behavior)
- Follow-up: Difficult to understand error message with today extension that has no linked files (39974757)
- View controller referenced only from a storyboard not found at runtime (39238390, Closed as duplicate of 4691676)