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 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.

]]>
I screwed up one key accessibility behavior, and now I'm on a mission to do better https://www.hackingwithswift.com/articles/261/i-screwed-up-one-key-accessibility-behavior-and-now-i-m-on-a-mission-to-do-better https://www.hackingwithswift.com/articles/261/i-screwed-up-one-key-accessibility-behavior-and-now-i-m-on-a-mission-to-do-better Accessibility labels, hints, and grouping are great, but don’t forget to think about Voice Control too. Fri, 23 Jun 2023 09:32:56 +0000 If you’ve followed any of my tutorials, you’ll know I make a point of teaching accessibility to everyone – I want to make sure that whether someone is learning SwiftUI or already has a lot of experience with it, they know that accessibility needs to be baked into their work.

As part of that, I teach five key concepts that – so I believed – helped make sure most apps provided a great accessibility experience out of the box:

  1. Using native controls rather than making your own, including using VStack and HStack in SwiftUI to provide a clear structure for assistive tools to follow.
  2. Adding short descriptions of views using accessibilityLabel(), keeping longer descriptions for accessibilityHint() for users who have that enabled.
  3. Grouping views together using accessibilityElement() so VoiceOver treats them as atomic units.
  4. Marking images as decorative when they shouldn’t be read by VoiceOver.
  5. Using Dynamic Type everywhere, to make sure our interfaces scale smoothly no matter what someone’s settings are.

Those five do help provide a great experience for many people, but while at WWDC23 one of the teams at Apple very gently pointed out that I was missing a key component – and in doing so creating a pretty awful accessibility experience for many people.

So, here’s the sixth item I’m putting on the list of things I’ll be teaching everywhere: using accessibilityInputLabels() to provide custom activation commands for Voice Control.

This modifier accepts an array of localizable strings that can be used by the user to activate a control. You can provide as many as you want, and the system will listen for all of them – it gives the user a little leeway, and hopefully means they never need to use “Show Names” to figure out how to activate something.

You can see the problem, and also how accessibilityInputLabels() solves it, in this code:

NavigationStack {
    List {
        NavigationLink {
            Text("Details about toda...
]]>
What’s new in SwiftUI for iOS 17 https://www.hackingwithswift.com/articles/260/whats-new-in-swiftui-for-ios-17 https://www.hackingwithswift.com/articles/260/whats-new-in-swiftui-for-ios-17 This is another huge year of updates, delivering many highly requested features such as advanced scroll view effects, container relative sizing, and even Metal shaders. Fri, 16 Jun 2023 08:26:34 +0000 SwiftUI continues to evolve at a rapid pace, and this year has seen a huge number of improvements to scroll views, fun new SF Symbols effects, advanced support for Metal shaders, and more.

Some of these are things I’ve asked for personally, including the ability to add Metal shaders, making Color work better with Codable, adding a completion closure for animations, allowing us to animate gradients, and being able to selectively round corners of a rectangle – I’ve closed at least a dozen feedbacks just from beta 1!

Scroll view improvements

Drawing and animation improvements

]]>
Hacking with Swift Live 2023 https://www.hackingwithswift.com/articles/259/hacking-with-swift-live-2023 https://www.hackingwithswift.com/articles/259/hacking-with-swift-live-2023 The full schedule is here – it’s almost time to get coding! Thu, 15 Jun 2023 13:27:29 +0000 Now that WWDC23 is over I’m really excited to announce the full schedule for Hacking with Swift Live 2023. The short version is that we’ll be covering the key new features in Swift, then exploring all the major changes for SwiftUI, and finally going hard on SwiftData – it’s going to be a really packed event!

As a reminder, Hacking with Swift Live is a charity-focused event where all ticket and sponsor revenue goes to help folks experiencing homelessness. So, you get to learn Swift, make new friends, and also help people in need!

Get your Hacking with Swift Live ticket here

Schedule

Hacking with Swift Live takes place June 26th-27th, from 9am to 4pm US Eastern time. I’ll walk you through new features, then give you chance to ask questions, and try challenges yourself – everyone will have lots of time to experiment with the code and really get to grips with it!

On day one we’ll be exploring the key changes to Swift this year, focusing specifically on the things that are likely to help make code easier to write or maintain. We’ll then dive straight into the many and varied SwiftUI improvements this year, building a real project that ties them all together as you learn.

