Hacking with Swift News, tips, and tutorials from Hacking with Swift https://www.hackingwithswift.com/articles/rss (c)2020 Paul Hudson https://www.hackingwithswift.com/favicon-96x96.png Hacking with Swift https://www.hackingwithswift.com/articles/rss What to fix in AI-generated Swift code https://www.hackingwithswift.com/articles/281/what-to-fix-in-ai-generated-swift-code https://www.hackingwithswift.com/articles/281/what-to-fix-in-ai-generated-swift-code As AI-assisted coding increases in popularity, here are a handful of things I would suggest you look out for – and what to replace them with instead. Thu, 04 Dec 2025 15:24:04 +0000 Building apps in Swift and SwiftUI isn’t quite as easy for AI tools as other platforms, partly because our language and frameworks evolve rapidly, partly because languages such as Python and JavaScript have a larger codebase to learn from, and partly also because AI tools struggle with Swift concurrency as much as everyone else.

As a result, tools like Claude, Codex, and Gemini often make unhelpful choices you should watch out for. Sometimes you’ll come across deprecated API, sometimes it’s inefficient code, and sometimes it’s just something we can write more concisely, but they are all easy enough to fix so the key is just to know what to expect!

Before I start, I want to mention three things up front:

  1. This advice assumes you’re able to target modern versions of iOS, i.e. iOS 18 or later. If you need to support older versions, your AI of choice will have a better chance of getting it correct.
  2. This is not designed to be an exhaustive list; it’s just the most common things I look out for.
  3. I’m not interested in arguing about whether LLMs are good or not; I accept they exist, and that many people want to use them, so I might as well help folks use them better.

Still here? Okay…

  • Every time you see foregroundColor(), switch it out for foregroundStyle(). It’s the same number of characters to type, but the former is deprecated, whereas the latter supports more advanced features like gradients.
  • Replace cornerRadius() with clipShape(.rect(cornerRadius:)). Again, the former is deprecated, whereas the latter offers more advanced features such as uneven rounded rectangles.
  • The onChange() modifier should not be used in its 1-parameter variant. Either accept two parameters or none, but the old variant is unsafe and deprecated.
  • If you see the old tabItem() modifier, replace it with the new Tab API instead. This lets you benefit from the new type-safe tab selection, and also adopt things like the iOS 26 search tab design.
  • Replace almost all use of `onTa...
]]>
One Swift mistake everyone should stop making today https://www.hackingwithswift.com/articles/280/one-swift-mistake-everyone-should-stop-making-today https://www.hackingwithswift.com/articles/280/one-swift-mistake-everyone-should-stop-making-today TL;DR: You should use replacing(_:with:) rather than replacingOccurrences(of:with:) Mon, 10 Nov 2025 20:57:22 +0000 There’s a Swift mistake I see time and time again, it can cause serious problems, and it’s trivial to fix. I’ve talked about it before, other people have talked about it before, and I even made a long Hacking with Swift+ video about it.

I don’t believe in making folks wait, so here’s the simple answer: if you’re using the String method replacingOccurrences(of:with) you should probably change it to replacing(_:with:) to avoid causing unintentional and frankly bizarre bugs.

If you’re not sure why, read on – I’ll start by showing you the problem in a simple way, then show you the solution.

First, think about this code:

let vacation = "🇨🇦🇺🇸"

That’s a trivial string containing two flags. As it’s a string, we can check whether it contains the Canadian flag like this:

print(vacation.contains("🇨🇦"))

And we can check whether the string includes the US flag like this:

print(vacation.contains("🇺🇸"))

Both those will print true, because both those flags are present in the string.

Similarly, we could check whether the string contains the Australian flag like this:

print(vacation.contains("🇦🇺"))

That will print false, because clearly the string "🇨🇦🇺🇸" does not contain 🇦🇺.

Now try this:

print(vacation.replacingOccurrences(of: "🇦🇺", with: "🇳🇮"))

That replaces the Australian flag with the Nicaraguan flag, which sounds innocent but is at the core of the problem I’m talking about here.

If you’re reading this and not trying the code, this will hurt your head: that code will print “🇨🇳🇮🇸” – the flags for China and Iceland.

Yes, even though we’re replacing something that doesn’t exist in the string.

What’s happening here?

Problem, meet solution

The problem is that `replacingOccurrences(of:wi...

]]>
Level up your SwiftUI https://www.hackingwithswift.com/articles/279/level-up-your-swiftui https://www.hackingwithswift.com/articles/279/level-up-your-swiftui Learn how to take average code and iteratively improve it until it shines Thu, 28 Aug 2025 13:56:23 +0000 On October 11th I’m running an interactive online workshop to help you write better SwiftUI code, and I hope you can join!

