Skip to content

Latest commit

 

History

History
740 lines (484 loc) · 47.8 KB

README.md

File metadata and controls

740 lines (484 loc) · 47.8 KB

100 Days of SwiftUI

Table of Contents

Click to see Table of Contents

Day 1 - First Steps in Swift

Variables and Constants, Strings, Integers, Doubles and Booleans, Inference and Type Annotations but setting foundations.

Code

Day 2 - Complex Types

Arrays, Sets, Tuples, Dictionaries and Enumerations.

Code

Day 3 - Operators and Conditions

Arithmetic Operators, Operators Overloading, Compound Assignment Operators, Comparison Operators, Conditions, Combining Conditions, The Ternary Operator, Switch Statements and Range Operators.

Code

Day 4 - Looping

For loops, While loops, Repeat loops, Exiting loops, Exiting multiple loops, Skipping items and Infinite loops.

Code

Day 5 - Functions

Writing functions, Accepting parameters, Returning values, Parameter labels, Omitting parameter labels, Default parameters, Variadic functions, Writing throwing functions, Running throwing functions and inout parameters.

Code

Day 6 - Closures, Part One

Creating basic closures, Accepting parameters in a closure, Returning values from a closure, Closures as parameters and Trailing closure syntax.

Code

Day 7 - Closures, Part Two

Using closures as parameters when they accept parameters, Using closures as parameters when they return values, Shorthand parameter names, Closures with multiple parameters, Returning closures from functions and Capturing values.

Code

Day 8 - Structs, Part One

Creating your own structs, Computed properties, Property observers, Methods, Mutating methods, Properties and methods of strings and Properties and methods of arrays.

Code

Day 9 - Structs, Part Two

Initializers, Referring to the current instance, Lazy properties, Static properties and methods and Access control.

Code

Day 10 - Classes

Creating your own classes, Class inheritance, Overriding methods, Final classes, Copying objects, Deinitializers and Mutability.

Code

Day 11 - Protocols And Extensions

Protocols, Protocol inheritance, Extensions, Protocol extensions and Protocol-oriented programming.

Code

Day 12 - Optionals

Handling missing data, Unwrapping optionals, Unwrapping with guard, Force unwrapping, Implicitly unwrapped optionals, Nil coalescing, Optional chaining, Optional try, Failable initializers and Typecasting.

Code

Day 13 - Swift Review, Day One

Variables and Constants, Types of Data, Operators, String Interpolation, Arrays, Dictionaries, Conditional Statements, Loops and Switch Case.

Code

Day 14 - Swift Review, Day Two

Functions, Optionals, Optional Chaining, Enumerations, Structs and Classes.

Code

Day 15 - Swift Review, Day Three

Properties, Static properties and methods, Access control, Polymorphism and typecasting and Closures.

Code

Day 16 - Project 1, Part One

  • Creating a form and adding a navigation bar
  • Modifying program state: @State
  • Binding state to user interface controls
  • Creating views in a loop

Code

Day 17 - Project 1, Part Two

  • Reading text from the user with TextField
  • Creating pickers in a form
  • Adding a segmented control for tip percentages
  • Calculating the total per person

Code

Day 18 - Project 1, Part Three

Challenge

  1. Add a header to the third section, saying “Amount per person”
  2. Add another section showing the total amount for the check – i.e., the original amount plus tip value, without dividing by the number of people.
  3. Change the “Number of people” picker to be a text field, making sure to use the correct keyboard type.

Code

Day 19 - Unit Conversions Challenge

You need to build an app that handles unit conversions: users will select an input unit and an output unit, then enter a value, and see the output of the conversion.

Code

Day 20 - Project 2, Part One

  • Using stacks to arrange views
  • Colors and frames
  • Gradients
  • Buttons and images
  • Showing alert messages

Code

Day 21 - Project 2, Part Two

  • Stacking up buttons
  • Showing the player's score with an alert
  • Styling our flags

Code

Day 22 - Project 2, Part Three

Challenge

  1. Add an @State property to store the user’s score, modify it when they get an answer right or wrong, then display it in the alert.
  2. Show the player’s current score in a label directly below the flags.
  3. When someone chooses the wrong flag, tell them their mistake in your alert message.

Code

Days 23 and 24 - Project 3