On day two we change tack and move over exclusively to SwiftData. This is a huge new framework that unlocks almost all of Core Data’s power with almost none of Core Data’s complexity – it will completely change the way we write apps. We’ll be looking at this topic from a number of perspectives, including:

  • The basics of getting started
  • Advanced uses, including data migrations and shared storage
  • Upgrading existing Core Data apps
  • Architectural issues, including using MVVM

If we still have time left over we’ll also explore a little of what visionOS development looks like,...

]]>
What’s new in Swift 5.9? https://www.hackingwithswift.com/articles/258/whats-new-in-swift-5-9 https://www.hackingwithswift.com/articles/258/whats-new-in-swift-5-9 Macros, if and switch expressions, noncopyable types, and more! Sat, 03 Jun 2023 04:52:49 +0000 Although Swift 6 is looming on the horizon, the 5.x releases still have a lot to give – simpler ways to use if and switch, macros, noncopyable types, custom actor executors, and more are all coming in Swift 5.9, making yet another mammoth release.

In this article I’ll walk you through the most important changes in this release, providing code examples and explanations so you can try it all yourself. You’ll need the latest Swift 5.9 toolchain installed in Xcode 14, or the Xcode 15 beta.

if and switch expressions

SE-0380 adds the ability for us to use if and switch as expressions in several situations. This produces syntax that will be a little surprising at first, but overall it does help reduce a little extra syntax in the language.

As a simple example, we could set a variable to either “Pass” or “Fail” depending on a condition like this:

let score = 800
let simpleResult = if score > 500 { "Pass" } else { "Fail" }
print(simpleResult)

Or we could use a switch expression to get a wider range of values like this:

let complexResult = switch score {
    case 0...300: "Fail"
    case 301...500: "Pass"
    case 501...800: "Merit"
    default: "Distinction"
}

print(complexResult)

You don’t need to assign the result somewhere in order to use this new expression syntax, and in fact it combines beautifully with SE-0255 from Swift 5.1 that allows us to omit the return keyword in single expression functions that return a value.

So, because both if and switch can now both be used as expressions, we can write a function like this one without using return in all four possible cases:

func rating(for score: Int) -> String {
    switch score {
    case 0...300: "Fail"
    case 301...500: "Pass"
    case 50...
]]>
Now available to pre-order: Swift Against Humanity https://www.hackingwithswift.com/articles/257/now-available-to-pre-order-swift-against-humanity https://www.hackingwithswift.com/articles/257/now-available-to-pre-order-swift-against-humanity Try the all-new card game that’s taking the Swift community by storm! Sat, 01 Apr 2023 11:10:47 +0000 So you think you know Swift? Think again! Fresh from the success of our audiobook launch, Laboratoires TwoStraws is back with an all-new card game that will finally give you something to do while waiting for Xcode to finish indexing.

It’s called Swift Against Humanity, and the rules are both dazzlingly simple and also surprisingly similar to some other games you might have previously heard of: one player places a black card on the table that contains a question or part of a sentence, and all other players play one white card they think best completes it. The first player then shuffles the white cards, reads them out, then picks a winner – it’s literally minutes of fun.

Black card: The secret to making your Swift code run fast is blank. White cards: Craig Federighi’s hair gel, some tasteful WWDC-themed cosplay, Paul Hudson’s dog army, two dozen force unwrapped optionals.

Pre-orders for Swift Against Humanity start tomorrow, with the first deliveries going out in the next week or so. Plus, we’re pleased to announce three incredible editions:

  • Swift Against Humanity Standard Edition: for the language purists out there.
  • Swift Against Humanity Enterprise Edition: for all you folks busy building with Swift Enterprise Edition.
  • Humanity Swift Concurrency Against Edition: for all developers who just love adding concurrency in places it really doesn’t belong.

Black card: What’s the most difficult thing about learning Swift? White cards: Always googling Swift and getting Taylor Swift results, converting a string to an array then back to a string then questioning your life choices, desperately trying to remember which button does what in Interface Builder, accidentally creating a black hole with Xcode’s Auto Layout constraints.