It's something I’ve run at several conferences worldwide, and the feedback is always very positive: it's clear, practical, and packed with takeaways you can use immediately.

We focus on issues such as:

  • Smarter code architecture
  • Clearer Swift and SwiftUI
  • Updating deprecated code
  • Internationalizing layouts
  • Creating consistent designs
  • Better UI and UX
  • Solid Xcode project structure

It’s accessible to all levels of SwiftUI developers – you can come and contribute as much as you want, or stay quiet and just watch if you prefer.

The workshop takes place at 10am UK time and then again at 5pm UK time, both on October 11th. Each session will last about three hours.

This workshop is free for all Hacking with Swift+ subscribers. You can attend either workshop or both, or if you can’t attend a transcript will be available a couple of days later. Links to the streams will be published on the HWS+ homepage a few days before the event.

Not a member yet? Join today and unlock this workshop plus the Swift Career Accelerator, book discounts, monthly live streams, and more.

If you want to level up your SwiftUI skills in just a few hours, this is the workshop you can’t afford to miss!

]]>
What's new in SwiftUI for iOS 26 https://www.hackingwithswift.com/articles/278/whats-new-in-swiftui-for-ios-26 https://www.hackingwithswift.com/articles/278/whats-new-in-swiftui-for-ios-26 WebView, rich text editing for TextEditor, section index list titles, and more Thu, 19 Jun 2025 22:15:44 +0000 Although the SwiftUI changes this year are a little smaller than we're used to, this year's SwiftUI update resolves a handful of common complaints folks hit when building – things that would pretty much always require us to drop down to UIKit can now be done natively, which is great.

This year the two biggest changes are:

But in talking to developers, it's been interesting to see how smaller features are often more popular, usually because they finally resolve long-standing annoyances with SwiftUI:

Once again we got a fantastic update from SF Symbols – the new draw on animations are thoroughly beautiul, particularly when used with things like checkboxes.

And there's also a bundle of updates specifically aimed at Apple's new liquid glass user interface, including:

]]>
What's new in Swift 6.2? https://www.hackingwithswift.com/articles/277/whats-new-in-swift-6-2 https://www.hackingwithswift.com/articles/277/whats-new-in-swift-6-2 Raw identifiers, backtraces, task naming, and more. Fri, 09 May 2025 20:04:59 +0000 Brace yourselves, folks: Swift 6.2 contains another gigantic collection of additions and improvements to the language, while also adding some important refinements to Swift concurrency that ought to make it much easier to adopt everywhere.

Many changes are small, such as the addition of raw identifiers, default values in string interpolation, or enumerated() conforming to Collection, but these are all likely to spread quickly across projects because they are just so darned useful.

It's also great to see Swift Testing going from strength to strength, with three major improvements coming in Swift 6.2, including exit tests and attachments.

In short, it feels like Swift 6.2 is delivering what many imagined Swift 6.0 would be – increasingly rounded support for concurrency, backed up by a number of pragmatic choices that help smooth out the language's learning curve.

Note: At the time of writing, Swift 6.2 is available only as a test release from Swift.org. The list below represents my best guess for what's coming up – don't be surprised if something slips to a later or release or something else arrives by surprise!

Control default actor isolation inference

SE-0466 introduces the ability for code to opt into running on a single actor by default – to effectively go back to being a single-threaded program, where most code runs on the main actor until you say otherwise.

Yes, this is exactly as good as you're thinking: with one single change many app developers can more or less avoid thinking about Swift concurrency until they are ready to do so, because unless they say otherwise all their types and functions will behave as if it were annotated with @MainActor.

To enable this new feature, add -default-isolation MainActor to your compiler flags, and code like this becomes valid:

