Making Toast Again

A quote from a slightly younger me quoting an even younger me:

Depression is one of those rare problems best solved by doing as little as possible. It is for this reason that one who is depressed needs friends so desperately. Without desire, the task of daily life becomes an unbearable burden. Even the will to make toast, for example, has disappeared. But the only way to keep one’s mind distracted from the recovering void is to press-on through all the mundanity of life. The act of making toast takes on a self-salvific importance it never had before. It is imperative that I make this toast in order that I avoid the temptation to try to resurrect my desire to make toast. It is making toast as an end in itself, which, as anyone who has been through depression can tell you, is no small task.

Almost every important lesson in life I end up forgetting and rediscovering and forgetting again. I’m getting really good at making the same mistakes with precision.

|  9 Jun 2015




My Daily Habits Before and After the Apple Watch

TL;DR

Unless I’m an edge case, I think the Apple Watch is potentially a threat to businesses that depend on people filling idle time with their apps. Your mileage may vary.

Before the Apple Watch

After the Apple Watch

|  22 May 2015




Jared’s Code Signing Tips: Apple Watch Edition

After much struggling and some good advice, I’ve finally managed to get an Apple Watch App/Extension running on an actual watch. Here’s some follow-up to my previous post on code signing woes.

How to Provision an Apple Watch

An Apple Watch has to be provisioned for development use in much the same way as an iPhone or iPad.

  1. Pair your watch with your iPhone.

  2. With both devices powered on and the watch nearby, connect your iPhone to your development Mac and launch Xcode.

  3. Open the Devices window.

  4. Copy the device identifier for the watch.

  5. At the iOS Developer Center, add the watch to your development device list the same way you would add an iPhone or iPad.

  6. Update any existing (relevant) provisioning profiles to include the new watch. Download them and double-click them to install them via Xcode. To be safe, consider deleting the older versions of the affected profiles from Xcode and from your phone prior to double-clicking the new profiles. See below for how to do this.

How to Install a Watch App/Extension on an Actual Damn Watch

When your watch app Xcode project is properly configured it will have a minimum of three targets:

All three targets require the following:

If your app also has other extensions (like a Today widget, etc.), or if it uses a custom framework to share code between all targets — you may have many more targets. Other extensions require the same things as the watch app/extension above. A framework only requires a code signing identity.

Create app IDs and provisioning profiles at the iOS Developer Portal. Download and install the new profiles as described above.

Your app IDs will look something like this:

com.company.App-Name
com.company.App-Name.todaywidget
com.company.App-Name.watchkitapp
com.company.App-Name.watchkitextension

After having created and installed all the new profiles for all your required targets, specify the code signing identities and provisioning profiles using the same methods I recommended in my previous code signing post. Make sure that you have entered all the app IDs in their respective Info.plist entries, and that the paths to the Info.plists in the Xcode build settings for each target are correct.1

After all this is complete, consider relaunching Xcode, your iPhone, and your Apple Watch to eliminate bugs related to caching issues (this happens a lot with Xcode in particular).

Debugging Tips

If you’re running out of ideas on what could be going wrong, try the following:

A Note About Entitlements

You are likely going to want to share application data between your host app and its extensions using a shared app group directory. This requires several things:

  1. Enable the “App Group” entitlement for all of your app IDs (not just the host app, but all extensions, too) on the developer portal. I’m not sure, but I think you might need to regenerate provisioning profiles after adding this entitlement.

  2. Update the Xcode “Capabilities” section for the host app and all extension targets to make sure that “App Groups” is enabled and the correct group name is checked.

  3. By this point, Xcode should have automatically created .entitlements files for all your targets, and included them in the appropriate line in the Code Signing section of the build settings for each target. Take heed: do not specify an entitlement for a watch app, only for a watch extension.

  4. Inspect your entitlements files to make sure they have the correct app group name(s). Also make sure that the paths to the entitlements files are correct in the build settings for each target. These can get out-of-sync with the actual path to the files on disk.

How to Delete Provisioning Profiles from Your Development Mac

Prior to getting started, I suggest doing some provisioning profile house cleaning. This process is so hard to discover that I’ve changed my mind about suggesting you just Google the answer. Here’s how to delete old profiles from your development Mac using Xcode 6:

  1. Go to Preferences > Accounts. Select an Apple ID on the left, and double click the team name in the list of teams on the right (there may be only one team).

  2. A modal sheet appears with a list of provisioning profiles installed on your Mac. Right click a profile and choose “Show in Finder.”

  3. From the Finder, you can trash the profile as you would any other file. Bear in mind that the containing folder contains provisioning profiles from all of your developer accounts on your Mac, so take care not to trash the wrong profile.

  4. Repeat as needed.

How to Delete Provisioning Profiles from Your iOS Device

