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

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

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

]]>