Importing Certificates into Xcode 27's Device Hub

Xcode 27 introduced, among other new features, a new Device Hub app for developers that takes the place of the Simulator app. Where Simulator relied on separate windows for each device, Device Hub brings them all together into a single window where each simulated device is the detail view from a source list of devices on the left. It’s a more organized approach, made necessary by the wide variety of platforms Apple and Apple platform app developers have to build and test against.

Xcode 27's Device Hub

For enterprise users or developers building apps that communicate with web services over HTTPS, those services need to be using a certificate pair signed by a globally-trusted authority like DigiCert or Let’s Encrypt for them to work “out of the box” in the simulated OS. If they are using a certificate pair signed by a self-signed or in-house/enterprise CA (Certificate Authority), the OS will refuse to connect, displaying a “This connection is not private” interstitial in Safari or failing with a TLS trust error like NSURLErrorServerCertificateUntrusted.

In releases prior to Xcode 27, you could resolve this by importing the root public certificate into the simulated OS. On iOS, this could be done by dragging and dropping the .cer file onto the Simulator device window. Nothing would appear to happen, but you could then navigate to Settings, General, About, Certificate Trust Settings and mark the certificate as trusted. On tvOS, the process was even more complex, requiring you to open Settings, General, Privacy & Security, hold down the virtual remote’s Play button on the Share AppleTV Analytics option to bring up a hidden dialog, then enter an HTTP URL to a .cer file. Similar to iOS, you’d have to mark it as trusted by navigating tvOS to Settings, General, About, Certificate Trust Settings and enabling the switch for that certificate. This process was slow and, especially on tvOS, quite obscure.

In Xcode 27 with Device Hub, this process is much more uniform.

Signed mobileconfig profile in Apple Configurator

  1. Open Apple Configurator and create a new profile.
  2. Under General, give the profile a name, a unique identifier, and perhaps an organization name.
  3. Under Certificates on the left, click the Configure button and choose the .cer file you wish to install into the simulated OS.
  4. From the File menu, choose “Sign Profile…” and select a developer identity to sign with. Alternatively, you can sign profiles from the command line with security cms -S -N "My Signing Identity" -i unsigned.mobileconfig -o signed.mobileconfig.
  5. In Device Hub, select the target device, then open the Profiles tab in the right-side device inspector.
  6. Click the plus button below the list and choose the .mobileconfig file you just signed.
  7. The profile and its contained certificate should be immediately installed into the simulated OS. In iOS, you can verify by navigating to Settings, General, VPN & Device Management, and on tvOS the list of installed profiles is at Settings, General, Profile.

While this new process does require you to wrap certificates in an Apple Configurator profile, this is much more consistent with how Apple’s device management system works, as it relies on signed profiles with policies, not loose .cer files. And now, just by adding the .mobileconfig to the Profiles section of the device inspector, the embedded certificate is automatically marked as trusted, greatly speeding up installation on new virtual devices.

Macrochips

I was so inspired by Jason Coon’s macrochips project – 4” slate drink coasters laser-engraved to look like notable chips from computing history – that I had to design and make some of my own. I don’t own a laser cutter, but the local hardware store had one available, and I was able to convince them to let me engrave similar slate coasters despite them not being among their pre-defined set of available engraving targets (keychains, mugs, and the like). But what to pick? I decided to go with some chips that were meaningful to me:

  • Apple A17 CPU
  • Nintendo 64 CPU
  • Sony PlayStation CPU
  • Broadcom Raspberry Pi 5 CPU
  • NVIDIA Media and Communications Processor (from the original Xbox)
  • IBM PowerPC 603 CPU (from early PowerPC Macs)
  • Motorola PowerPC G4 CPU (from later PowerPC Macs)
  • AMD K6 CPU
  • Intel i386 EX CPU

The hardest part of designing these was tracking down vector versions of some of these companies’ now-obsolete logos, extracting them from PDF files and datasheets, but I think the designs turned out pretty good:

My macrochip designs

Once designed, it was time to hand them off to the laser cutter:

Laser cutter mid process

It was fun to watch the designs get laid down by the laser cutter:

The results turned out alright:

My macrochip designs as slate coasters

Though, there were a number of text layers I forgot to convert to outlines, so the engraving prep software replaced them with Myriad instead of the specific fonts I had chosen. As well, a few early attempts were also a little mis-aligned. I could certainly do better if I had time to sit and make adjustments with my own laser cutter…