@MainActor
class DataController {

...

]]>
What's new in Swift 6.1? https://www.hackingwithswift.com/articles/276/whats-new-in-swift-6-1 https://www.hackingwithswift.com/articles/276/whats-new-in-swift-6-1 Trailing commas in lists, metatype key paths, diagnostic groups, and more. Thu, 01 May 2025 10:55:05 +0000 This year's spring release of Swift brings with it a number of welcome additions and refinements that will make small but important improvements to many projects.

Things like support for trailing commas in lists have been on many people's wish lists for some time, and the extended use of nonisolated helps work around one of the pain points folks encounter with Swift concurrency, but ultimately these changes are mostly minor and provide a neat run up to larger changes that will come in Swift 6.2.

Let's take a look at what's changing…

Allow trailing comma in comma-separated lists

SE-0439 adjusts Swift's syntax so that trailing commas are now permitted in arrays, dictionaries, tuples, function calls, generic parameters, string interpolation, and indeed anywhere a list of items is bound by parentheses (), brackets [], or angle brackets <>.

So, this kind of code is now allowed:

func add<T: Numeric,>(_ a: T, _ b: T,) -> T {
    a + b
}

let result = add(1, 5,)
print(result,)

In practice you're unlikely to write that kind of code, but this feature is really useful in code like this:

import Foundation

let message = "Reject common sense to make the impossible possible."

let range = message.range(
    of: "impossible",
    options: .caseInsensitive
)

You can see the call to range(of:options) is split across multiple lines, which is a fairly common coding style. It looks for the string "impossible" in a case-insensitive search, but thanks to the support for trailing commas we can comment out the whole options: .caseInsensitive line entirely without breaking our code – the line before ends with a trailing comma, but that's allowed from Swift 6.1 onwards.

T...

]]>
Apple starts accepting GitHub sponsorships for Swift https://www.hackingwithswift.com/articles/275/apple-starts-accepting-github-sponsorships-for-swift https://www.hackingwithswift.com/articles/275/apple-starts-accepting-github-sponsorships-for-swift Send money, get rewards. Tue, 01 Apr 2025 15:17:12 +0000 Last year Apple began moving Swift and its associated projects from GitHub.com/apple over to GitHub.com/swiftlang, and the reason is becoming clear: you can now use GitHub Sponsors to support the project with a regular monthly donation, getting various rewards in return.

There are a number of tiers on offer right now, but this might change over time – keep an eye on the project for updates.

The launch tiers are:

  • $5 a month: Your name is added to a @discardableResult contributor list. Might be used. Might not.

  • $10 a month: Your name and email address are displayed in Xcode's crash dialog. You're welcome.

  • $20 a month: You get to use C-style for loops again – admit it, you missed them.

  • $30 a month: Receive one (1) tub of Craig Federighi’s personal hair gel. Warning: may result in sudden confidence, vertical hair lift, and involuntary keynotes.

  • $50 a month: You gain access to a special version of LLDB where po works first time. (But only on Tuesdays.)

  • $100 a month: Includes one automatic rewrite of a Swift expression too big for the compiler to type check. Xcode will automatically split your line into 47 let statements and add a single comment, "There. Happy now?"

  • $250 a month: Your name is chosen as a Swift reserved word so you can strut around in code reviews like the royalty you are.

  • $500 a month: Every time you force unwrap an optional, a monk from Apple’s compiler team lights a candle. Your app will probably still crash, but morally you’re in the clear.

  • $750 a month: Xcode will let you disable WiFi debugging for a device, but only if you ask nicely.

  • $1000 a month: The compiler will start issuing passive-aggressive warnings. "Oh, you're still using Combine? Brave."

  • $2000 a month: Your Swift code is no longer subject to ABI stability. You are the ABI now.

  • $5000 a month: Once per month, Tim ...

]]>
Take on Apple Intelligence at Unwrap Live 2025 https://www.hackingwithswift.com/articles/274/take-on-apple-intelligence-at-unwrap-live-2025 https://www.hackingwithswift.com/articles/274/take-on-apple-intelligence-at-unwrap-live-2025 Bring your apps into the age of AI with AppIntents, image playgrounds, and more! Thu, 09 Jan 2025 12:14:22 +0000 Unwrap Live is back for its third year, this time focusing on building great apps using Apple Intelligence.

Once again, it's a full-day, online-only workshop event aimed at intermediate to advanced developers, and everyone who attends will have ample chance to learn new approaches, tackle coding challenges, and of course ask lots of questions.