It used to be possible to view and delete provisioning profiles directly on an iOS device via the Settings.app. I’m not sure which version of iOS changed this behavior, but now you’ll have to use Xcode in order to remove a profile.

  1. Open the Devices window in Xcode.

  2. Connect your iOS device and right click it in the devices list when it appears.

  3. Choose “Show Provisioning Profiles”

  4. Select a provisioning profile you want to delete, and then click the minus button.

  5. Repeat one-at-a-damn-time as needed. Sigh. After a while your device may have many provisioning profiles, including numerous duplicates of the same profile as it gets updated with additional devices and certs, so this click-and-delete process can be tedious.


  1. They must be manually updated if you reorganize the hierarchy of your project files on disk — something you might do when adding a bunch of new targets to your project. 

|  25 Apr 2015




Follow These Guidelines and Never Struggle with Xcode Code Signing Again

For at least a year now I haven’t had any struggles with Xcode’s code signing, thanks to the following habits. Some of them seem like overkill, and all of them are a lot “harder” than using the built-in “support” in Xcode, but — fuck all that noise. Do these things1 and get back to work:

  1. Never use Xcode’s built-in code signing helpers. Especially avoid any button that says Fix Issue. It fills your Developer portal with dozens of worthless “iOS Team Provisioning Profile Blah…” profiles and leads you towards Provisioning Profile Rot.

  2. Never use wildcard app identifiers. These are especially problematic when you belong to multiple teams, each with multiple wildcard app identifiers. Take the extra few seconds it takes to log into the developer portal on the web and create an app-specific bundle ID for every app, even proofs-of-concept. By avoiding wildcard app identifiers you eliminate an entire vector of shit on the path to code signing hell. If you have any existing wildcard profiles, delete them all immediately. Modern versions of Xcode make this much harder to do than it used to be. Let me Google that for you. If you really need a wildcard app identifier, just create an identifer that is literally com.company.Wildcard (or com.company.RadarSample, etc.) and re-use it as needed.

  3. Use build configs and shared schemes. Make life easier on yourself and check the “Shared” box in the “Manage Schemes…” window next to at least two schemes. Have one for development and one for App Store releases at the very least. Consider adding a third for beta builds if necessary. Select the appropriate build config in the editing window for each scheme. If you use the default build configs provided by Xcode that’ll be Debug for your development scheme and Release for your release scheme.

  4. Use explicit code-signing identities, and automatic profile selection. Since you’re now using shared schemes linked to specific build configs, you can make your Xcode project settings even more helpful. In the Code Signing Identity and Provisioning Profile sections for your project settings, specify explicit signing identities for any build configs that require distribution certificates (Ad Hoc, Enterprise, or App Store distributions). You can also try the automatic iOS Distribution setting if you’re lazy, but I’m on too many teams and don’t trust Xcode to do the right thing. I do recommend using the iOS Developer automatic setting for your Debug build configs, since this scales better when working with other developers. I have found that by using the above settings for signing identities, I can use the Automatic provisioning profile setting for all build configs without hiccups.

  5. Repeat your project-level settings at the target level. Another common problem is when project-level settings for code signing and profile selection don’t match the target-level settings. Unless you think you’ll never make this mistake (I used to think I could handle this. Now I know better.), manually set the code signing and provisioning profile settings at both project and target levels. Periodically check them to make sure they didn’t get out-of-sync.

  6. Delete expired certificates from Keychain Access. Keychain Access makes this pretty easy to do. Most certificates (Ad Hoc, APN, and App Store) expire after 365 days. Some Enterprise certificates may last up to three years. Create calendar alerts the same day you create new distribution and APN certificates, to remind yourself to get them updated and ready to go ahead of time, before they expire and your APN server starts flaring up with signing errors.

  7. Make sure you have all the certificates you need in Keychain Access. You will need at least two certificates for each team to which you belong: 1) A developer certificate that gives you permission to install apps on your own devices. 2) A distribution certificate that allows you to sign Ad Hoc and App Store builds. You might also need two additional certificates for push notifications (one for development and one for production builds). Developer and Distribution certificates apply to all apps on your team. APN certificates are specific to each application. Expand the carets to ensure that you also have the private keys for all these certificates. Store your certificate exports someplace that is both secure and convenient. Everyone on your team should be able to ship to the App Store in case all your senior engineers get serial-crushed by some huge friggin guy.

  8. Relaunch Xcode whenever you install new profiles or certificates. Cached expired certificates are particularly prone to caching errors.


Update 1: I’ve posted a follow-up article with code sigining tips for Apple Watch apps. April 25, 2015 — JTS.

Update 2: If you use CocoaPods, you’ll need this post-install script to make sure all your dependency frameworks are using the correct code-signing identities for the current scheme/config. My script assumes that you are using a distribution identity for configs named Beta and/or Release.


  1. Caveat: I only stand by this advice for iOS projects. I’ve no idea what kind of cowboy antics you’d have to do when shipping OS X binaries for both Mac App Store and direct sales distribution. 

|  14 Apr 2015




Apple Watch Try-On, Unsorted Thoughts

|  14 Apr 2015