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

]]>
How to build your first SwiftUI app with Swift Playgrounds https://www.hackingwithswift.com/articles/245/build-your-first-swiftui-app-with-swift-playgrounds https://www.hackingwithswift.com/articles/245/build-your-first-swiftui-app-with-swift-playgrounds Learn the basics of SwiftUI and build a real app along the way. Wed, 15 Dec 2021 22:25:43 +0000 Swift Playgrounds lets you build a complete iOS app from scratch, right on your iPad. You get to draw upon Apple’s powerful SwiftUI framework, you can pull in libraries that other people have written, and if you want you can even move your project over to your Mac and continue it in Xcode, Apple’s full-blown code editor.

In this tutorial I’m going to walk you through building your very first app using Swift Playgrounds for iPad, where you’ll be able to show pictures of your friends and family, and tapping one of them will play a sound – it’s just for fun, but you’ll learn a lot along the way, and also make use of other built-in software on your iPad. This tutorial is aimed at beginners, so you don’t need any prior Swift experience.

To follow along you’ll need to install Playgrounds from the App Store, but that’s it – you don’t need Xcode or even a Mac. In case you were curious, I’m using Apple’s Magic Keyboard with an iPad Pro, running iOS 15.2.

First steps

To get started, press the “App” button under “Get a Playground” to create a new project. This will be called My App by default, and it will be given a random icon – I’ll show you how to change those later.

Go ahead and tap your new playground to open it for editing, and you’ll see Playgrounds splits into two parts: on the left is some simple Swift code to get us started, and on the right is a live preview that shows your actual code running.

I expect the starter code will change over time, but that’s okay because I want you to delete almost all of it – leave only this behind:

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
    }
}

As you delete parts, you’ll see the preview on the right change immediately – it really is live, and later on you’ll see it’s interactive too.

Our remaining code does several things:

  1. It tells Swift to bring in the SwiftUI fra...
]]>
Swift Playgrounds 4 is here, and it’s a thing of beauty https://www.hackingwithswift.com/articles/244/swift-playgrounds-4 https://www.hackingwithswift.com/articles/244/swift-playgrounds-4 Building complete apps on your iPad is now possible. Tue, 14 Dec 2021 16:41:59 +0000 At WWDC21 Apple revealed that Swift Playgrounds was getting a huge upgrade to allow us to build complete SwiftUI apps, including not only a live preview of our work but also the ability to ship direct to the App Store.

Well, Playgrounds 4 just arrived and I’m really pleased to say they nailed it: this is a landmark release for Swift Playgrounds, introducing instant interactive previews, lightning-fast code completion, complete integration for Swift Package Manager repositories, and so much more…

In case you’re short on time, here’s the TL;DR:

  • Yes, you can now build SwiftUI apps right on your iPad.
  • Yes, you can use also UIKit if you prefer.
  • Yes, you can ship your apps to the App Store straight from your iPad.
  • Yes, it supports Swift Package Manager packages from GitHub.
  • Yes, you get the fantastic new code completion, just like with Xcode.
  • Yes, it ships with Swift 5.5 and all the concurrency awesomeness that entails.

Okay, let's explore the app…

Building iPad apps on your iPad

Folks have been requesting Xcode for iPad for some time, but that would have required a pretty epic effort – does that mean all of Interface Builder? All the Objective-C and C++ support? Or – *cue silent screaming* – Info.plist files?

Swift Playgrounds has chosen a different way: rather than trying to recreate all of Xcode on iPadOS, it instead aims to produce “Diet Xcode” – by which I mean “slimmer, faster, and streamlined” and not “why does my drink taste weird.” That means we get Xcode-style code completion that appears instantly, we get Xcode-style instant SwiftUI previews as we type, we get Xcode-style imports for SPM packages through Git, and much more.

![Swift Playgrounds 4 showing inline code completion.](/uploads/arti...

]]>
Write better code with Swift Algorithms https://www.hackingwithswift.com/articles/243/write-better-code-with-swift-algorithms https://www.hackingwithswift.com/articles/243/write-better-code-with-swift-algorithms Write faster, simpler, safer Swift code with this powerful open-source package. Thu, 02 Dec 2021 22:55:29 +0000 Swift’s standard library is packed with types and functions to solve the most common code problems quickly and efficiently, but it doesn’t cover everything. So, for more advanced needs we need to turn to Swift Algorithms: Apple’s open source package of sequence and collection algorithms, tuned for maximum performance and flexibility.

With the 2021 Advent of Code happening right now, this is a great time to see how Swift Algorithms can help you write faster, simpler, and safer code. There’s functionality for uniquing sequences, chunking them, selecting several random elements, compacting them, and more, and most return new, highly-optimized sequence types that are more efficient than flattening everything to a simple array.

Plus, Apple has said that Swift Algorithms provides an opportunity to explore algorithmic problems and solutions before graduating them into the main standard library – you get better code today, and a look in at what the standard library might become in the future. What’s not to like?

Best of all, adding Swift Algorithms to your Xcode project takes only a few moments: go to the File menu, choose Add Packages, select Apple Swift Packages, then select “swift-algorithms” and click Add Package. Now just add import Algorithms to your code, and you’re all set!

In this article I’m going to pick out just a little of what Swift Algorithms can already do, focusing on nine particular algorithms I find most useful. Let’s get to it…

  • Prefer to watch this as a video? Here you go!

Chaining sequences

If you have two arrays of data and want to loop over them both, you might write something like this:

let names1 = ["Jane", "Elizabeth", "Mary", "Kitty"]
let names2 = ["Daphne", "Eloise", "Francesca", "Hyacinth"]

for name in names1 + names2 {
    print(name)
}

That will print all eight names, but in...

]]>
Learn essential Swift in one hour https://www.hackingwithswift.com/articles/242/learn-essential-swift-in-one-hour https://www.hackingwithswift.com/articles/242/learn-essential-swift-in-one-hour Here’s the least you need to know to get started with Swift. Fri, 15 Oct 2021 21:23:01 +0000 In this article I’m going to introduce you to the fundamentals of the Swift programming language in about one hour.

This article is aimed at two kinds of people: folks who have completed the introduction to my 100 Days of SwiftUI course and are looking for a quick review, and folks who are experienced with other languages and want to transfer their skills over to Swift.

We’re going to move fast because this is designed to be a primer – if you find yourself struggling to understand something, visit the 100 Days of SwiftUI to complete the longer, more detailed introduction there.

Let’s get to it!

Creating constants and variables

Swift can create constants and variables, but constants are generally preferable.

Use this to create then change a variable string:

var name = "Ted"
name = "Rebecca"

If you don’t want to change a value, use a constant instead:

let user = "Daphne"

The print() function is helpful for learning and debugging, and shows some information about a variable:

print(user)

Strings

Swift’s strings start and end with double quotes:

let actor = "Tom Cruise"

And they work great with emoji too:

let actor = "Tom Cruise 🏃‍♂️"

If you want double quotes inside your string, place a backslash before them:

let quote = "He tapped a sign saying \"Believe\" and walked away."

If you want a string that spans multiple lines, start and end with three double quotes, like this:

let movie = """
A day in
the life of an
Apple engineer
"""

Swift provides many useful properties and methods for strings, including .count to read how many letters it has:

print(actor.count)

There are also hasPrefix() and hasSuffix(), which lets us know whether a string starts or ends with specific letters:

print(quote.hasPrefix("He"))
print(quote.hasSuffix("Away."))

Important: Strings are case-sensitive in Swift, so ...

]]>