Swift Against Humanity was developed in conjunction with legendary game designer [Daniel Leivers](https://twitter.com/s...

]]>
What's new in Swift 5.8 https://www.hackingwithswift.com/articles/256/whats-new-in-swift-5-8 https://www.hackingwithswift.com/articles/256/whats-new-in-swift-5-8 Back-deployable APIs, more implicit self upgrades, improved result builders, and more! Wed, 08 Mar 2023 10:56:01 +0000 Although many major Swift changes are currently percolating through Swift Evolution, Swift 5.8 itself is more of a clean up release: there are additions, yes, but there are more improvements that refine functionality that was already in widespread use. Hopefully this should make adoption much easier, particularly after the mammoth set of changes that were squeezed into Swift 5.7!

In this article I’m going to walk you through the most important changes this time around, providing code examples and explanations so you can try it all yourself. You’ll need Xcode 14.3 or later to use this, although some changes require a specific compiler flag before Swift 6 finally happens.

Lift all limitations on variables in result builders

SE-0373 relaxes some of the restrictions on variables when used inside result builders, allowing us to write code that would previously have been disallowed by the compiler.

For example, in Swift 5.8 we can use lazy variables directly inside result builders, like so:

struct ContentView: View {
    var body: some View {
        VStack {
            lazy var user = fetchUsername()
            Text("Hello, \(user).")
        }
        .padding()
    }

    func fetchUsername() -> String {
        "@twostraws"
    }
}

That shows the concept, but doesn’t provide any benefit because the lazy variable is always used – there’s no difference between using lazy var and let in that code. To see where it’s actually useful takes a longer code example, like this one:

// The user is an active subscriber, not an active subscriber, or we don't know their status yet.
enum UserState {
 ...
]]>
SwiftUI by Example: Now updated for iOS 16 https://www.hackingwithswift.com/articles/255/swiftui-by-example-now-updated-for-ios-16 https://www.hackingwithswift.com/articles/255/swiftui-by-example-now-updated-for-ios-16 100 new Xcode projects to download and try. Thu, 01 Dec 2022 21:41:36 +0000 This week I published the biggest ever update to SwiftUI by Example, adding lots of new sample code plus 100 new Xcode projects to download.

The initial goal was to update the book for iOS 16, but I ended up going back and adding coverage of functionality introduced in iOS 15 and even 14 – this update is just packed with extra code, improved examples, and more.

To save you having to dig through and look for what’s new, here’s a list of the biggest changes:

]]>
WWDC22: Wrap up and recommended talks https://www.hackingwithswift.com/articles/254/wwdc22-wrap-up-and-recommended-talks https://www.hackingwithswift.com/articles/254/wwdc22-wrap-up-and-recommended-talks Together again for lots of best practices, backed up with a sprinkling of big new features. Thu, 23 Jun 2022 22:27:27 +0000 This year was a WWDC like we’ve never seen before, with 1000 developers being invited into Apple’s home in Cupertino to share their excitement, meet engineers, and even have tours around Apple Park.

Of course, the conference was also available remotely, with digital lounges returning, labs available for everyone, and lots of community events. In this article I’ll go over how I think the event went, pick out the talks I enjoyed the most and would recommend you watch, highlight some of my favorite community events, and put forward a handful of suggestions for how WWDC23 might look.

Code one, code all

After two years of being fully remote, this year Apple took a new approach of having a single-day event to kick things off, with the rest of the week being fully remote. You might think that would have dissuaded folks from wanting to attend, I can assure you dear reader that it did not: the in-person event was packed, and I lost track of how many people I met who came to town for the week without getting into the Apple special event.

Even from the first time folks agreed to meet up – at a community drinks event in San Jose – you could feel the incredible excitement once again, as if 2+ years of absence never happened. Folks were just happy to be able to meet their friends from around the world again, to chat about the projects they were working on, and catch up on lost time.

Of course, Apple themselves contributed greatly to the excitement by inviting developers to tour their new Developer Center just next to Apple Park and the visitor center.

<...

]]>
How to use inner shadows to simulate depth with SwiftUI and Core Motion https://www.hackingwithswift.com/articles/253/how-to-use-inner-shadows-to-simulate-depth-with-swiftui-and-core-motion https://www.hackingwithswift.com/articles/253/how-to-use-inner-shadows-to-simulate-depth-with-swiftui-and-core-motion Tilt your device to move the shadow, as if there’s a light source shining from above. Thu, 23 Jun 2022 16:02:20 +0000 SwiftUI comes with a whole range of advanced effects we can use to customize the way our content is drawn, and from iOS 16 onwards we gain another important option: the ability to create inner shadows. Inner shadows create the illusion that some shape or text is cut out, placing the shadows on the area inside the shape as if an overhead light source were in place.