This year we'll be focusing on three key areas of AI:

  • Getting deep integration with AppIntents so the system, so your app's content can be accessed and even queried through Siri.
  • Integrating generative AI into your app using Image Playgrounds and writing tools.
  • Bonus APIs such as NaturalLanguage and Translation.

If we have any extra time, I might try to squeeze in training your own models using Create ML, but that can be guided by folks on the day.

The format is the same as last year: live-streamed videos for all attendees where I walk you through specific techniques, backed up by hands-on coding challenges where you need to apply what you've learned – it's the fastest way to get up to speed with building great apps with AI.

All sessions take place March 8th, from 9am to 4pm US Eastern time. They will be recorded, and you'll be able to download the videos afterwards.

Tickets cost $100 each, but Hacking with Swift+ subscribers get access free. If you aren't already a Hacking with Swift+ subscriber, you can sign up before the event to get your free ticket – find out more here.

I'm also offering two other ticket types:

  1. A diversity sponsor ticket, which is for folks who already have a ticket and want me to give one ticket away to someone who would otherwise not be able to attend.
  2. A ticket + diversity sponsor option, where you can buy a ticket for yourself and one for me to donate.

Get your ticket here!

]]>
Save 50% on all books and bundles this Black Friday https://www.hackingwithswift.com/articles/273/save-50-on-all-books-and-bundles-this-black-friday https://www.hackingwithswift.com/articles/273/save-50-on-all-books-and-bundles-this-black-friday All books and bundles are half price! Mon, 11 Nov 2024 12:32:34 +0000 My Black Friday sale starts today, which means you can save 50% on all my books and bundles! I have a huge range of books for all skill levels, including:

  • Pro Swift helps you develop a deeper knowledge of the Swift language, and is packed with videos demonstrating all the techniques.
  • Pro SwiftUI explores advanced techniques in SwiftUI, including optimization, debugging, complex layouts and animations, and more.
  • Swift Design Patterns and Testing Swift combine to help you develop senior developer skills.
  • Hacking with macOS and Hacking with watchOS show you how to extend your SwiftUI skills to other Apple platforms.
  • Plus there are lots more books to choose from, such as SwiftUI by Example, SwiftData by Example, and Swift Concurrency by Example.

All my bundles are also on sale, meaning that you can get the Swift Power Pack for $75, the Swift Platform Pack for $100, or the Swift Plus Pack for $75. These bundles normally have a discount over buying the books individually, but the Black Friday sale on top makes them incredible value for money.

But if you want to save the most, you're looking for the Hacking with Swift: Everything Pack. It contains every book I've written so far, which means it's an instant learning library no matter your current level.

Bought individually, the books in the Everything Pack would retail for $820. Bought as a bundle that price comes down to $500. And with the 50% Black Friday discount on top, it takes the total price to get all the books I've written so far down to just $250 – it's just unbeatable value for money.

The sale starts November 11th, and runs until December 2nd. Whether you want to complete your collection, learn something new, or perhaps just treat a friend to a Christmas gift, this is your chance!

]]>
Go further, faster with the Swift Career Accelerator https://www.hackingwithswift.com/articles/272/swift-career-accelerator https://www.hackingwithswift.com/articles/272/swift-career-accelerator Your complete Swift journey: from first job to leadership, all in one powerful program Thu, 19 Sep 2024 09:24:33 +0000 Unleash your full potential as a Swift developer with the all-new Swift Career Accelerator: the most comprehensive, career-transforming learning resource ever created for iOS development.

Whether you’re just starting out, looking to land your first job, or aiming to become a lead developer, this program offers everything you need to level up – from mastering Swift’s latest features to conquering interview questions and building robust portfolios.

So, if you're ready for a guided journey that will elevate your skills and accelerate your career, read on…

Your complete pathway

The Swift Career Accelerator aims to give you a complete pathway to take your career forward, no matter what your level is right now.

It does this by bringing together for the first time the world's largest collection of Swift development resources in one place, then carefully organizes it across five career stages so that everyone at every level has something to take them forward…

Level 1: Kickstart your career and land your first job

If you’re just starting out, Level 1 is designed to help you build the foundation for a successful career in Swift development. Along with my popular 100 Days of SwiftUI and Ultimate Portfolio App courses, you’ll gain exclusive access to my brand-new Take Home Test course. You’ll master essential skills like Git source control and dive into critical data structures like queues, stacks, and trees.