Challenge

  1. Create a custom ViewModifier (and accompanying View extension) that makes a view have a large, blue font suitable for prominent titles in a view. Code
  2. Go back to project 1 and use a conditional modifier to change the total amount text view to red if the user selects a 0% tip. Code
  3. Go back to project 2 and create a FlagImage() view that renders one flag image using the specific set of modifiers we had. Code

Day 25 - MILESTONE: Projects 1-3

Your challenge is to make a brain training game that challenges players to win or lose at rock, paper, scissors.

So, very roughly:

  • Each turn of the game the app will randomly pick either rock, paper, or scissors.
  • Each turn the app will alternate between prompting the player to win or lose.
  • The player must then tap the correct move to win or lose the game.
  • If they are correct they score a point; otherwise they lose a point.
  • The game ends after 10 questions, at which point their score is shown.

So, if the app chose “Rock” and “Win” the player would need to choose “Paper”, but if the app chose “Rock” and “Lose” the player would need to choose “Scissors”.

Code

Day 26 - Project 4, Part One

  • Entering numbers with Stepper.
  • Selecting dates and times with DatePicker.
  • Working with dates.
  • Training a model with Create ML.

Code

Day 27 - Project 4, Part Two

  • Building a basic layout.
  • Connecting SwiftUI to Create ML.
  • Cleaning up the user interface.

Code

Day 28 - Project 4, Part Three

  • Replace each VStack in our form with a Section, where the text view is the title of the section. Do you prefer this layout or the VStack layout? It’s your app – you choose!
  • Replace the “Number of cups” stepper with a Picker showing the same range of values.
  • Change the user interface so that it always shows their recommended bedtime using a nice and large font. You should be able to remove the “Calculate” button entirely.

Code

Day 29 - Project 5, Part One

  • Introducing List, your best friend
  • Loading resources from your app bundle
  • Working with strings

Code

Day 30 - Project 5, Part Two

  • Adding to a list of words
  • Running code when our app launches
  • Validating words with UITextChecker

Code

Day 31 - Project 5, Part Three

  • Disallow answers that are shorter than three letters or are just our start word.
  • Add a toolbar button that calls startGame(), so users can restart with a new word whenever they want to.
  • Put a text view somewhere so you can track and show the player's score for a given root word. How you calculate score is down to you, but something involving number of words and their letter count would be reasonable.

Code

Day 32 - Project 6, Part One

  • Creating implicit animations
  • Customizing animations in SwiftUI
  • Animating bindings
  • Creating explicit animations

Code

Day 33 - Project 6, Part Two

  • Controlling the animation stack
  • Animating gestures
  • Showing and hiding views with transitions
  • Building custom transitions using ViewModifier

Code

Day 34 - Project 6, Part Three

  • When you tap a flag, make it spin around 360 degrees on the Y axis.
  • Make the other two buttons fade out to 25% opacity.
  • Add a third effect of your choosing to the two flags the user didn't choose.

Code

Day 35 - MILESTONE: Projects 4-6

Your goal is to build an “edutainment” app for kids to help them practice multiplication tables – “what is 7 x 8?” and so on. Edutainment apps are educational at their code, but ideally have enough playfulness about them to make kids want to play.

Breaking it down:

  • The player needs to select which multiplication tables they want to practice. This could be pressing buttons, or it could be an “Up to…” stepper, going from 2 to 12.
  • The player should be able to select how many questions they want to be asked: 5, 10, or 20.
  • You should randomly generate as many questions as they asked for, within the difficulty range they asked for.

Code

Day 36 - Project 7, Part One

Code

Day 37 - Project 7, Part Two

  • Building a list we can delete from
  • Working with Identifiable items in SwiftUI
  • Sharing an observed object with a new view
  • Making changes permanent with UserDefaults
  • Final polish (6578f09)

Code

Day 38 - Project 7, Part Three

  1. Use the user’s preferred currency, rather than always using US dollars. (659659b)
  2. Modify the expense amounts in ContentView to contain some styling depending on their value – expenses under $10 should have one style, expenses under $100 another, and expenses over $100 a third style. What those styles are depend on you. (e4f8c49)
  3. For a bigger challenge, try splitting the expenses list into two sections: one for personal expenses, and one for business expenses. This is tricky for a few reasons, not least because it means being careful about how items are deleted! (d8cd46d)

Code

Day 39 - Project 8, Part One

Code

Day 40 - Project 8, Part Two

Code

Day 41 - Project 8, Part Three

Code

