Skip to main content
Donovan’s Vision Blog

ARCtic iOS conference 2025 - Day 2

After a great ARCtic Conference day 1, we had a second day packed full of inspiring Apple development talks.

Highlights #

  1. Paul Hudson introduced Ignite, a new static site generator for Swift, allowing developers to build websites using Swift’s syntax and SwiftUI-like result builders.
  2. Mikaela Caron showcased TabletopKit for VisionOS, demonstrating how to create immersive tabletop games with RealityKit and SharePlay integration.
  3. Daniel Steinberg broke down some vs. any in Swift, explaining their impact on generics, type safety, and performance.
  4. Priyal Porwal explored Swift Macros, showing how they reduce boilerplate and improve maintainability in iOS apps.
  5. Hidde van der Ploeg emphasized “Less AI, more magic”, encouraging developers to focus on seamless user experiences rather than highlighting AI.
  6. Pol Piella Abadia demonstrated Xcode’s Instruments, providing insights into detecting performance bottlenecks, UI hangs, and memory leaks.
  7. Aurelius Prochazka discussed the history of AudioKit, highlighting the benefits of creating community.

If you missed it, you can find a write-up of the talks from day one here.

Day 2 talks #

As with day one, the conference took place in the beautiful Teatteri Rio. The following is my notes from each of the talks.

Paul Hudson: Ignite #

At the recent ARCtic Conference, Paul Hudson introduced Ignite, a new tool that allows Swift developers to build websites using Swift. This talk explored why this approach makes sense and how Ignite simplifies web development while leveraging Swift’s strengths.

When building websites today, developers need to consider a range of factors:

For Swift developers, juggling both Swift and HTML can be a challenge. Hudson’s argument is that using Swift to build websites could streamline this process, making web development more familiar and accessible for Swift developers.

One of the key innovations behind Ignite is its use of Swift’s Result Builders to define HTML structures. This approach allows developers to write HTML in a SwiftUI-like syntax. Just as swift handles views like this:

VStack {
  Text("Hello world")
}

This can be directly mapped to HTML elements:

h2 {
  Text("Hello world")
}

By adopting SwiftUI’s declarative approach, developers can define web pages with clean, readable Swift code that is then rendered appropriately for the web.

Ignite: A Static Site Generator for Swift Developers #

Ignite is a static site generator designed specifically for Swift developers. It allows you to write websites in Swift and publish them easily, whether to GitHub Pages or other hosting services.

This makes Ignite an appealing choice for developers who want a Swift-centric approach to building websites while ensuring modern compatibility and accessibility.

Ignite in Practice #

Ignite is open source and actively maintained, boasting over 74 contributors and 500+ unit tests. While it is focused on static site generation, developers looking for more dynamic functionality can integrate it with Vapor or Hummingbird.

If you’re interested in seeing Ignite in action, check out the live examples available at Ignite Samples.

During the talk, one interesting idea came to mind: Could Ignite be used as a template for app developers to create marketing websites for their apps?

A simple, ready-to-use Ignite template could include:

Since Ignite handles the complexities of web development, Swift developers could quickly spin up an app website without needing to learn HTML, CSS, or JavaScript.

Find Ignite on GitHub.

Mikaela Caron: Creating games with TabletopKit for VisionOS #

TabletopKit is a set of APIs designed for building tabletop games, working alongside RealityKit to render 3D elements. It provides a structured approach to game development by defining tables, seats, equipment, and interactions within a shared environment.

Setting Up a Game #

Each game is centered around a table, which exists within a Volume and conforms to the Tabletop protocol. The table is identified using an Equipment identifier. Players occupy seats, which have specific poses relative to the table. These seats conform to the TableSeat protocol, defining their state and position.

The primary steps to building an app with TabletopKit include:

Equipment and Game Elements #

Each piece of equipment requires a unique identifier (e.g., table, seats, game pieces). Equipment conforms to the Equipment protocol and has a BaseEquipmentState for configuration and rules. Items are added to the tabletop using setup.add.

Additional considerations include:

Handling Interactions #

Interactions are managed through a structured update cycle:

Gestures define possible actions, such as:

Observing Actions and Game State #