That alone is nice enough, but with a tiny bit of Core Motion work we can make our shadow move as the user’s device is tilted, as if there really were a fixed light overhead. We can then go even further to add some 3D rotation into the shape – you’ll see how that’s only a small step further.

I think you’ll be surprised how easy this effect is, but please do read to the end before you use this code in your own projects – there are some important tips I want you to be aware of!

Tracking Core Motion

Our first step is to create an observable object that can watch for device motion changes, and send them off to any views that might be interested in it. This can be done using CMMotionManager, which we get through the Core Motion framework, so start by adding an import for that:

import CoreMotion

Now we’re going to create a new MotionManager class that conforms to ObservableObject. This needs to have three properties:

  • The CMMotionManager that is currently monitoring movement. This can be a private constant because it’s only for internal use.
  • The amount of X movement we want to apply.
  • The amount of Y movement we want to apply.

Both those last two should trigger change notifications when they are modified, so we’ll mark them with @Published.

So, add this new class now:

class MotionManager: ObservableObject {
    private let motionManager = CMMotionManager()
    @Published var x = 0.0
    @Published var y = 0.0
}

In my example code, we want to start reading motion data as soon as this manager is started, so we’ll use the ini...

]]>
8 Things I Wish I Knew When I Started Programming https://www.hackingwithswift.com/articles/252/8-things-i-wish-i-knew-when-i-started-programming https://www.hackingwithswift.com/articles/252/8-things-i-wish-i-knew-when-i-started-programming I don’t have a time machine, but you can learn from my mistakes! Fri, 17 Jun 2022 10:28:48 +0000 I've been programming for over 25 years now, and today I love it just as much if not more than when I started. But looking back on me as a kid just starting out, I really had no idea what I was doing, so if I were able to build a time machine today there are eight things I would tell a younger version of myself.

Obviously I don’t have a time machine, but that’s okay because you’re here, and if you’re just starting out with your programming career I can guarantee these things will prove useful to you too.

Before I start, I want to say the most important thing of all: young me was extremely impatient – I always, always wanted to jump ahead onto the next thing, without really taking the time to listen to advice. This caused huge problems in the first 10 years of my career, so if you’re already thinking “I’m bored already – I need to jump over to TikTok to watch some comedy fail videos,” maybe you’re on that same track. Trust me, it doesn’t end well.

Okay, you’re still here, so I guess that’s the first test passed!

So let’s get right into it – you can watch the video below, or keep on scrolling for the text version.

1. Technology will change – don’t get stuck on stuff!

Seriously, no matter how much you love Thing X or language Y, it will evolve or go away entirely. I learned Java and C++ at college, I did PHP, JavaScript, and Visual Basic after graduating, then wrote software for Windows Mobile and Xbox 360, built iPhone apps using Objective-C, and more, and almost all those technologies have evolved beyond recognition or are more or less dead now.

And that’s okay – in fact, it’s kind of how our industry works. But it means I cringe super hard when I see language fanatics who insist JavaScript is the worst, or equally those who think JavaScript can do everything under the sun. There really is a reason there are lots of languages out there, and it isn’t because there are a whole bunch of bored langua...

]]>
What’s new in Xcode 14? https://www.hackingwithswift.com/articles/251/whats-new-in-xcode-14 https://www.hackingwithswift.com/articles/251/whats-new-in-xcode-14 Source editing just keeps getting better and better Tue, 14 Jun 2022 22:20:01 +0000 While Xcode 13 added some major features such as Vim mode, version control, DocC, and Xcode Cloud, Xcode 14 opts to return to the basics and polish some core features that make the whole experience faster and smarter to use.

In this article I want to walk through some of the many improvements introduced in Xcode 14, many of which weren’t even mentioned by Apple, as well as a few things that I’m less convinced about. Let’s get straight into it…

Source editor improvements

This year is another bumper year for Xcode’s source editor – it just keeps getting smarter and smarter in ways that I hadn’t even imagined were possible.

As an example, let’s say we had a Player struct such as this one:

struct Player: Identifiable {
    var id = UUID()
    var name: String
    var score = 0
}

Swift will automatically generate a memberwise initializer for that because it’s a struct, but it’s common to want to customize that initializer. So, Xcode 14 will now autocomplete a memberwise initializer for us – just start typing init inside the struct and it will complete to this:

init(id: UUID = UUID(), name: String, score: Int = 0) {
    self.id = id
    self.name = name
    self.score = score
}

So, now we might say that the score must always be at least 0:

self.score = max(0, score)

This even works with Codable – if you add a Codable conformance to the struct then start typing encode inside the struct, it will autocomplete this:

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(self.id, forKey: .id)
    try container.encode(self.name, forKey: .name)
    try container.encode(self.score, forKey: .score)
}

This relieves a lot of boilerplate for those times when you want to make one small change to your Codable conformance.

Moving on, we might create an array of users...

]]>
What’s new in SwiftUI for iOS 16 https://www.hackingwithswift.com/articles/250/whats-new-in-swiftui-for-ios-16 https://www.hackingwithswift.com/articles/250/whats-new-in-swiftui-for-ios-16 Bottom sheets, fixed grids, and a wholly new way to handle navigation Tue, 07 Jun 2022 09:27:43 +0000 WWDC was back in person for the first time since 2019, and once again was absolutely packed with new features for app developers – huge new features in Swift 5.7, new APIs such as WeatherKit and Swift Charts, and, of course, lots of goodies for SwiftUI developers.

Please keep in mind that these changes are very new – I'm pushing it as hard as I can, experimenting, refining, sharing, and learning all at the same time. If you have any feedback, please tweet me @twostraws. I’ll be adding more soon!

You can watch the video below, or scroll down for links to articles.

The big stuff

Additional: It’s now possible to create multi-column tables on iOS and iPadOS, but I think it’s a bit buggy in beta 1. I’ve documented it here in case you’d like to try it yourself: How to create multi-column lists using Table.

More welcome improvements

]]>
What’s new in Swift 5.7 https://www.hackingwithswift.com/articles/249/whats-new-in-swift-5-7 https://www.hackingwithswift.com/articles/249/whats-new-in-swift-5-7 Or as I’ve started calling it, what isn’t new in Swift 5.7? Mon, 06 Jun 2022 16:35:32 +0000 Swift 5.7 introduces another gigantic collection of changes and improvements to the language, including power features such as regular expressions, quality of life improvements like the if let shorthand syntax, and a great deal of consistency clean ups around the any and some keywords.

In this article I want to introduce you to the major changes, providing some hands-on examples along the way so you can see for yourself what’s changing. Many of these changes are complex, and many of them are also interlinked. I’ve done my best to break things down into a sensible order and provide hands-on explanations, but it took a huge amount of work so don’t be surprised to spot mistakes – if you find any, please send me a tweet and I’ll get it fixed!

  • I’m grateful to Holly Borla for taking the time to answer questions from me regarding the new generics proposals – if any mistakes crept through, they are mine and not hers.

  • Tip: You can also download this as an Xcode playground if you want to try the code samples yourself.

if let shorthand for unwrapping optionals

SE-0345 introduces new shorthand syntax for unwrapping optionals into shadowed variables of the same name using if let and guard let. This means we can now write code like this:

var name: String? = "Linda"

if let name {
    print("Hello, \(name)!")
}

Whereas previously we would have written code more like this:

if let name = name {
    print("Hello, \(name)!")
}

if let unwrappedName = name {
    print("Hello, \(unwrappedName)!")
}        

This change doesn’t extend to properties inside objects, which means code like this will not work:

struct User {
    var name: String
}

let user: User? = User(name: "Linda")

...

]]>
Swift Core Team to Swift bloggers: “Please, for the love of all things holy, find a different color than orange” https://www.hackingwithswift.com/articles/248/swift-core-team-to-swift-bloggers-please-for-the-love-of-all-things-holy-find-a-different-color-than-orange https://www.hackingwithswift.com/articles/248/swift-core-team-to-swift-bloggers-please-for-the-love-of-all-things-holy-find-a-different-color-than-orange “Surely some of you can pick a different color? Please?” Fri, 01 Apr 2022 08:52:19 +0000 Early this morning Apple published an unprecedented tech note aimed at Swift bloggers around the world, pleading them with them to be more creative with their color choices.

Ed Kermenek, the Swift project lead, had this to say: “Look, we get it: we chose orange for the logo way back in 2014, and that obviously led some people to think of it as the Official Swift Color or something, but come on – surely some of you can pick a different color? Please?”