Day 42 - Project 8, Part Four

  1. Add the launch date to MissionView, below the mission badge. You might choose to format this differently given that more space is available, but it’s down to you. (6195c6e)
  2. Extract one or two pieces of view code into their own new SwiftUI views – the horizontal scroll view in MissionView is a great candidate, but if you followed my styling then you could also move the Rectangle dividers out too. (6a4d7bc)
  3. For a tough challenge, add a toolbar item to ContentView that toggles between showing missions as a grid and as a list. (c065692)

Code

Day 43 - Project 9, Part One

Code

Day 44 - Project 9, Part Two

Code

Day 45 - Project 9, Part Three

Code

Day 46 - Project 9, Part Four

  1. Create an Arrow shape – having it point straight up is fine. This could be a rectangle/triangle-style arrow, or perhaps three lines, or maybe something else depending on what kind of arrow you want to draw. (5326dfd)
  2. Make the line thickness of your Arrow shape animatable. (18997eb)
  3. Create a ColorCyclingRectangle shape that is the rectangular cousin of ColorCyclingCircle, allowing us to control the position of the gradient using one or more properties.

Code

Day 47 - MILESTONE: Projects 7-9

Build a habit-tracking app, for folks who want to keep track of how much the do certain things. That might be learning a language, practicing an instrument, exercising, or whatever - they get to decide which activities they add, and track it however they want.

At the very least, this menas there should be a list of all activities they want to track, plus a form to add new activities - a title and description should be enough.

For a bigger challenge, tapping one of the activities should show a detail screen with the description. For a though challenge, make that detail screen contain how many times they have completed it, plus a button incrementing their completion count.

And if you want to make the app really useful, use Codable and UserDefaults to load and save all your data.

Code

Day 48 - Expanding Your Horizons

Video - What Star Wars Can Teach Us About Swift

Day 49 - Project 10, Part One

Code

Day 50 - Project 10, Part Two

  • Taking basic order details. (c6d3399)
  • Checking for a valid address. (39c8e34)
  • Preparing for checkout. (09f4c96)

Code

Day 51 - Project 10, Part Three

Code

Day 52 - Project 10, Part Four

  1. Our address fields are currently considered valid if they contain anything, even if it’s just only whitespace. Improve the validation to make sure a string of pure whitespace is invalid. (bf20e2c)
  2. If our call to placeOrder() fails – for example if there is no internet connection – show an informative alert for the user. To test this, try commenting out the request.httpMethod = "POST" line in your code, which should force the request to fail. (5c46e59)
  3. For a more challenging task, see if you can convert our data model from a class to a struct, then create an ObservableObject class wrapper around it that gets passed around. This will result in your class having one @Published property, which is the data struct inside it, and should make supporting Codable on the struct much easier. (7053dc9)

Code

Day 53 - Project 11, Part One

Code

Day 54 - Project 11, Part Two

Code

Day 55 - Project 11, Part Three

Code

Day 56 - Project 11, Part Four

Challenge

  1. Right now it’s possible to select no title, author, or genre for books, which causes a problem for the detail view. Please fix this, either by forcing defaults, validating the form, or showing a default picture for unknown genres – you can choose. (f3cb6e3)
  2. Modify ContentView so that books rated as 1 star are highlighted somehow, such as having their name shown in red. (d3bcc42)
  3. Add a new “date” attribute to the Book entity, assigning Date.now to it so it gets the current date and time, then format that nicely somewhere in DetailView. (18f0ee2)

Code

Day 57 - Project 12, Part One

Day 57 - Core Data

  • Core Data: Introduction. (c2922d4)
  • Why does \.self work for ForEach? (b6be702)
  • Creating NSManagedObject subclasses. (bf5f11c)
  • Conditional saving of NSManagedObjectContext. (5e3efc1)
  • Ensuring Core Data objects are unique using constraints. (63740f3)

Code

Day 57 - SwiftData

Code

Day 58 - Project 12, Part Two

Day 58 - Core Data

Code

Day 58 - SwiftData

  • Dynamically sorting and filtering @Query with SwiftUI. (c22f126)
  • Relationships with SwiftData, SwiftUI, and @Query. (1c408b8)
  • Syncing SwiftData with CloudKit. (56b3db0)

Code

Day 59 - Project 12, Part Three

Challenge

Day 59 - Core Data