Indiana Jones and the Great Circle

Indiana Jones and the Great Circle title screen

I finally caught up to 2024 and finished playing Indiana Jones and the Great Circle to 100%. I had been putting off starting the game for some time because I’m really not much of a gamer, and I find it oddly difficult to internalize new game control schemes and menu systems. But once I finally picked up the controller, it didn’t take long to get acquainted with the intuitive grip and whip system, and I’m so glad I did, because this game is really something special.

Look and Feel

MachineGames did a fantastic job at matching the feel of the source material. The levels are dense with detail, the typography looks just right, and there are both first person in-game and third person cutscene references to the films’ cinematic choices at every turn. Most notably, the use of hard contrasting light and shadow appears fairly often while exploring. Following along with the game’s story feels like enjoying a lost installment from the original trilogy, which is a bar I didn’t expect it to clear going in.

A spotlight casts Indy's shadow on the wall Carefully placed spotlights and torches regularly cast Indy’s recognizable shadow.

Light shines across Indy's eyes as he thinks Light reveals Indy’s eyes when he’s making a connection or solving a puzzle.

Welcome to Sukhothai screen Open Kapitalen and Eurostile Extended welcome you to new regions and lend film authenticity.

Choosing a mostly first-person adventure also seemed like a big development risk. For an iconic character like Indiana Jones, it’s definitely a choice to not show him for large swaths of the game. To make it convincing, they had to lean hard into what it would be like to be Indiana Jones. So much would revolve around what you can do with your hands and whip and items. Therefore, that in-game system had to feel very comfortable to use and be pretty extensive. I had played a few previous Indiana Jones (and of course, Tomb Raider) games which were all third person, so going in, I thought first person would be weird or off-putting, but this game does it so well that I now prefer it over third person or over-the-shoulder views.

The developers clearly spent a lot of time studying the films. They picked up so many of Indy’s smirks, quirks, and mannerisms, and when combined with Troy Baker’s shockingly accurate voiceover work, you’d be surprised to learn it wasn’t voiced by and motion captured from Harrison Ford himself. The humor from the films is also ever present and used to great effect. Even beyond the dialogue, the yells, grunts, and exclamations all sound so perfect, capturing Indy’s intonation well.

What really put it over the top for me, though, is the music and sound. The game features a lovely and familiar score, threading John Williams’ original themes through new material in a way that sounds completely organic and unforced, rather than just quoting the Raiders March and calling it a day. Sound effects are also very much on point, with whip, punch, and gunfire having the signature cracks, thuds, and pops that seem right out of the films.

There are a few behind-the-scenes videos that go deep into all of this, and I watched them with a big stupid grin on my face. Hearing the development team talk about watching the films together, cataloging the core details that had to be right, and obsessing over everything clearly paid off.

It’s also just a gorgeous game. The id Tech 7 engine looks incredible on modern devices, rendering lighting and geometry in more detail than I’m used to in games (again, I don’t play a ton of games). The amount of just stuff to see in the levels is impressive. I can’t even imagine how long it took to set-dress all these areas. Notably, many of these items can be used as weapons or distractions, including wrenches, frying pans, mops, and bottles.

Indiana Jones turns to think, revealing his adventure companion Gina behind him Just marvel at the level of detail achieved here: The fine individual hair, the wear on the seams of the leather jacket, the distressed fur felt on the fedora, and the specular highlights on the sclera of the eyes.

Looking through a town and down the main river in Sukhothai Every region has loads to explore, little sub-plots to follow, and NPCs going about their business. Some casually relay details or hints towards as-yet-unsolved puzzles.

Gameplay

The game heavily encourages you to lean on Indy’s punch and whip maneuvers rather than using his revolver. Ammo isn’t something to be spent carelessly. Rather, you save it for the moments when you get into a jam that’s larger than you can otherwise take on. But the cost of using a loud weapon is that nearby enemies will overhear it, blow the whistle on you, and rally reinforcements, so you need to pick and choose your battles carefully rather than playing it like a run-and-gun first person shooter. While not a stealth game, climbing, disguise, distraction, and a healthy dose of hand-to-hand combat will get you further than running headlong into battle. Certain classes of enemies will also see through your various disguises and similarly call attention to you, so you need to be aware of who’s nearby.