Taking a break from his work on Swift Enterprise Edition, Jay Gorff took a more hardline stance: “Frankly, I never want to see the color orange again. I can’t eat oranges, carrots, or pumpkins any more, and you jerks have completely ruined Cheetos for me too. Wait… it’s almost sunset, and I can already feel my stomach getting into a knot thinking of the colors – do you see what you monsters have done?!”

Bolly Horla, who is somehow still not on the Swift Core Team despite being more than qualified, pulled out a tabbed binder of colors the team considered more appropriate. “How about a nice blue,” she said, “or some shade of chartreuse? Ooh, why not try plaid? I bet we could solve this with some kind of @Color property wrapper…”

Steve Prestoff, currently working to make Swift compile faster, took a break to add: “Chickens.” We’re not sure if that means he likes the color of chickens, the taste of chickens, or something else, but at least he’s not on a hor— oh, wait, he’s back on a horse again.

]]>
What’s new in Swift 5.6? https://www.hackingwithswift.com/articles/247/whats-new-in-swift-5-6 https://www.hackingwithswift.com/articles/247/whats-new-in-swift-5-6 Type placeholders, unavailable checks, Codable improvements, and more. Wed, 02 Mar 2022 14:37:06 +0000 Swift 5.6 introduces another barrage of new features to the language, while refining others as we get closer to Swift 6. In this article I want to introduce you to the major changes, providing some hands-on examples along the way so you can see for yourself what’s changing.

Introduce existential any

SE-0335 introduces a new any keyword to mark existential types, and although that might sound esoteric please don’t skip ahead: this one is a big change, and is likely to break a lot of Swift code in future versions.

Protocols allow us to specify a set of requirements that conforming types must adhere to, such as methods they must implement. So, we often write code like this:

protocol Vehicle {
    func travel(to destination: String)
}

struct Car: Vehicle {
    func travel(to destination: String) {
        print("I'm driving to \(destination)")
    }
}

let vehicle = Car()
vehicle.travel(to: "London")

It’s also possible to use protocols as generic type constraints in functions, meaning that we write code that can work with any kind of data that conforms to a particular protocol. For example, this will work with any kind of type that conforms to Vehicle:

func travel<T: Vehicle>(to destinations: [String], using vehicle: T) {
    for destination in destinations {
        vehicle.travel(to: destination)
    }
}

travel(to: ["London", "Amarillo"], using: vehicle)

When that code compiles, Swift can see we’re calling travel() with a Car instance and so it is able to create optimized code to call the travel() function directly – a process known as static dispatch.

All this matters because there is a second way to use protocols, and ...

]]>
Special Effects with SwiftUI https://www.hackingwithswift.com/articles/246/special-effects-with-swiftui https://www.hackingwithswift.com/articles/246/special-effects-with-swiftui TimelineView, Canvas, particles, and… AirPods?! Wed, 26 Jan 2022 16:30:52 +0000 Everyone knows SwiftUI does a great job of creating standard system layouts with lists, buttons, navigation views, and more, and while it’s really useful I doubt most people would call it fun.

So, in this article I’m going to show you how to use SwiftUI to build something fun, beautiful, and unlike anything you’ve seen before. You’ll need at least Xcode 13 and iOS 15 or later, but you also need to download a single image from my site from here: https://hws.dev/spark.zip.

Getting started

At the core of our little experiment is a particle system, which is commonly used in games to create effects like fire, smoke, rain, and more. We’re going to start simple and work our way up – it’s pretty amazing how fast we can move with SwiftUI.

The first step is easy: create a new iOS project using the App template, making sure to choose SwiftUI for your interface. You should already have downloaded the spark.zip file from my site, which contains a single image. I’d like you to drag that into your project’s asset catalog, so we have an image to use for all our particles.

Next, I’d like to think about what it means to store one particle in a particle system – what does one rain drop need to store, or one snowflake? There are all sorts of values we could store, but we need only three: the X and Y coordinates for the particle, plus the date it was created.

In addition to that, I’m also going to add a conformance to the Hashable protocol, so we can add our particles to a set and remove them easily.

Create a new Swift file called Particle.swift, and give it this code:

struct Particle: Hashable {
    let x: Double
    let y: Double
    let creationDate = Date.now.timeIntervalSinceReferenceDate
}

So, that stores a single particle in our particle system – that’s one drop of rain, one spark from a fire, one piece of fairy dust, or whatever kind of particles you’re working with.

One level up from that is the pa...

]]>