But that’s just the beginning. You’ll also get a wealth of new interview questions with expert answers, step-by-step guidance on crafting a standout resume, and practical tips for launching your first apps on the App Store. Everything you need to land that first job and start building your future is right here.

Level 2: Strengthen your skills and advance as a developer

Once you've found your first job, it's time to build on that foundation and take your skills to the next level. Here you'll move on to more detailed topics such as **gener...

]]>
Making mistakes while learning Swift https://www.hackingwithswift.com/articles/271/making-mistakes-while-learning-swift https://www.hackingwithswift.com/articles/271/making-mistakes-while-learning-swift Tired of making mistakes while learning to code? You're not alone. Wed, 07 Aug 2024 16:39:44 +0000 I run a monthly newsletter about Swift, and each month I try to finish with a few thoughts based on work I'm doing, people I've met, or advice based on past experiences. In the July 2024 edition I wrote about mistakes, and I had so many folks reach out to me to thank me for tackling a difficult topic so honestly that I decided to publish it here too.

A few weeks ago I received an email, which I'm sharing below with permission.

"I keep making mistakes, and have to go back and fix them again and again and again, and frequently make more mistakes while trying to fix the first mistakes. You never seem to screw up in any of your streams. How many more years until I get to that point?"

I've mildly edited it to be a bit less sweary, but I think you get the point! It took me until yesterday to reply (sorry, I recently moved house!), but I'm going to share my reply with you all below in case it helps you too.

First, congratulations on making mistakes! I know that sounds odd, but often we get so focused on not making mistakes that we forget mistakes are part of everyone's journey – trying things out, getting them wrong, and learning lessons from that experience is a fantastic way to learn, and it's even true that sometimes the only way to figure out what's right is to see what's wrong first.

One of my favorite Steve Jobs videos is him responding to a rather aggressive crowd question about some of his choices on returning to Apple. Towards the end, he says "some mistakes will be made along the way, and that's good, because at least some decisions will be made along the way." So, as hard as it might be, be happy that you're making mistakes, because it shows you're pushing yourself outside your comfort zone and learning something new.

Second, you have no idea how many mistakes I've made over the years. Lots of small ones, sure, but dozens – hundreds? – of really serious errors, some of which I'm going to regre...

]]>
What’s new in SwiftUI for iOS 18 https://www.hackingwithswift.com/articles/270/whats-new-in-swiftui-for-ios-18 https://www.hackingwithswift.com/articles/270/whats-new-in-swiftui-for-ios-18 We got new API for colors and gradients, more scrollview improvements, tab improvements, and more. Fri, 21 Jun 2024 19:44:52 +0000 This is another good year for SwiftUI, with another batch of scrollview improvements, some welcome macOS features, remarkable control over text rendering, and more – the team at Apple have a lot to be proud of, and many developers will breathe a sigh of relief as API such as fine-grained subview control is now public for all of us to use.

But there's also one major architectural change you need to be aware of, so let's start with that…

View is now on the main actor

For a long time, the View protocol looked a bit like this:

protocol View {
    @MainActor var body: some View
}

That meant code in your view's body ran on the main actor, but code elsewhere in your view did not.

This allowed our views to do work across tasks naturally, but caused problems when using @Observable classes that ran on the main actor. For example, code like this simply wouldn't compile:

@Observable @MainActor
class ViewModel {
    var name = "Anonymous"
}

struct ContentView: View {
    @State private var viewModel = ViewModel()

    var body: some View {
        Text("Hello, \(viewModel.name)!")
    }
}

That would throw up "Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context", which is a rather complex way of saying "your class says it must be on the main actor, but you're creating it away from the main actor."

When you rebuild your code with Xcode 16 that error goes away completely, and with no work from us – it's just gone. However, it's important to know why. You see, the View protocol now looks more like this:

@MainActor protocol View {
    var body: some View
}

The difference is small, but makes a huge difference: the @MainActor attribute moved from body up to the protocol itself, which means the body property along with all other properties and methods we make are run on the main actor.

You can see the impact with this sample code:

struct Co...
]]>
What's new in Swift 6.0? https://www.hackingwithswift.com/articles/269/whats-new-in-swift-6 https://www.hackingwithswift.com/articles/269/whats-new-in-swift-6 When fully enabled, Swift 6 is likely to require changes in pretty much every project. Sun, 09 Jun 2024 21:20:26 +0000 2024 is Swift's 10th anniversary, and for the last five of those years we've had no major-version Swift updates – literally half of Swift's life has been 5.0 through to 5.10.

This is more common than you might think. In fact, several major programming languages have some kind of release that takes significantly longer than all others: Python 3 took years to arrive, PHP 6 took so long the team bailed out and jumped straight to PHP 7, and Perl 6 dragged on so much that it ended up evolving into a different language called Raku.

Swift last had major breaking changes back in Swift 3, but when enabled in full Swift's own v6 has the potential to make Swift 3 look like a walk in the park. This is partly because of new changes, but partly also because many features added in recent Swift versions have been hidden behind feature flags that will be enabled by default in Swift 6.

Let's take a look at what's changing…

Complete concurrency enabled by default

Swift 6 contains another barrage of updates around concurrency, and the team ought to be proud of the extraordinary advances they have made to make this release possible.

By far the biggest change is that complete concurrency checking is enabled by default. Unless you're very fortunate indeed, there's a very good chance your code will need some adjustment – it's no surprise the Swift team made it optional in earlier versions to give folks time to evaluate what's changing.

Swift 6 improves concurrency checking further, and the Swift team say it "removes many false-positive data-race warnings" that were present in 5.10. It also introduces several targeted changes that will do wonders to make concurrency easier to adopt – if you tried with 5.10 and found things just too gnarly to figure out, hopefully some of the changes in Swift 6 will help.

Easily the biggest is [SE-0414](https:/...

]]>
Save 50% on all books and bundles for WWDC24 https://www.hackingwithswift.com/articles/268/save-50-on-all-books-and-bundles-for-wwdc24 https://www.hackingwithswift.com/articles/268/save-50-on-all-books-and-bundles-for-wwdc24 Shop the Hacking with Swift sale and upgrade your skills today! Sun, 09 Jun 2024 19:38:18 +0000 WWDC24 is here, which means all-new upgrades for Swift, SwiftUI, SwiftData, and more. If you want to stay ahead of the pack, you'll be pleased to know that all Hacking with Swift books and bundles are half price for WWDC – including my all-new Everything Pack, which means you can buy every book I've ever published at one unbeatable price.

All Hacking with Swift books come with:

So, whether you're looking to learn something new, take the next step in your career, or just complete your collection, now is the time.

]]>
What's new in Swift 5.10? https://www.hackingwithswift.com/articles/267/whats-new-in-swift-5-10 https://www.hackingwithswift.com/articles/267/whats-new-in-swift-5-10 Important concurrency clean ups ahead of Swift 6. Sun, 09 Jun 2024 19:13:50 +0000 A huge swathe of features, changes, and adjustments are planned Swift 6, but before then we have Swift 5.10: an interim release mostly focused on fixing up data race checking at compile time, hopefully clearing the decks for Swift 6.

Let's take a look at what's changing…

Data races are now clearly diagnosed

Swift concurrency was introduced back in Swift 5.5, but had a bit of a rocky adoption both in Apple's own frameworks and our own projects. However, with Swift 5.10 the team made a rather dramatic statement: "Swift 5.10 closes all known static data-race safety holes in complete strict concurrency checking."

Concurrency checking is what allows the compiler to verify our use of concurrent code is safe – that we aren't accidentally sharing mutable state in a way that can cause race conditions. Of course, the key word here is "known": everything they know about has been resolved.

Apple's work here is not only hugely innovative, but hugely complex: similar to how type inference requires the Swift compiler to be able to reason about how various parts of our code are used, in concurrency the compiler is effectively running a series of algorithms that attempt to determine conclusively that our code is concurrency-safe.

To give you a concrete example, this code generated a warning in Swift 5.9:

import SwiftUI

struct ContentView: View {
    var body: some View {
        Button("Tap Me", action: doWork)
    }

    func doWork() {
        print("Hello")
    }
}

That would throw up the rather unhelpful warning, "Converting function value of type '@MainActor () -> ()' to '() -> Void' loses global actor MainActor".

