![Paul Hudson](/img/default-banner.jpg)
- 1 375
- 10 408 490
Paul Hudson
United Kingdom
Приєднався 9 лют 2014
I'm a full-time Swift author and speaker, and I run Hacking with Swift - the world's largest site dedicated to teaching developers how to build apps with Swift and SwiftUI. I've written books about iOS, macOS, watchOS, and much more - I enjoy hacking around with Swift regardless of the platform, and love passing on what I learned to others.
For more information you can visit my site at hackingwithswift.com, or follow me on Twitter @twostraws.
For more information you can visit my site at hackingwithswift.com, or follow me on Twitter @twostraws.
Build your next website in Swift
Swift's result builders let us create domain-specific languages right inside our Swift code, and with a little thinking that means we can actually build whole websites in Swift - and even use similar syntax to SwiftUI!
Get Ignite here: github.com/twostraws/Ignite
Get Ignite here: github.com/twostraws/Ignite
Переглядів: 38 458
Відео
What it's like attending WWDC in Cupertino
Переглядів 8 тис.4 місяці тому
At WWDC23 I recorded a lots of videos as I met friends, visited Apple Park, attended community events, and more, so now you can see exactly what it's like attending WWDC in person. So, if you're in town for WWDC this year, hopefully you can come prepared! 00:00 Introduction 00:47 Getting there 01:22 The lead up 03:42 Sunday before the event 11:46 Special event at Apple Park 24:12 Tuesday at App...
Hiding and grouping accessibility data - Accessibility SwiftUI Tutorial 2/7
Переглядів 8124 місяці тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 15: Introduction: www.hackingwithswift.com/books/ios-swiftui/accessibility-introduction 1. Identifying views with useful labels: ua-cam.com/video/bAM_ybHPcRs/v-deo.html 2. Hiding and grouping accessibility data: This video 3. Reading the value of controls: ua-cam.com/video/SlCBMdPfWNc/v-deo.html 4....
Using generics to load any kind of Codable data - Moonshot SwiftUI Tutorial 7/11
Переглядів 1,5 тис.4 місяці тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 8: Introduction: www.hackingwithswift.com/books/ios-swiftui/moonshot-introduction 1. Resizing images to fit the screen using GeometryReader: ua-cam.com/video/Zzx9JgMNzkM/v-deo.html 2. How ScrollView lets us work with scrolling data: ua-cam.com/video/GWivGqus6hE/v-deo.html 3. Pushing new views onto ...
Loading a specific kind of Codable data - Moonshot SwiftUI Tutorial 6/11
Переглядів 8304 місяці тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 8: Introduction: www.hackingwithswift.com/books/ios-swiftui/moonshot-introduction 1. Resizing images to fit the screen using GeometryReader: ua-cam.com/video/Zzx9JgMNzkM/v-deo.html 2. How ScrollView lets us work with scrolling data: ua-cam.com/video/GWivGqus6hE/v-deo.html 3. Pushing new views onto ...
Letting the user mark favorites - SnowSeeker SwiftUI Tutorial 12/12
Переглядів 1,1 тис.5 місяців тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 19: Introduction: www.hackingwithswift.com/books/ios-swiftui/snowseeker-introduction 1. Working with two side by side views in SwiftUI: ua-cam.com/video/vdI0ZpJXcHk/v-deo.html 2. Using alert() and sheet() with optionals: ua-cam.com/video/QKUBGEMcbAY/v-deo.html 3. Using groups as transparent layout ...
Binding an alert to an optional string - SnowSeeker SwiftUI Tutorial 11/12
Переглядів 5375 місяців тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 19: Introduction: www.hackingwithswift.com/books/ios-swiftui/snowseeker-introduction 1. Working with two side by side views in SwiftUI: ua-cam.com/video/vdI0ZpJXcHk/v-deo.html 2. Using alert() and sheet() with optionals: ua-cam.com/video/QKUBGEMcbAY/v-deo.html 3. Using groups as transparent layout ...
Changing a view’s layout in response to size classes - SnowSeeker SwiftUI Tutorial 10/12
Переглядів 7185 місяців тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 19: Introduction: www.hackingwithswift.com/books/ios-swiftui/snowseeker-introduction 1. Working with two side by side views in SwiftUI: ua-cam.com/video/vdI0ZpJXcHk/v-deo.html 2. Using alert() and sheet() with optionals: ua-cam.com/video/QKUBGEMcbAY/v-deo.html 3. Using groups as transparent layout ...
Searching for data in a List - SnowSeeker SwiftUI Tutorial 9/12
Переглядів 5895 місяців тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 19: Introduction: www.hackingwithswift.com/books/ios-swiftui/snowseeker-introduction 1. Working with two side by side views in SwiftUI: ua-cam.com/video/vdI0ZpJXcHk/v-deo.html 2. Using alert() and sheet() with optionals: ua-cam.com/video/QKUBGEMcbAY/v-deo.html 3. Using groups as transparent layout ...
Using groups as transparent layout containers - SnowSeeker SwiftUI Tutorial 3/12
Переглядів 1,2 тис.5 місяців тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 19: Introduction: www.hackingwithswift.com/books/ios-swiftui/snowseeker-introduction 1. Working with two side by side views in SwiftUI: ua-cam.com/video/vdI0ZpJXcHk/v-deo.html 2. Using alert() and sheet() with optionals: ua-cam.com/video/QKUBGEMcbAY/v-deo.html 3. Using groups as transparent layout ...
Creating a detail view for resorts - SnowSeeker SwiftUI Tutorial 8/12
Переглядів 7055 місяців тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 19: Introduction: www.hackingwithswift.com/books/ios-swiftui/snowseeker-introduction 1. Working with two side by side views in SwiftUI: ua-cam.com/video/vdI0ZpJXcHk/v-deo.html 2. Using alert() and sheet() with optionals: ua-cam.com/video/QKUBGEMcbAY/v-deo.html 3. Using groups as transparent layout ...
Building a primary list of items - SnowSeeker SwiftUI Tutorial 6/12
Переглядів 6845 місяців тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 19: Introduction: www.hackingwithswift.com/books/ios-swiftui/snowseeker-introduction 1. Working with two side by side views in SwiftUI: ua-cam.com/video/vdI0ZpJXcHk/v-deo.html 2. Using alert() and sheet() with optionals: ua-cam.com/video/QKUBGEMcbAY/v-deo.html 3. Using groups as transparent layout ...
Sharing @Observable objects through SwiftUI's environment - SnowSeeker SwiftUI Tutorial 5/12
Переглядів 9295 місяців тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 19: Introduction: www.hackingwithswift.com/books/ios-swiftui/snowseeker-introduction 1. Working with two side by side views in SwiftUI: ua-cam.com/video/vdI0ZpJXcHk/v-deo.html 2. Using alert() and sheet() with optionals: ua-cam.com/video/QKUBGEMcbAY/v-deo.html 3. Using groups as transparent layout ...
Using alert() and sheet() with optionals - SnowSeeker SwiftUI Tutorial 2/12
Переглядів 5945 місяців тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 19: Introduction: www.hackingwithswift.com/books/ios-swiftui/snowseeker-introduction 1. Working with two side by side views in SwiftUI: ua-cam.com/video/vdI0ZpJXcHk/v-deo.html 2. Using alert() and sheet() with optionals: This video 3. Using groups as transparent layout containers: ua-cam.com/video/...
Making a SwiftUI view searchable - SnowSeeker SwiftUI Tutorial 4/12
Переглядів 5385 місяців тому
Download the completed project here: github.com/twostraws/hackingwithswift Other parts in Project 19: Introduction: www.hackingwithswift.com/books/ios-swiftui/snowseeker-introduction 1. Working with two side by side views in SwiftUI: ua-cam.com/video/vdI0ZpJXcHk/v-deo.html 2. Using alert() and sheet() with optionals: ua-cam.com/video/QKUBGEMcbAY/v-deo.html 3. Using groups as transparent layout ...
Presenting a default detail view on iPad - SnowSeeker SwiftUI Tutorial 7/12
Переглядів 4495 місяців тому
Presenting a default detail view on iPad - SnowSeeker SwiftUI Tutorial 7/12
Working with two side by side views in SwiftUI - SnowSeeker SwiftUI Tutorial 1/12
Переглядів 1 тис.5 місяців тому
Working with two side by side views in SwiftUI - SnowSeeker SwiftUI Tutorial 1/12
ScrollView effects using visualEffect() and scrollTargetBehavior() - Layout and Geometry SwiftUI 8/8
Переглядів 1,7 тис.6 місяців тому
ScrollView effects using visualEffect() and scrollTargetBehavior() - Layout and Geometry SwiftUI 8/8
ScrollView effects using GeometryReader - Layout and Geometry SwiftUI Tutorial 7/8
Переглядів 1,5 тис.6 місяців тому
ScrollView effects using GeometryReader - Layout and Geometry SwiftUI Tutorial 7/8
Understanding frames and coordinates in GeometryReader - Layout and Geometry SwiftUI Tutorial 6/8
Переглядів 1,7 тис.6 місяців тому
Understanding frames and coordinates in GeometryReader - Layout and Geometry SwiftUI Tutorial 6/8
Resizing images to fit the screen using GeometryReader - Layout and Geometry SwiftUI Tutorial 5/8
Переглядів 1 тис.6 місяців тому
Resizing images to fit the screen using GeometryReader - Layout and Geometry SwiftUI Tutorial 5/8
Absolute positioning for SwiftUI views - Layout and Geometry SwiftUI Tutorial 4/8
Переглядів 1,1 тис.6 місяців тому
Absolute positioning for SwiftUI views - Layout and Geometry SwiftUI Tutorial 4/8
How to create a custom alignment guide - Layout and Geometry SwiftUI Tutorial 3/8
Переглядів 1,3 тис.6 місяців тому
How to create a custom alignment guide - Layout and Geometry SwiftUI Tutorial 3/8
How layout works in SwiftUI - Layout and Geometry SwiftUI Tutorial 1/8
Переглядів 1,6 тис.6 місяців тому
How layout works in SwiftUI - Layout and Geometry SwiftUI Tutorial 1/8
Alignment and alignment guides - Layout and Geometry SwiftUI Tutorial 2/8
Переглядів 1,3 тис.6 місяців тому
Alignment and alignment guides - Layout and Geometry SwiftUI Tutorial 2/8
Adding and deleting cards - Flashzilla SwiftUI Tutorial 13/13
Переглядів 4406 місяців тому
Adding and deleting cards - Flashzilla SwiftUI Tutorial 13/13
Fixing the bugs - Flashzilla SwiftUI Tutorial 12/13
Переглядів 2806 місяців тому
Fixing the bugs - Flashzilla SwiftUI Tutorial 12/13
Building a stack of cards - Flashzilla SwiftUI Tutorial 7/13
Переглядів 6036 місяців тому
Building a stack of cards - Flashzilla SwiftUI Tutorial 7/13
Moving views with DragGesture and offset() - Flashzilla SwiftUI Tutorial 8/13
Переглядів 5756 місяців тому
Moving views with DragGesture and offset() - Flashzilla SwiftUI Tutorial 8/13
Coloring views as we swipe - Flashzilla SwiftUI Tutorial 9/13
Переглядів 5256 місяців тому
Coloring views as we swipe - Flashzilla SwiftUI Tutorial 9/13
Are the names from Fruit basket? =D
Yep! I’m a big fan 🙂
@@twostraws Man of culture <3 Never change mate, never change While we are at it I'd also like to express my thanks for your work. Bought Hacking with Swift Everything Pack <3
What is the empty () brackets for in Array<String>()?
I am getting the error ”Expressions are not allowed at the top level”
Very well explained. However, this appears to only detect a "known iBeacon" Is there a way to detect unknown nearby iBeacons?
Does anybody know how it works with static properties of class? I have static property of @Observable class - gameIsActive (Bool) and would like to change states of different views depending of this common property. But I didn’t find how to do that.
What if we want to combine filters?
I find the solve finally it is : import SwiftUI import SwiftData @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() .modelContainer(for: Book.self) } } } . Just you should pot the .model……_ In windowgrop
I'm over here struggling to implement Newton's approximation for square roots from memory with caveman level Swift skills trying to get doubles to converge to the square root. Finally conceded and watched the "hints". Next time you might want to mention we're only looking for the solutions to perfect squares for the thick skulled amongst us.
Note: if you print out a date, it will return the raw UTC version, contrary to displaying it in a SwiftUI View. And that can be confusing, especially if you only set hour = 8, minute = 0 as in this example. For me in Europe/Amsterdam timezone, the printed value was 0001-01-01 07:42:30 +0000 where I would have expected 0001-01-01 06:00:00 +0000 (taking into account the timezone) Probably because of all the changes to the calendar in the last couple of centuries? :)
Reminder to come September 4th 2024
Great video! do you or could you make a video on how to use the documentation ? I find it hard to what are all the options that can be passed into a functions or method. For example Lets say I create a button and add .Frame and .Padding. I could I find where all the other options are in the documentation. Not just for the button but for others as well.
I tried to call the result like this: let person = Person() ------------------------> This line printed "John Doe is alive!" person.printGreeting() ----------------------> And this line printed "Hello, I'm John Doe" But I couldn't get the 'deinit' result While when using for _ in 1...3 { let person = Person() person.printGreeting() } when using it, I got all three lines: init() and func and deinit I don't understand why do we have to use 'for _ in' to get the full result! can anyone help me to understand this?
Crystal clear! Thanks!
struct Car { // Properties let model: String // Constant since the model of the car won't change let numberOfSeats: Int // Constant since the number of seats is fixed private(set) var currentGear: Int // Variable as the gear changes, but only changeable within the struct // Initializer init(model: String, numberOfSeats: Int, initialGear: Int) { self.model = model self.numberOfSeats = numberOfSeats self.currentGear = initialGear } // Method to change gears up mutating func gearUp() { if currentGear < 10 { currentGear += 1 } else { print("Already in the highest gear.") } } // Method to change gears down mutating func gearDown() { if currentGear > 1 { currentGear -= 1 } else { print("Already in the lowest gear.") } } } // Example usage: var myCar = Car(model: "Tesla Model 3", numberOfSeats: 5, initialGear: 1) myCar.gearUp() // Increases gear by 1 print(myCar.currentGear) // Should print 2 myCar.gearDown() // Decreases gear by 1 print(myCar.currentGear) // Should print 1
Very cool to see. 😊
Brother I had to add an if statement on mine😂
Thanks for the energetic teaching, it proofs what you can do with little code. Do you have some pointers how to include a map and tag a photo with location on the map. The idea is to create an app that allows someone to take a photo of a lost subject, and position that on the map so someone who lost it can visit and collect it. Around a school you find in wintertime a lot of winter cloves, would be nice to make parents happy to reunite their pair of cloves 😎
offset is kind of like the anchor point in after effects
Hello Paul and thank you very much for these videos. I am a novice programmer wannabe and am trying to learn Swift through following your videos. I completed the code for the first tutorial but I am getting nothing back from the API call, just a blank screen. I get the following message: "Communication with Apple failed. Your team has no devices from which to generate a provisioning profile. ..." I am working on a current MacOS machine and the app large is iPhone 15 Pro. Do I need to do something with the App Sandbox under "Capabilities"? When I look under "Capabilities" I do not see the option to add App Sandbox
Cool) can you help me do the same with iOS 15?)
Paul thank u so much I've been wondering how to do these crazy effects and u did show that it can be not that hard thanks! Gonna dig in Inferno etc. Btw these dogs are adorable 2 treats were not enough lol :D
my solution: * * * * * * import Cocoa enum ErrorSquareRoot: Error { case outOfBounds, noRoot } func findSquareRootOf(_ number: Int) throws { if number < 1 || number > 10000 { throw ErrorSquareRoot.outOfBounds } for i in 1...100 { if i * i == number { print("The Square root of \(number) is \(i)") return } } throw ErrorSquareRoot.noRoot } let number = 10 do { try findSquareRootOf(number) } catch ErrorSquareRoot.outOfBounds{ print("out of bounds") } catch ErrorSquareRoot.noRoot { print("no root") }
Thank you for all this work. Just got through the first part and made it here. It didn't fall into place right away but i'm new to programming languages. I'm happy to say I was able to make it happen without looking for an answer first.
You never showed how to automatically move to a new view.
Paul, It is months later but I want to let you know that I found this tutorial VERY clear and consequently VERY helpful. I had watched other tutorials and none were as clear as this one. A BIG thank you!!!
Nice. I hope the latest CSS APIs are in use. These APIs are removing some of the dependency on JS.
Would have preferred a simpler example.
Wow!
SwiftUI is the worst UI Framework I ever worked with lol.
day 87 going strong!
my solution: let luckyNumbers = [7, 4, 25, 49, 22, 33, 2, 9, 1, 17] let filerEven = luckyNumbers.filter{ $0 % 2 == 0} print(filerEven) let ascendingOrder = luckyNumbers.sorted{ return $1 > $0 } print(ascendingOrder) let luckyAnnouncement = luckyNumbers.map{ return "\($0) is the lucky number" } for i in luckyAnnouncement{ print(i) }
at 1:19 , how can you do that? is there a short-cut?
fellas this is my solution, let me know what you think //checkpoint 4 enum sqrtCheckError: Error{ case lessGreater, noRoot } var squaresArray: [Int] = [] for i in 1...100{ var iSqrt = i * i squaresArray.append(iSqrt) } print(squaresArray) func sqrtCheckFunction(_ number: Int) throws -> String{ for i in 1...100{ var iSqrt = i * i squaresArray.append(iSqrt) } if number > 10000 || number < 1{ throw sqrtCheckError.lessGreater } if !squaresArray.contains(number){ return "no root" }else{ return "root: \(number) is \(sqrt(Double(number)))" } } var num = 27; do{ let result = try sqrtCheckFunction(num) print("\(result)") }catch sqrtCheckError.lessGreater{ print("num is out of the bounds") }catch{ print("error") } i used sqrt() because i was out of idea
What does the form actually do from a functionality perspective though? Do toggles etc not work unless they’re in a form? This seems like an important detail.
Thanks for the great tutorial series! One issue I found with this step is that when the QR code is saved to the image library, it's saved in a very low/blurry resolution. I tried setting .interpolation(.none) on the image passed to ShareLink but it did not seem to fix the problem. Do you have any suggestions to resolve this?
I've always been confused by how protocols work. The way you've explained it like I was 5 was perfect! It's literally just a bare requirement for structs, and it allows for custom types for richer inference. Thank you!
Amazing! Thanks
Paul, you're the best!
I am new with SwiftUI and just ran into this problem this week. Unfortunately, @Observable is "only available in iOS 17.0 or newer" so I guess I need to find another way of doing this myself, as my target is for older versions of the OS. (My iPhone X won't run iOS 17 😩) I guess I need to learn just what @Observable does behind the scenes!
Took forever.. here is my solution : enum SquareRootFinderError: Error { case outOfBounds, noRoot } func squareRootFinder(number: Int) throws -> Int { if number < 1 || number > 10_000 { throw SquareRootFinderError.outOfBounds } var i = 0 while i * i <= number { i += 1 } let squareRoot = i - 1 if squareRoot * squareRoot != number { throw SquareRootFinderError.noRoot} return squareRoot } let numberToBeSquared = 100 do { let result = try squareRootFinder(number: numberToBeSquared) print("The square root of \(numberToBeSquared) is \(result)") } catch SquareRootFinderError.outOfBounds { print("Please use a number from 1 - 10,000") } catch SquareRootFinderError.noRoot { print("Cannot find a root") } catch { print("There was an error") }
Great👍, Hudson
The dogs are adorable ☺
Hi Paul, I had a question. You mentioned to have a shuffled array we need to use array.shuffled here. Could you please help understand why we cannot use set here and may be a use case where set can be used rather than this? BTW, I am really loving the swiftUI 100days and how it is structured it is practical to follow and useful. Thank you for creating this.
I would like my app to rewind 2 views upon a certain error. My views are not Ints, they're views I've defined. Currently I am using multiple binding bools to programmatically rewind. Isn't their a way to have every view access the same path and allow me to manipulate it?
A very basic solution: struct Car { let model: String let seatsNumber: Int private(set) var currentGear: Int = 0 var currentSpeed: Int = 0 { didSet { if oldValue - currentSpeed >= 10 { changeGear(.down) } else if currentSpeed - oldValue >= 10 { changeGear(.up) } } } enum GearChangeCommand { case up, down } mutating private func changeGear(_ command: GearChangeCommand) { switch command { case .down where currentGear > 0: currentGear -= 1 print("Changing gear to \(currentGear) at \(currentSpeed)") case .up where currentGear < 6: currentGear += 1 print("Changing gear to \(currentGear) at \(currentSpeed)") print("Changing gear to \(currentGear) at \(currentSpeed)") default: break } } }
I feel like I’ll never be good at layouts. There are so many options.
Speechless, this is the best dev video ive seen on YT - period. Seriously awesome stuff Paul. Also your 100 days of SwiftUI course is incredible!
Hi Paul Hudson I’m using SwiftData for managing my app’s data and am planning to make some changes to the data model. Specifically, I want to add a new attribute and change an existing one. I want to ensure that users won’t lose their data during this migration. What are the best practices and recommended techniques for handling data model migrations in SwiftData? Are there any specific steps I should follow or tools I should use to perform a seamless migration? Additionally, how can I test the migration process to ensure data integrity? Best regards SwiftLotus
In Swift, is it safe to modify 𝘢 collection (in this case removing members) while iterating over it?