Looking down from atop a scaffold, reloading Attention to detail is everywhere in this game. Here, the number of remaining shots in the heads-up display corresponds to the number of visibly unfired rounds in the revolver. The reload animation has Indy individually pluck out spent rounds and replace them, rotating the cylinder for each.

The game balances exploration, discovery, collection, puzzle solving, and storytelling well. I rarely found myself spending too much time doing any one of those activities. The puzzles aren’t particularly difficult, with key items often just in adjacent crawlspaces, but they’re also not too simple. They feel calibrated to make you think, but aren’t so onerous that they impede advancing the story.

Along the way, you pick up money, bandages, food, local maps, and Adventure Books that expand your capabilities. The books are the game’s skill system, where you can improve your abilities like reducing reloading time, increasing damage dealt against enemies, or boosting climb and run stamina, and finding them is a nice reward for exploration. Once learned, they make future encounters progressively more achievable and boost your confidence to take swings at more aggressive confrontations. Indy is a scholar and a problem-solver first, so getting better at the job through research feels like the right approach.

A view of the menu system listing Adventure Books that boost combat skills Acquiring and reading Adventure Books boosts combat, survival, brawling, etc.

Indiana Jones' Pause menu Even the Pause menu looks like it belongs. Also, hey, it’s me: I’m mac_minded on PlayStation and Mac Minded on Xbox.

That Belongs in a Museum

The Order of Giants DLC is a worthwhile addition, though it left me wanting even more time in this world. What MachineGames accomplished here is astounding. Licensed games based on beloved properties like Indiana Jones have a history of often getting surface details right but missing what actually made the source material work. This one didn’t miss. It understood what Indiana Jones is about well enough to make a game that genuinely belongs on the same shelf as the films. I don’t know if it will happen, but I would very much love a sequel.

Using uv with RedHat Python Images

When deploying web apps, I use containers almost exclusively. Containerization lets you package up everything your app needs and ship all of it to a container runtime in a single archive. While it has some drawbacks, it’s still a significant net improvement over web app deployment methods that pre-date it.

I use uv to install dependencies into a container image, but I typically don’t want to create a Python virtualenv within the container because then there are two levels of isolation to contend with. Just the container alone is sufficient. However, I still want all the benefits of using uv, particularly the specific tree of dependency versions and their hashes listed in the uv.lock file. For this reason, I configure uv to install the listed dependencies into the container’s “system” Python at install time, rather than a virtualenv .venv/ directory:

FROM registry.redhat.io/rhel9/python-312:latest

WORKDIR /opt/app-root/src

# Use the "system" Python for uv (the container's)
ENV UV_SYSTEM_PYTHON=1
ENV UV_PROJECT_ENVIRONMENT=/opt/app-root

# Install uv
RUN pip install --upgrade pip==26.0.1 && pip install --upgrade uv==0.11.4

# Copy only dependency files first to cache the dependency installation as its own container image layer.
# --active: prefer the environment specified by VIRTUAL_ENV (in the upstream RedHat Python base image)
# --frozen: treat the versions in uv.lock as the source of truth and skips updating the lockfile
# --no-dev: skip dev dependencies, since this is a non-development environment
# --compile-bytecode: compile Python files to .pyc files to trade CI build time for faster container start time
# --no-python-downloads disables automatic downloads of Python so we use the container's
COPY pyproject.toml uv.lock .
RUN uv sync --active --frozen --no-dev --compile-bytecode --no-python-downloads

# Copy the rest of the codebase in a separate layer
COPY . .

CMD ["granian", "app:app"]

Those options will use uv to install dependencies into the container-provided Python environment at /opt/app-root/ in the Python image rather than creating a new virtualenv at /opt/app-root/src/.venv/. With this, you can omit uv run ... from container commands, cron jobs, etc. Opening a shell into this container will drop you into a place where the dependencies are installed and readily available without having to activate a virtualenv, prefix tool invocations with uv run, or specify a container ENTRYPOINT).

Push Notifications with Brrr

iOS developer Simon Støvring recently launched Brrr, a convenient and low-friction web service and corresponding iOS app deliver push notifications to your iOS devices using only an HTTP request. In this way, it can integrate with almost any service or device that is internet-connected. Options allow you to customize the notification content, alert sound, destination URL, image, and more.

Brrr fills the particular niche of when you want a quick notification from a script, a cron job, or home automation trigger without building your own push notification infrastructure. It’s not the first app of its kind to do this, but it does so very simply. And at $9.99/year, it’s very reasonably priced for what it does.

Mastodon