The problem here is that SwiftUI's Button view doesn't use @MainActor for its action, so Swift was throwing up a warning that we were calling a main acto...

]]>
Build your next website in Swift https://www.hackingwithswift.com/articles/266/build-your-next-website-in-swift https://www.hackingwithswift.com/articles/266/build-your-next-website-in-swift How Swift's result builders can help us write smarter, safer HTML. Sat, 18 May 2024 08:21:37 +0000 Swift's result builders are a powerful language feature that let us create domain-specific languages right inside our Swift code. With a little thinking, this means we can actually create whole websites in Swift, with our code automatically being converted to valid, accessible Swift, and we can even sprinkle in a little SwiftUI magic to complete the effect.

Let's get to it…

Starting from scratch

For over 30 years, HTML has been a great language for describing the structure of web pages.

For example, we can write HTML like this:

<h1>Wise words</h1>
<p>"If you don't take risks, you can't create a future" - <em>Monkey D. Luffy</em> in <a href="https://en-wp.org/wiki/One_Piece">One Piece</a></p>

That has a heading, a paragraph of text with some emphasis, and a link to another page. But, what happens if we forget the closing </em> tag? Without it, web browsers will assume everything that follows should also be emphasized.

That's not what I intended, but it's easy to do because HTML is just a bunch of text.

But even if you write perfect HTML, there are other, bigger problems:

  1. How can you make sure your pages look the same on all browsers?
  2. How can you make your page adapt to different screen sizes, such as iPhone and iPad?
  3. How can you use more advanced UI elements such as dropdown menus, carousels, and accordions?
  4. Most importantly, how can you be sure your site is accessible to everyone?

Ultimately, all these boil down to one huge problem: most people don't have enough time to become experts in Swift and also experts in HTML.

And so I want to suggest that the answer is to not use HTML, or at least not directly. Instead, I would you like to propose that we use Swift to build our websites.

Introducing result builders

Back in 2019 when Apple announced SwiftUI there the usual What's New in Swift presentation. During that talk they showed the following HTML:


<html>
    <head>
        <title>Jess...
]]>
Shipping a visionOS app for launch https://www.hackingwithswift.com/articles/265/shipping-a-visionos-app-for-launch https://www.hackingwithswift.com/articles/265/shipping-a-visionos-app-for-launch The future of audio synthesis is in your hands! Wed, 31 Jan 2024 19:35:12 +0000 We're now just a few days away from the launch of Apple Vision Pro, and like many other developers I've built and shipped a visionOS app ready for launch day.

Doing this took quite a few steps, so I wanted to walk you through the whole process: coming up with an idea, building a prototype, visiting Apple's Vision Pro labs, fixing problems, and more. Hopefully this is useful to anyone else who is thinking about shipping for visionOS!

About the app

The app I built is called Spatial Symphony, and it's a synthesizer controlled by hand movements.

It was born out of a very simple idea to create a theremin for Apple Vision Pro – an instrument that in real life is created by moving your hands in the air, and so seemed perfectly suited to the new hand-tracking APIs that ship with visionOS.

The idea quickly expanded into a general-purpose synth, with controls for waveform, reverb, distortion, chorus, scale snapping, and more, and I ended up shipping 20 synth presets plus a full editor UI.

You can see the app running here:

What powers it all?

Beyond Swift and SwiftUI, Spatial Symphony was made possible by three frameworks.

The first framework is AudioKit, which drives all the synth work, providing all the effects and customizations. This was a massive revelation to me: there are countless thousands of people out there with a hundred times more knowledge about audio engineering than I have, but honestly AudioKit somehow manages to make me look like a pro.

The project – completely open-source, available under the MIT license – provides a wealth of audio power for us mere mortals to lean on, ...

]]>
Take on visionOS at Unwrap Live 2024 https://www.hackingwithswift.com/articles/264/take-on-visionos-at-unwrap-live-2024 https://www.hackingwithswift.com/articles/264/take-on-visionos-at-unwrap-live-2024 The Vision Pro is almost here – are you ready to build? Mon, 08 Jan 2024 13:40:48 +0000 Unwrap Live is back for its second year, this time focusing on building great apps for visionOS.

Once again, it's a full-day, online-only workshop event aimed at intermediate to advanced developers, and everyone who attends will have ample chance to learn new approaches, tackle coding challenges, and of course ask lots of questions.