After setting up interactions, observers track game state changes and trigger responses, such as animations or state updates based on the type of equipment being used.

Enabling SharePlay for Multiplayer #

TabletopKit integrates with the GroupActivities API to support shared multiplayer sessions. This is managed through:

This ensures that game states remain in sync, allowing for a seamless shared experience.

Daniel Steinberg: What the heck happened to generics #

Understanding some and any in Swift #

Swift provides some and any as ways to define opaque or existential types, but choosing the right one can impact performance and flexibility.

Using some and any #

Handling Identifiability in Lists #

Best Practices #

Swift encourages certain best practices to optimize performance and maintainability:

Parameter Packs for Generic Views #

To handle cases where a function needs to render multiple types of views generically, parameter packs can be used. These allow a flexible number of generic parameters without needing to specify them individually, improving type safety and reducing boilerplate. More details can be found in this guide.

Priyal Porwal: Building maintainable iOS apps with Swift Macros #

Swift macros, introduced in Swift 5.9, are used throughout Xcode to reduce repetitive code and improve performance by generating code at compile time. One common example is the #Preview macro for SwiftUI views. While macros do not support parameters, they help streamline development by eliminating boilerplate code.

Types of Macros #

There are two main types of macros:

Creating and Using Custom Macros #

Developers can create custom macros in Xcode using the swift-syntax framework. Macros should be well-tested, ensuring that their output matches expected results, including formatting details like newlines. A basic example of a macro definition looks like this:

public macro myMacro(...)

Macros have specific roles that define how they transform code. More details on their implementation and best practices can be found in this article.

Challenges and Considerations #

While powerful, macros come with challenges. The syntax can be complex, and poorly optimized macros can increase build times. Proper testing is crucial, but unit tests for macros can be tricky due to strict formatting requirements. Macros offer significant benefits by simplifying code and improving maintainability.

Hidde van der Ploeg: Less AI, more magic #

AI is everywhere. It's like when electricity replaced candles. Over time, appliances came about from better understanding of electricity. In a way, AI is similarly early.

Using AI can help in marketing, but we can go further and turn it into magic.

Magic = achieving the impossible #

AI can help produce solutions that were not possible before. We don't need to call it out with sparkles icons. Such as when presenting a summary of data - the value is in the summary not in dressing it by advertising the implementation details.

Approach: Start with the problem #

As in, don't start with "how can we use AI to do insert thing here", instead ask "how do we do insert thing here" and if AI is an answer, maybe use it. In the end the customer doesn't care if the solution is created with AI as long as it works.

AI presents a new or extended pallette of tools. From image generation, text summaries, translations and more.

Abstract away the complexity #

Instead of using an open text field, offer more specific options such as translate or improve. The chat box is only the beginning.

Naming features #

In the example above, translate could be AI translation but not useful information for the user looking for a solution.

Sell the solution, not the technology.

Pol Piella Abadia: Tuning your app using Xcode's instruments #

Instruments are powerful tools for analyzing performance across Apple platforms. They are integrated into Xcode and can be accessed from the standalone Instruments app, by pressing Cmd + I in Xcode, or navigating to Product -> Profile. While incredibly useful, mastering them can take time.

Working with the Main Thread #

All UI updates must happen on the main thread. If a function runs on a background thread but modifies the UI, it can cause crashes or unexpected behavior.

However, overusing @MainActor can lead to performance bottlenecks. If the main thread is too busy, it may cause UI delays or hangs:

Memory Management & Leaks #

Memory leaks occur when allocated memory is not properly released, leading to increased memory usage over time. This is often due to strong references preventing objects from being deallocated.

The Leaks instrument in Instruments helps identify memory leaks:

Using the Profiler #

To diagnose performance issues, Instruments provides various profiling tools:

For long-running tasks that slow down the main thread:

Additional Tools & Tips #

By integrating these tools into development workflows, performance issues can be identified and resolved efficiently, leading to smoother, more responsive apps.

Aurelius Prochazka: 10 Years of Magic and Bliss (Just Kidding) #

The creator of AudioKit, Aurelius gave a wonderful talk that drew together all the others in delivering insights about how to be a positive member of the developer community.

Shipping, improving, collaborating, and the benefits of putting out quality into the universe. A lovely end to the day!