Thinking About Default iOS Apps

There's a report that came out this week from Bloomberg that says Apple is "considering" the idea of allowing users to pick third-party apps to be their default for things like email, music, and web browsing. This really does feel like a good thing for Apple to do, though I do laugh a bit at the "considering" word. If they are truly considering it then it's likely to miss iOS 14 which I imagine has been feature-locked for some time. The question is: what does setting a default app mean?

  • In Messages, tapping an http or https link would presumably take you to the browser you've set as default. This could be Safari, Chrome, or iCab.
  • Tapping a mailto link would open up your email app. There are plenty out there which could supplant the default Mail.app (which is what I use and personally find to be fine).
  • Asking Siri to play some music could launch Spotify without having to add "with Spotify" to the end of your query.

And there are many other possibilites here that I won't bother listing. As a user I think the time is definitely right for Apple to introduce a feature like this. But what about as a developer?

The big question that I have revolves around code that would normally put Safari in your app. The class to do this is SFSafariViewController and it literally puts a Safari view in your app. This allows for the system to use your content blockers and other installed extensions. It also locks the domain to the one provided by the developer when they brought it on screen.

If one of the benefits of setting your default browser to (let's say) Chrome so you have access to all the Chrome things all the time would it be jarring for a user to see Safari inside of their Twitter app when they tap on a link? Would Apple provide some kind of hook inside of SFSafariViewController to actually show the content of a third-party app like this? If I've purposefully gone and set Chrome as my default browser then I sure don't want Safari ever getting in my way.

There's also similar code around MFMailComposeViewController for sending emails in apps (I use that in Scorebook) as well as MFMessageComposeViewController for sending iMessage or SMS messages. Would they allow users to pick their email or message client and slide up those experiences as well?

If Apple does allow these third-party apps then it will be the result of a mountain of work touching who knows how many parts of iOS. I'm excited to see what we get in iOS 14 come WWDC this year. We should be hearing logistical details about the conference in just a few weeks. 🍿

Apps I Love: Kaleidoscope

Several years ago I had a series of posts here called "Apps I Love". Many of the apps I loved back then I still do, but right now I want to highlight a special part of my tool bag. It's my diff tool of choice: Kaleidoscope. I freaking love this thing, and it's just received its first update in a while to v2.3.

If you've never seen a diff tool in action (or even heard the term), basically what it does is can take 2 things and tell you the difference between them. Kaleidoscope can diff text files, folder contents in the Finder, git branches, and even images. I use it most frequently in my development workflow when resolving conflicts during code merges but have definitely used its folder support before too. It plugs nicely in to my git app of choice Tower (which I should probably write about too).

I do have a funny story to share about Kaleidoscope in closing. Version 2.0 came out 7 years ago, in early 2013. At that point I was barely writing any code and definitely not professionally. I heard about v2's release somehow (probably from one of the tech-related Twitter accounts I was following) and Black Pixel was doing some Twitter contests for free copies. I'm a sucker for stuff like that even if I have no idea how to use what I'm winning. I ended up winning a copy and being lost as to what it did. Fast forward a year or so and I'm learning development and see in Tower that it has a way to trigger Kaleidoscope as the diff tool! That was my gateway to a bigger world 🙂

I really hope this new version is a harbinger of things to come and that some day they'll release a version that I need to pay for. So go check out Kaleidoscope and come to love it as much as I do!

🔗 iOS Performance Tips

iOS Performance tips you probably didn't know (from an ex-Apple engineer)

A common anti-pattern is leaving UITableView/UICollectionView cell labels populated with their text content when these cells enter the reuse queue. It is highly likely that once the cells are recycled, the labels’ text value will be different, so storing them is wasteful.

I could have pulled a few more gems from this super helpful post by Rony Fadel, but this first one struck me off the bat. I don't know how many times I have kept text in a label when I perhaps didn't need to. I also didn't know that the right place to nil-out text in reusable views (UI{Table|Collection}ViewCell) is not in their prepareForReuse() method but in the delegate's didEndDisplaying method instead.

In larger projects with many cell class types this may take some thinking on how to get the message across to a cell type of "time to reset any labels you have". I know if I were still at zulily this would be something that I'd work to get in place as soon as possible, as I did a lot of really hacky things to collection views in my time there 😀

The Time I Stumped the Apple Geniuses

When the Apple stores first opened, the Genius Bar was a much different experience than it is today. For one it actually was a bar you could go to at the back of the store. But they also wanted to answer the really tough questions. And if the Genius you were talking with didn’t know the answer, there was a Red Phone to dial home and talk to someone in the next level up in support. It really was a fun experience.

Prior to the Seattle area getting its first Apple store my family and I went on a vacation to Las Vegas and we went to the Fashion Show Mall so I could see their store. And I had just the question to stump their Geniuses:

iMacs in their wonderful colors – those were the days

I worked at an Apple Authorized Service Center and had been doing service on the iMacs with slot loading optical drives (like the ones pictured above). Whenever I would need to erase a hard drive and restore the operating system I noticed that the desktop wallpaper color matched the color of the case. So a Ruby iMac would get a Ruby colored desktop, and same with Sage green, Indigo blue, and so on. How did they pull this off?

I do also have some inside information to help rule out some possibilities:

  • The main logic boards did not know anything about the shell color. There was 1 part per model of iMac and they were not ordered by color of case. These boards hold everything: CPU, graphics, memory, all the ports, all of the guts.
  • Same story for the other big board: the analog/video board. It was not ordered by color either.
  • The only other real parts inside were the optical and hard drives.
  • Except for the speakers.

And that last part is what I think happens. The speakers on these iMacs were colored to match the back case (and you could see them through the translucent base). I think that there was some chip in the speakers that would indicate to the system what color it was and then the system would pull the appropriate wallpaper.

If you or someone you know may happen to know how this worked I would love to know the answer!

PS: Special thanks to the Xcoders group last night for encouraging me to post this after I told the story. It was a ton of fun to speculate together. Community is awesome 🙂

Update 2/15

After a lot of fun discussion and speculation I think Daniel Kennett has the most plausible answer: the color was encoded into the serial number!

If my memory serves correctly, when we would replace a logic board we would have precisely one opportunity to reset the serial number via a firmware reset tool. I don't recall what would happen if we failed to update the serial number (and that sure would be a fascinating experiment to run!).

Note to self: when animating NSLayoutConstraint properties, remember to call layoutIfNeeded() before the animation block and inside the animation block. Otherwise the animation won't work.

Hopefully this saves future me some time.

Catalystic Converter

Apple this year brought a new technology called Catalyst to the Mac. Going in to WWDC back in June, it was thought that Catalyst (née Marzipan) was going to be the future of the Mac. Essentially it lets developers write an app for iOS using the UIKit frameworks and have it work as a native Mac app. I think the results so far have been hit-or-miss but it's still super early days for this technology.

I'm starting a new project and wondered while updating my project templates – what does making an iOS app work on the Mac actually do to your project? Let's take a look!

Step 1: Make a new, empty iOS project. To make things easy, have Xcode create a git repo. This will set the stage for viewing differences.

Step 2: Add a couple extra targets. Lots of apps nowadays are moving towards a modular approach. This is great because it lets us keep our code separated in such a way that we can easier test our individual pieces and gain reuse by sharing frameworks across apps. I don't know offhand what Catalyst means for my dynamic frameworks and static libraries. Let's add a couple different types of these modules.

Step 3: Commit the current state. We want to capture the repo's place in time.

Step 4: Click the Mac checkbox. In your app's Deployment Info section, check the Mac device target to get going. You'll see the following sheet drop down.

Going Catalyst - hold on to your butts

Moving ahead will surprisingly just make a few changes to your project. There is a new entitlements file added with a couple of entries:

  • com.apple.security.app-sandbox
  • com.apple.security.network.client

I suspect if your app is using iCloud or other permissions that further entitlements may be added here as well, but in our sample project we're not using any of that.

Additionally there are 3 new build settings on only the app target:

CODE_SIGN_ENTITLEMENTS = Catalystic/Catalystic.entitlements;
SUPPORTS_MACCATALYST = YES;
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;

There are a couple of interesting things here. First, only app targets need to be updated in build settings. Your other module's code may need some slight changes to source, but no build settings need to change. Super cool.

The other interesting thing is the DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER setting. I don't know what would happen if this was set to NO. Thankfully there's a handy Help button next to our Mac version's bundle identifier. It's help page contains this text:

You can change the Mac version bundle ID format but then you need manually sign the app. Set the Derive Mac Catalyst Product Bundle Identifier (DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER) build setting to NO, add a macOS conditional value for Product Bundle Identifier (PRODUCT_BUNDLE_IDENTIFIER) and Provisioning Profile (PROVISIONING_PROFILE_SPECIFIER), then manually sign the app.

So that's pretty cool. Xcode will automatically give us the maccatalyst prefixed bundle ID as a convenience to signing our apps across the embedded executables like app extensions. And if you want to manage it all yourself (say by replacing the maccatalyst prefix with a .macos suffix) you can do that too.

So there you have it. Just a few steps and you too can have a Mac app from your iPad source base.

WWDC Resources

My Desk Setup

For the last couple of years I've really dialed in my desk situation. I'm really blessed in that I can have essentially the same setup in 2 places – my office near home, and my desk at the Lyft office. In this post I'll go over the gear I've got, what works and what could be better.

My desk

The Computer

I've got a 2018 MacBook Pro. It's a 6-core i9 with 32GB of RAM – and our Lyft project really demands all those resources. Sure, I'd vastly prefer an iMac Pro on my desk(s) but the portability really is great to have on the whole.

The Dock

Here's the brains of the rest of the operation. I have a CalDigit TS3 Plus which lets me plug one cable into my laptop. From there it breaks out to video, USB, audio, and ethernet. I friggin love this thing. I used to have to plug in power, video, USB, all in separate cables. This box even sends power to my computer so it's a true single-cable plug and go.

The Display

For many years now I've been able to have a 27" 4k monitor on my desk. I've used Dell (pictured here) for quite some time – it's the P2715Q model. I know it's not 5k and the resolution could be better, but 5k monitors are a lot more expensive than I was willing to pay at the time.

I got the Autonomous monitor arm last year and it's been quite nice to have the display floating. There are probably better arms (definitely more expensive ones), but this one has been just fine for my entry in to the bigger world of monitor arms.

The Keyboard

For a long time I used the Microsoft Sculpt ergonomic keyboard, but recently I switched to the Kinesis Advangage2 LF. It's still got the nice split layout that helps with ergonomics, and the key wells help my finger travel be overall smaller. I was feeling a fair bit of pain in my right forearm and with the Advantage2 that has subsided quite a bit.

Fair warning: the layout on the Advantage2 takes a lot of adjusting to. I've been using it for a little over a month and still adjusting.

The Desk & Chair

The desk I have shown is the Autonomous SmartDesk2. It's adjustable to be tall for standing or shorter for sitting. I love the control panel (especially compared to my other desk at the Lyft office) because the programmable buttons let me press once and it will adjust to the defined height. On my other desk I have to keep the button held for it to move. There's plenty of space for all that I put on the surface, and when it's standing up isn't wobbly or rickety at all. Highly recommended - especially for the price. It's one of the least expensive powered desks I've seen.

I also got the Autonomous ErgoChair 2 for the times when my desk is lowered. It's pretty comfortable – though the Steelcase Gesture that Lyft provided is much more comfortable but a lot more money.

You can follow this link to get at least $15 off your order with Autonomous (full disclosure: this is a referral link so I get something back too).

Miscellaneous

  • I love, love, love the Magic Trackpad 2 for all my mousing needs.
  • The HomePod is a great little speaker that more than fills the space.
  • The Logitech HD Pro Webcam C920 is what I use for video calls. It more than gets the job done for me.
  • I use the Audio Technica ATR2100 USB mic for recording podcasts and video calls. I get tons of compliments of how good my audio is.
  • I also under-mounted a power strip on the front-right side of the desk (under the HomePod) so that I didn't have a bunch of cords laying on the ground.

That's my setup. I think the big thing missing from the image above is a little filing cabinet. It's not crucial but I currently stash papers & miscellaneous little stuff behind the comfy chair in the corner (not pictured).

Maverick Apps

I've really liked working on Maverick over the past few days. I want to be blogging more and the improvements I've been making will definitely lead to that end. I deployed my metadata update I wrote about and things are showing no sign of issues. So now I'm on to the next step: better authoring and site maintenance tools.

For a long time I have wanted to make a set of Mac & iOS apps that would let me more easily manage my site. But I've had soem struggles figuring out how best to structure things (I'm starting with the Mac apps because I've long been an aspiring Mac developer). I could make one app that can manage the whole site, and author the needed textbundle files. Or, I could make a couple of different apps: one for basic site maintenance that would facilitate taking in new textbundles from any app you wanted to write in, and another for actually doing the writing.

I don't think there's an app out there right now that does textbundles really well at an affordable price. I've used Ulysses but it has its own syntax for things and you'd have to export files to get them out as a textbundle. Currently I'm a BBEdit user and while I do like it for many things, I think the UX on having markdown files with inline assets could be improved. I'd like to build a really nice textbundle editor as a standalone app.

I don't have any timeline for either of these apps, and honestly I'm not sure which one to build first. I think the textbundle editor may see a broader audience (since I'm the only one using Maverick as a blog engine that I know of). So maybe I'll give that one a go first, especially since I can wrangle up scripts to help with publishing kinks. Okay, I've convinced myself 🙂

I do also want to play with Catalyst, so this would be a really nice opportunity to use iOS to make iPhone, iPad, and Mac apps all with one codebase. Let's go.

Better Procrastination Through Yak Shaving

The first step in any new project is to create the project (more on what the project is tomorrow). That's where yesterday's yak shaving adventure comes in.

The app I'm starting in on is for the Mac. I have a project template for iOS already but it didn't support a Mac app. I have really come to like using Xcodegen to generate my Xcode files and not check them in to source control. So I decided to update my template to support a Mac app.

Instead of starting with the assumption of always wanting a Mac app, I updated the new-module command to output a framework, an iOS app, or a Mac app. This will let me have maximum flexibility for my project. I went about it by creating a shell project from Xcode, extracting the build settings using James Dempsey's excellent Build Settings Extractor, and modified some files to tokenize the name based on input.

I'm pretty happy with the result, even though I've been churning over my new app idea in my head. This was a fun distraction, but now the real work will begin.

I'm at the part of a new project where, before actually starting on the project, I need to update all my templates. Currently updating my iOS project template to be able to make a Mac or iOS app.