This year we'll be focusing on three key areas of visionOS APIs:

  • 2D apps built using SwiftUI. This will start small, looking at the least it takes to get your app onto visionOS, but then we'll expand to look at platform-specific adjustments so your apps feel fully at home.
  • 3D apps built using RealityKit and ARKit. Once you're comfortable working in 2D, we'll start to explore 3D content as well – bringing it into existing apps effectively, but also building projects that focus specifically on a great 3D experience.
  • Designing assets with Reality Composer Pro. Apple's new tool for creating content is fantastically powerful, so we'll look at how it can fit into your app development workflow.

The format is the same as last year: live-streamed videos for all attendees where I walk you through specific techniques, backed up by hands-on coding challenges where you need to apply what you've learned – it's the fastest way to get up to speed with building great apps for visionOS.

All sessions take place January 27th, from 9am to 4pm US Eastern time. They will be recorded, and you'll be able to download the videos afterwards.

Tickets cost $100 each, but Hacking with Swift+ subscribers get access free. If you aren't already a Hacking with Swift+ subscriber, you can sign up before the event to get your free ticket – find out more here.

I'm also offering two other ticket types:

  1. A diversity sponsor ticket, which is for folks who already have a ticket and want me to give one ticket away to someone who would otherwise not be able to attend.
  2. ...
]]>
Build your first app with SwiftUI and SwiftData https://www.hackingwithswift.com/articles/263/build-your-first-app-with-swiftui-and-swiftdata https://www.hackingwithswift.com/articles/263/build-your-first-app-with-swiftui-and-swiftdata Learn about queries, models, containers, and more, all while building a real app. Sat, 23 Dec 2023 22:41:18 +0000 In this article we're going to build a complete iOS app using SwiftUI and SwiftData, all while building a real app so you can see all the techniques in action. The app we're building is called FaceFacts, which is designed to help you remember the names, faces, and personal details of folks you meet at your workplace, school, events, and more.

Note: This project requires some Swift and SwiftUI knowledge, but I'll do my best to explain all the SwiftData things along the way. We'll be targeting iOS 17, so you need Xcode 15 or later.

Bringing SwiftData into the project

Start by making a new iOS project called FaceFacts, making sure to choose SwiftUI for the interface. Although we'll be using SwiftData here, please leave the Storage option as None so that Xcode doesn't bring in lots of extra code we don't need.

There are three small steps required to bring SwiftData into an app:

  1. Defining the data you want to work with.
  2. Creating some storage for that data.
  3. Reading the data wherever you need it.

The first thing we'll do is design our data. This will be simple at first, but we'll add more over time. For now we'll store just three pieces of information: their name, their email address, and a free text field where you can add any extra information you want.

So, start by creating a new Swift file called Person.swift, which we'll use to store the SwiftData class describing a single person in our app. This means adding an import for SwiftData, then adding this class:

class Person {
    var name: String
    var emailAddress: String
    var details: String
}

You'll need to create an initializer for that because it's a class, but typing "in" inside the class should prompt Xcode to create one automatically for you:

class Person {
    var name: String
    var emailAddress: String
    var details: String...
]]>
Introducing Inferno: Metal shaders for SwiftUI https://www.hackingwithswift.com/articles/262/introducing-inferno-metal-shaders-for-swiftui https://www.hackingwithswift.com/articles/262/introducing-inferno-metal-shaders-for-swiftui Blazing-fast special effects for your SwiftUI apps. Thu, 16 Nov 2023 12:46:58 +0000 SwiftUI for iOS 17 and macOS Sonoma come with a fantastic new superpower: the ability to transform any SwiftUI view with Metal shaders, all hardware accelerated so complex effects run at lightning fast speeds even on old devices.

I want to help folks get started with Metal, so I've produced two free resources that will help everyone:

Inferno is a project that makes Metal shaders easy for everyone to use, but I've also gone a step further and added comprehensive documentation explaining exactly how each shader works so that others can learn too.

I've also produced a walkthrough video for Inferno so you can get an overview of the project before downloading it.

But there's more: over on Hacking with Swift+ I'm working on a large tutorial series teaching exactly how to build your own shaders, piece by piece, going into lots of detail on the Metal shading language. Part 1 of that series is already available – check it out!

This is all powered by new APIs introduced in iOS 17 and other coordinated releases – we get complete control over how our views are rendered, and now with only a handful of lines of Metal shading language we can produce some really remarkable results.

]]>