Here are three ways to extend this app by modifying the FilteredList view:

  1. Make it accept a string parameter that controls which predicate is applied. You can use Swift’s string interpolation to place this in the predicate. (08c19cc)
  2. Modify the predicate string parameter to be an enum such as .beginsWith, then make that enum get resolved to a string inside the initializer. (2f50b48)
  3. Make FilteredList accept an array of SortDescriptor objects to get used in its fetch request. (09f6397)

Code

Day 59 - SwiftData

  1. Start by upgrading it to use SwiftData. (3e03af9)
  2. Add a customizable sort order option: by name or by amount. (1149730)
  3. Add a filter option to show all expenses, just personal expenses, or just business expenses. (8a85ff8)

Code

Day 60 - MILESTONE: Projects 10-12

Your job is to use URLSession to download some JSON from the internet, use Codable to convert it to Swift types, then use NavigationStack, List, and more to display it to the user.

Your first step should be to examine the JSON. The URL you want to use is this: https://www.hackingwithswift.com/samples/friendface.json – that’s a massive collection of randomly generated data for example users.

As you can see, there is an array of people, and each person has an ID, name, age, email address, and more. They also have an array of tag strings, and an array of friends, where each friend has a name and ID. (ae83062)

Code

Day 61 - Time for Core Data

Challenge

Your job today is to expand your app so that it uses Core Data. Your boss just emailed you to say the app is great, but once the JSON has been fetched they really want it to work offline. This means you need to use Core Data to store the information you download, then use your Core Data entities to display the views you designed – you should only need to fetch the data once. You still need to try to fetch the data every time your app loads, just in case it has changed somehow, but if that fetch fails it’s okay because you still have your Core Data back up.

Day 62 - Project 13, Part One

  • How property wrappers become structs.
  • Responding to state changes using onChange().
  • Showing multiple options with confirmationDialog().

Code

Day 63 - Project 13, Part Two

Code

Day 64 - Project 13, Part Three

  • Loading photos from the user's photo library. (6eec33b)
  • How to let the user share content with ShareLink. (1c5f097)
  • How to ask the user to leave an App Store review. (a8526c3)

Code

Day 65 - Project 13, Part Four

Code

Day 66 - Project 13, Part Five

Code

Day 67 - Project 13, Part Six

Challenge

  1. Try making the Slider and Change Filter buttons disabled if there is no image selected.
  2. Experiment with having more than one slider, to control each of the input keys you care about. For example, you might have one for radius and one for intensity.

Code

Day 68 - Project 14, Part One

  • Bucket List: Introduction
  • Adding conformance to Comparable for custom types (d550513)
  • Writing data to the documents directory (5b6ccb6)
  • Switching view states with enums (52867f4)

Code

Day 69 - Project 14, Part Two

Code

Day 70 - Project 14, Part Three

  • Adding user locations to a map (a0fec09)
  • Improving our map annotations (22572bc)
  • Selecting and editing map annotations (509c41a)

Code

Day 71 - Project 14, Part Four

  • Downloading data from Wikipedia (84c4826)
  • Sorting Wikipedia results (83b7bcb)

Code

Day 72 - Project 14, Part Five

  • Introducing MVVM into your SwiftUI project (8328660)
  • Locking our UI behind Face ID (10a44ce)

Code

Day 73 - Project 14, Part Six

Challenge

  1. Allow the user to switch map modes, between the standard mode and hybrid. (b115a56)
  2. Our app silently fails when errors occur during biometric authentication, so add code to show those errors in an alert. (cc41a4f)
  3. Create another view model, this time for EditView. What you put in the view model is down to you, but I would recommend leaving dismiss and onSave in the view itself - the former uses the environment, which can only be read by the vie, and the latter doesn't really add anything when moved into de model. (dbb0659)

Code

Day 74 - Project 15, Part One

  • Identifying views with useful labels (e2cc5f4)
  • Hiding and grouping accessibility data (8b3e4d2)
  • Reading the value of controls (0f645bd)

Code

Day 75 - Project 15, Part Two

Day 76 - Project 15, Part Three

Challenge

  1. The check out view in Cupcake Corner uses an image and loading spinner that don't add anything to the UI, so find a way to make the screenreader not read them out. (a1a35e4)
  2. Fix the list rows in iExpense so they read out the name and value in one single VoiceOver label, and their type in a hint. (13bf74a)
  3. Do a full accessibility review of Moonshot - what changes do you need to make so that it's fully accessible? (58f8af5)