0% found this document useful (0 votes)
52 views

Swift Ios17 Swiftui Sample

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
52 views

Swift Ios17 Swiftui Sample

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 262

Table of Contents

Preface
Chapter 1 - The Development Tools, the Learning Approach, and the App
Idea
The Tools
The Learning Approach
UIKit vs SwiftUI
Chapter 2 - Your First Taste of Swift with Playgrounds
Trying out Swift in Playgrounds
Constants and Variables
Understanding Type Inference
Control Flow Basics
Understanding Optionals
Playing around with UI
Chapter 3 - Build Your First App in Swift and SwiftUI
An Introduction to SwiftUI
Declarative vs Imperative Programming
Building Your First App Using SwiftUI
Run Your App for the First Time
Chapter 4 - Designing UI Using Stack Views
Understanding VStack, HStack and ZStack
Adding Images to the Xcode Project
Using Spacer and Padding
Using Images
Arranging the Images Using Horizontal Stack Views
Extracting Views for Better Code Organization
Adapting Stack Views Using Size Classes
Chapter 5 - Introduction to Prototyping
Sketching Your App Ideas on Paper
Wireframing Your App
Make Your Sketch/Wireframe Interactive
Prototyping Your App with App Prototyping Tools
Chapter 6 - Understanding List and ForEach
Creating a Simple List
Presenting a List with Array of Items
Adding Thumbnails to the List View
Changing the List View's Style
Alternative Ways to Present the List
Chapter 7 - Customizing List Views
Creating the Basic List View
Displaying Different Restaurant Images
Redesigning the Row Layout
Hiding the List Separators
Chapter 8 - Displaying Confirmations and Handling List View Selection
Building a more Elegant Row Layout
Managing Row Selections Using State
Detecting Touches and Displaying an Action Sheet
Understanding Binding
Displaying an Alert Message
Previewing the Row Layout
Chapter 9 - Understanding Struct, Project Organization and Code
Documentation
Classes, Objects and Structures
Creating a Restaurant Struct
Using the Array of Restaurant Objects
Organizing Your Xcode Project Files
Documenting and Organizing Swift Code with MARK
Chapter 10 - List Deletion, Swipe Actions, Context Menus and Activity
Controller
Performing Row Deletion
Using Swipe Actions
Creating Context Menu
Understanding SF Symbols
Working with Activity Controller
Chapter 11 - Working with Navigation View
Creating Navigation Views
Adding the Restaurant Detail View
Navigating from One View to Another
Using Accent Color
Customizing the Back Button
Removing Disclosure Indicators
Chapter 12 - Detail View Enhancement, Custom Fonts and Navigation Bar
Customization

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 4
Using Custom Fonts
Improving the Detail View
Ignoring the Safe Area
Previewing the Detail View inside a Navigation View
Customizing the Navigation Bar
Chapter 13 - Understanding Colors, Swift Extensions and Dynamic Type
Working with Custom Colors
Swift Extensions
Adapting Colors for Dark Mode
Dynamic Type
Chapter 14 - Working with Maps
Understanding Map View in SwiftUI
Creating Our Own Map View
Converting an Address into Coordinates Using Geocoder
Adding Annotations to the Map
Embedding MapView
Displaying a Full Screen Map
Chapter 15 - View Animations and Blur Effect
Using Enumeration to Represent Ratings
Implementing the Review View
Applying a Visual Blur Effect
Dismissing the Review View with Animations
Animating the Rate Buttons with Slide-in Animation
Chapter 16 - Working with Observable Objects and Combine
The Problem with our Existing Design

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 5
Using Observable Object
Displaying the Rating in Detail View
Chapter 17 - Working with Forms and Camera
Understanding Text Field in SwiftUI
Building Generic Form Fields for User Input
Implementing the Restaurant Form
Working with Photo Library and Camera
Adding Toolbar Buttons
Chapter 18 - Working with Database and SwiftData
What is SwiftData?
Using Code to Create and Manage Data Models
Defining the Model Class for the FoodPin Project
Using @Query to Fetch Records
Deleting a Record from Database
Handling Empty List Views
Updating a Model Object
Chapter 19 - Adding a Search Bar Using Searchable
Using Searchable
Adding a Search Bar to the Restaurant List View
Search Bar Placement
Performing Search and Displaying Search Results
Chapter 20 - Building Walkthrough Screens Using TabView
A Quick Look at the Walkthrough Screens
Creating the Tutorial View
Adding Next and Skip Buttons

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 6
Presenting the Tutorial View
Working with UserDefaults
Chapter 21 - Working with Tab View and Tab Bar Customizations
Creating Tab Interface Using TabView
Adjusting the Color of Tab Bar Items
Adjusting the Color of Tab Bar Items
Chapter 22 - Displaying Web Content with WKWebView and
SFSafariViewController
Designing the About View
Opening Safari Using Link
Using WKWebView
Using SFSafariViewController
Chapter 23 - Working with CloudKit
Understanding CloudKit Framework
Managing Records in CloudKit Dashboard
Fetching Data from a Public Database Using Convenience API
Fetching Data from Public Database Using Operational API
Optimizing the Performance with Activity Indicator
Pull to Refresh
Saving Data Using CloudKit
Chapter 24 - Localizing Your App to Support Multiple Languages
Internationalizing Your App
Export for Localization
Import Localizations
Testing the Localized App

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 7
Chapter 25 - Deploying and Testing Your App on a Real iOS Device
Understanding Code Signing and Provisioning Profiles
Automatic Signing in Xcode
Deploying the App on Your Device via USB
Deploying the App over Wi-Fi
Chapter 26 - Beta Testing with TestFlight and CloudKit Production
Deployment
Creating an App Record on App Store Connect
Archiving and Validating Your App
Upload Your App to App Store Connect
Manage Internal Testing
Manage Beta Testing with External Users
CloudKit Production Deployment
Chapter 27 - Submit Your App to App Store
Get Prepared and Well-Tested
Submit Your App to App Store
Chapter 28 - Adopting Haptic Touch
Home Screen Quick Actions
Handling Quick Actions Using Custom URL Scheme
Chapter 29 - Working with User Notifications
Using User Notifications to Increase Customer Engagement
Using the User Notifications Framework
Creating and Scheduling Notifications
Interacting with User Notifications
Appendix - Swift Basics

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 8
Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 9
Published: 21/11/2023 | Last updated: 21/11/2023 | AppCoda © 2023

Copyright ©2023 by AppCoda Limited

All right reserved. No part of this book may be used or reproduced, stored or
transmitted in any manner whatsoever without written permission from the
publisher.

Published by AppCoda Limited

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 10
What People Say About This Book
"This book got me an internship and a job. After one week of following this book’s
tutorial, I was immediately able to begin developing my own app! 4 months
later, I got an offer at Ancestry to intern as an iOS developer. Best money I ever
spent!!"

- Adriana, iOS developer at Ancestry

"The Basic and Intermediate books are everything you need to understand all the
concepts of design, coding, testing, and publishing an app. All you need is the
idea."

- Rich Gabrielli

"I have published 8Cafe and 8Books, apps based on, and inspired by, the
AppCoda Swift iOS book; it was a pleasure to learn and develop with your team.
In fact, a lot of my apps/games utilise ideas and techniques from your excellent
Beginner and Intermediate Swift books. To me, and a lot of developers, your
talent, knowledge, expertise and willingness to share have been simply a
godsend."

- Mazen Kilani, creator of 8Cafe

"I've been developing iOS apps for about a year now and am greatly indebted to
the team at AppCoda. The Swift books I've purchased from them have
dramatically increased my productivity and understanding of the entire Xcode
and iOS development process. I've learned much more than I ever would have by
scouring StackOverflow and github for hours and hours, which is what I had
been doing prior to deciding to use AppCoda. All of the information is updated

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 11
and accurate, simple to read and follow, and the sample projects are fantastic. I
really can't recommend these books highly enough. If you're trying to jump-start
your Swift education, go for it."

- David Gagne, creator of Bartender.live

"AppCoda's books are fantastic. They are clearly written, assuming no


knowledge, but still push you to think for yourself and internalize the concepts.
No other resource is so comprehensive."

- JP Sheehan, Ingot LLC

"The book is well written, concise, with excellent example code and real-world
examples. It's really helped me get my first App on the App store, and given me
many ideas for further enhancements and updates. I also use it as a reference
guide ongoing as well with the language, and the updates produced as Swift and
iOS change are much gratefully received."

- David Greenfield, creator of ThreadABead

"Thanks for making such an awesome book! This book helped me develop my first
real app and have made $200 on the app store in less than 2 months since
launch. I was also able to get a software developer job where now I am running
the Mobile department. Thanks again for the great book, I always try to promote
it when people ask me about learning how to code."

- Rody Davis, Developer of Pitch Pipe with Pitch Assistant

"The book is really good. I was taking other courses of Swift from Udemy and the
instructor did not have much background as a developer. In your case, I know
you have a good background as a developer. By the way, you explain the things."

- Carlos Aguilar, creator of Roomhints Interior Design Ideas

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 12
"For years, I'd been looking in vain for good quality resources to help sharpen my
app development skills. Your books saved my life. They're the best explained
programming books I've ever read in my 10 years of programming. They're so
easy to understand and they hit everything. I will never thank you enough for
writing the books and I owe you a lot."

- Eric Mwangi

"This book is clearly written with lots of examples. It is also great for experienced
programmers new to Swift."

- Howard Smith, Flickitt

"Without this book, I couldn't become an iOS developer."

- Changho Lee, SY Energy

"I wanted to learn about iOS programming with Swift. For this, I turned to this
book. It's an absolutely great way to learn Swift and iOS app development. If you
have some programming background, you'll be able to do real stuff within a
couple of days. But even if you do not, you'll still be able to learn to develop apps."

- Leon Pillich

"This book is the best book I have found on the Internet. It is very
straightforward. I started my programming journey three years ago and
currently, all my app achievement was due to this book."

- Aziz, Engineer at Kuwait Concepts

"Insightful, helpful, and motivational. The books are full of knowledge and depth
of the subject, providing hints and tips on many aspects of iOS development, and
encourages the student/reader to push forward and to not be afraid of seeking a
deeper understanding of the concepts. Just awesome."

- Moin Ahmad, Creator of Guess Animals

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 13
"This book taught me how to build the structure for the type of app I wanted to
create. The lessons are well laid out, each one is just the right length to avoid
overload. I would highly recommend this book as an excellent introduction to
creating your first app and beyond."

- Stephen Donnelly, Director at Rascalbiscuit

"I tried multiple learning sources including the Stanford training. Although I
already did learn some topics like auto layout, delegates, segues, etc through
other sources, your book was the first one that really made me understand
them!"

- Nico van der Linden, SAP developer at Expertum

"Over the past three years, I have purchased more than a dozen books on
Objective C and Swift. As a high school AP computer science teacher I work
mainly with Java but I also teach several other programming languages so I
tend to keep a large library of books on-hand. While many of the other books and
online video tutorials I purchased these past years were very good, I found
AppCoda's to be far above all others. Simon has a way of presenting a topic in
such a manner where I felt he was teaching me in a classroom environment
rather than just me reading words on a screen. The best way to describe his
writing style is to say it feels like he is speaking to you, not just giving you
instructions."

- Ricky Martin, Gulf Coast High School

"This was one of the easiest books I have found to learn Swift. As a beginner, it
was extremely easy to follow and understand. The real-life examples you include
as your work through the book and build the app being taught is genius and
makes it all worth it in the end. I was able to take many things away and apply to
my own apps. I find myself referring back to it many times. Great Work."

- Bill Harned, creator of Percent Off

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 14
"Best books on iOS development, well designed and easy to follow, and a great
development journey companion."

- Ali Akkawi, freelancer in mobile apps development for iOS and Android

"I like the book. The contents are well structured. We have almost all of the latest
concepts covered."

- Barath V, Lead iOS developer at Robert Bosch LLC

"I have purchased both the Beginning and Intermediate iOS 11 Programming
with Swift books. I am a Java developer turned iOS mobile developer and these
books really helped me learn the concepts of building a mobile application. The
FoodPin application that you build in the Beginner book is an excellent way to
learn all of the most common components of a mobile app. Even though I have
now been working on iOS apps for over three years, I still regularly go back to
the AppCoda swift books as a reference."

- Stacy Chang

"I probably could have done it without the book but it would've taken WAY longer
and I probably wouldn't have understood what I was doing so well. If it weren't
for this book my app probably won't be in the App Store right now. True story.
Keep it up!"

- Marc Estwick

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 15
Preface
A couple years ago, people still asked, "Is Swift ready for app development?"

Now everyone knows Swift is the programming language to learn for developing
iOS apps.

I have a genuine passion for Swift programming, and my admiration for this
language is not solely driven by my profession as a Swift programming instructor
or a desire to promote my courses/books. With over 15 years of programming
experience in various languages, I can confidently say that Swift has become my
favorite language at present. Its well-designed structure, simplified syntax, and
cleanliness are some of the key factors that contribute to its appeal. Swift's ease of
learning and enhanced productivity in iOS app development make it a standout
choice compared to the more traditional Objective-C.

Introduced by Apple in June 2014, Swift has undergone significant updates and
advancements. Fast forward to today, the company already released version 5.9 of
the programming language along with Xcode 15, introducing a wealth of features.
With over 9 years of development since its first release, Swift has transcended its
status as a new language. It has matured into a robust and well-established
programming language, poised to tackle application development across iOS,
macOS, watchOS, and tvOS. Notably, renowned companies such as Lyft, LinkedIn,
and Mozilla have embraced Swift for their app development endeavors. Whether
you aspire to create your next iOS app or forge a career in iOS app development,
Swift undoubtedly stands out as the programming language to learn and employ.

This book covers everything you need to learn for iOS app development. However,
it's important to remember that Swift is merely a programming language. To
successfully develop an iOS app, you'll need to acquire knowledge beyond Swift

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 16
alone. In addition to introducing Swift, this book will guide you through the
process of designing user interfaces using SwiftUI and mastering the essential
APIs of the iOS SDK. Most importantly, you'll gain practical Swift programming
skills by building a real-world app from the ground up.

For those starting from scratch without any programming experience, you may
wonder if it's possible to learn Swift programming and create a functioning iOS
app.

Having personally programmed in Swift since its inception, I can confidently state
that Swift is incredibly accessible and much easier for beginners to grasp compared
to Objective-C. While not everyone may become an exceptional developer, I firmly
believe that anyone can learn programming and develop an app using Swift. All it
requires is dedication, perseverance, and a proactive approach to learning and
taking action. With the right mindset and effort, you can embark on a rewarding
journey of Swift programming and app development.

I launched AppCoda about 10 years ago and started to publish iOS programming
tutorials on a weekly basis. Since then, I have published several books on iOS app
development. At first, I thought people, who want to learn app development, are
those with programming experience and technical background. What's interesting
is that people from diverse backgrounds are passionate to build their own apps. I
have a reader from France, who is a surgeon by profession, started from zero
programming experience to launching his first app, which allows anyone to share
and advertise event information for free. Another reader is a pilot by profession.
He began to learn iOS programming a couple years ago and is now building iPhone
apps for his own use and other pilots. Boozy is an app for finding Happy Hours,
Daily Deals and Brunches. It was built by a law school dropout. The creator of the
app could not find a good place for a drink in DC area. So she decided to make an
app to meet a real need. Similarly, she did not know coding when she came up with
the idea. She just got started and learned along the way.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 17
From time to time, I got emails from individuals expressing their desire to create
an app. These messages often contain similar sentiments: "I have an app idea, but
I don't know where to start. I lack programming skills. Can I learn from scratch
and bring my idea to life?"

What I learned from these truly inspiring stories is that you do not necessarily
require a Computer Science or Engineering degree to develop an app. These
readers share a common attribute: unwavering commitment to taking action. They
all invested their hard work to transform their aspirations into reality. And that is
precisely what you need.

So, you have an app idea? I wholeheartedly believe that you have the ability to
bring it to life. There is absolutely nothing that can hold you back from learning
and accomplishing your goals if you possess true passion and dedication. Let me
borrow one of my favorite quotes from Last Lecture to conclude:

Brick walls are there for a reason: they let us prove how badly we want
things.

- Randy Pausch

Lastly, thanks for picking up the book. I hope you will enjoy reading it and that it
helps you in launching your first iOS app on the App Store. If you would like to
share the story of your app development journey, please don't hesitate to drop me
an email at [email protected]. I would be thrilled to hear from you and learn
about your experiences.

Simon Ng
Founder of AppCoda

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 18
What You Will Learn in This Book
This new book is specifically designed for readers who have an app idea but are
unsure of where to begin. It comprehensively covers Swift programming, guiding
you through the process of building a real-world app from scratch. Starting with
the basics of Swift and SwiftUI, you'll progress to prototyping and constructing the
app step by step.

Each chapter focuses on utilizing iOS APIs to implement different features. By the
end of the book, you'll have a fully functional app. Throughout the journey, you'll
learn essential skills such as data presentation in list views, UI design using Stack
Views, creating animations, working with maps, developing adaptive UI, local
database storage, iCloud data upload, TestFlight beta testing, and more.

This book offers numerous hands-on exercises and projects, allowing you to write
code, debug, and test your app. While it requires effort, the experience will be
rewarding. By the end, you'll have a solid grasp of Swift 5.9, Xcode 15, and iOS 17
programming. Most importantly, you'll have the ability to develop an app and
release it on the App Store.

Audience
This book is tailored for individuals who are beginners in programming and have
no prior experience. It is also suitable for programmers seeking to learn a new
language, designers aiming to transform their designs into iOS apps, or
entrepreneurs interested in acquiring coding skills.

Assuming you are already familiar with using macOS and iOS as a user, this book
will provide you with the necessary knowledge to embark on your Swift
programming journey.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 19
SwiftUI vs UIKit
The introduction of SwiftUI had a tremendous impact on both existing iOS
developers and those interested in learning iOS app development. It
unquestionably represented the most significant change in recent years within the
realm of iOS app development. However, this shift may lead beginners to feel
confused about which UI framework to focus on. The question arises: which one
should you learn or begin with?

To make a decision, it's essential to reflect on your motivation for learning iOS
programming and determine your goals. Are you aiming to become a professional
iOS developer and secure employment? Or are you simply interested in learning
something new as a hobby?

If your aspiration is to pursue a career as a professional iOS developer and secure


job opportunities, it is advisable to learn both frameworks. The majority of apps on
the App Store are developed with UIKit. Therefore, it is highly likely that you will
work on UIKit-based apps in a professional setting. In this case, starting with
UIKit and subsequently transitioning to SwiftUI would be a suitable approach.

On the other hand, if you are taking up programming as a hobby or working on an


app as a side project, I recommend diving straight into SwiftUI.

This book is available in two editions: UIKit and SwiftUI. Both editions guide you
through building the same real-world app but using different UI frameworks. If
your intention is to start with SwiftUI, you can continue reading from Chapter 1.
Otherwise, opt for the UIKit edition of the book.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 20
Chapter 1
The Development Tools, the
Learning Approach, and the App
Idea

Since you pick up this book, I guess you want to create an iOS app. Creating an app
is a fun and rewarding experience. I still remembered the joy when I first created
an app years ago, even though the app is just so simple and elementary.

iOS, the mobile operating system behind iPhone and iPad, has been released for
more than 10 years. The tools, the programming language and its frameworks have
greatly evolved over these years. Therefore, before we dive into iOS programming,
let's go through the tools you need to build an app and get prepared the mindset
for learning iOS app development.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 21
The Tools
Apple has favored a closed ecosystem over the open system. iOS can be only run on
Apple's own devices including iPhone and iPad. It is very much unlike its
competitor, Google, that Android is allowed to run on mobile devices from
different manufacturers. As an aspiring iOS developer, what this means to you is
that you will need a Mac for app development.

1. Get a Mac
Having a Mac is the basic requirement for iOS development. To develop an iPhone
(or iPad) app, you need to get a Mac that is capable to run on macOS version 13.5
(or later). If you now own a PC, the cheapest option is to purchase the Mac Mini.
As of this writing, the retail price of the entry model is US$599. You can hook it up
to the monitor of your PC. I would recommend you to pick the basic model of Mac
mini with Apple M1 chip. It should be good enough to run the iOS development
tools smoothly. Of course, if you have a bigger budget, get the higher model or an
iMac with better processing power.

2. Register Your Apple ID


You will need an Apple ID to download Xcode, access iOS SDK documentation,
and other technical resources. Most importantly, it will allow you to deploy your
app to a real iPhone/iPad for testing.

If you have downloaded an app from the App Store, it is quite sure that you already
own an Apple ID. In case you haven't created your Apple ID before, you have to get
one. Simply go to Apple's website (https://appleid.apple.com/account) and follow
the procedures for registration.

3. Install Xcode

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 22
To start developing iOS apps, Xcode is the only tool you need to download. Xcode
is an integrated development environment (IDE) provided by Apple. Xcode
provides everything you need to kick start your app development. It already
bundles the latest version of the iOS SDK (short for Software Development Kit), a
built-in source code editor, graphic user interface (UI) editor, debugging tools and
much more. Most importantly, Xcode comes with an iPhone (and iPad) simulator
so you can test your app without the real devices.

To install Xcode, go up to the Mac App Store and download it. If you're using the
latest version of Mac OS, you should be able to open the Mac App Store by clicking
the icon in the dock. In case you can't find it, you may need to upgrade your Mac
OS.

Figure 1-1. App Store icon in the dock

In the Mac App Store, simply search "Xcode" and click the "Get" button to
download it.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 23
Figure 1-2. Download Xcode on App Store

Once you complete the installation process, you will find Xcode in the Launchpad.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 24
Figure 1-3. Xcode icon in the Launchpad

At the time of this writing, the latest version of Xcode is 15. Throughout this book,
we will use this version of Xcode to create the demo apps. Even if you have
installed Xcode before, I suggest you upgrade to the latest version. This should
make it easier for you to follow the tutorials.

4. Enroll in the Apple Developer Program


(Optional)
A common question about developing an iOS app is whether you need to enroll in
the Apple Developer Program (https://developer.apple.com/programs/). The
short answer is optional. First, Xcode already includes a built-in iPhone and iPad
simulator. You can develop and test out your app on Mac, without enrolling in the
program.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 25
Starting from Xcode 7, Apple has changed its policy regarding permissions
required to build and run apps on devices. Before that, the company required you
to pay US$99 per year in order to deploy and run your apps on a physical iPhone
or iPad. Now, program membership is no longer required. Everyone can test their
apps on a real device without enrolling in the Apple Developer Program. Having
said that, if you want to try out some advanced features such as in-app purchase,
push notifications or CloudKit, you still need to apply for the program
membership. Most importantly, you're not able to submit your app to App Store
without paying the annual membership fee.

So, should you enroll in the program now? The Apple Developer Program costs
US$99 per year. It's not big money but it's not cheap either. Since you're reading
this book, you're probably a newcomer and just start exploring iOS development.
The book is written for beginners. We will first start with something simple. You
are not going to tap into the advanced features until you grasp the basic skills.

Therefore, even if you do not enroll into the program, you will still be able to follow
most of the content to build an app and test it on your device. For now, save your
money. I will let you know when you need to enroll in the program. At that time,
you're encouraged to join the program as you're ready to publish the app to the
App Store!

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 26
The Learning Approach
I have been teaching iOS programming from 2012 through blogging, online
courses, and in-person workshops. What I found is that it is the learning approach
and the mindset that make the difference between failing and achieving. Before we
talk about Swift and iOS programming, I want to get you equip with the right
mindset and understand the most effective way to learn programming.

Get Your Hands Dirty


One of the most popular questions about learning how to code is:

What's the best way to learn iOS programming?

First, thanks for reading this book. Unfortunately, I have to tell you that you
cannot learn programming just by reading books. This book has everything you
need to learn Xcode, Swift, and iOS app development.

But the most important part is taking action.

If I have to provide an answer to the question, I will say "Learn by Doing". It is at


the heart of my teaching approach.

Let me change the question a little bit:

What's the best way to learn English (or other foreign languages)?

What's the best way to learn cycling (or any other sports)?

You probably know the answer. I especially like this answer on Quora about
learning a new language:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 27
Follow this routine: listen 1 hour a day, speak 1 hour a day, publish 1 journal
entry.

- Dario Mars Patible

You learn through practice, not by just studying grammar. Learning programming
is somewhat very similar to learning a language. You need to take actions. You
have to work on a project or some exercises. You have to sit in front of your Mac,
immerse yourself in Xcode, and write the Swift code. It doesn't matter how many
mistakes you make during the process. Just remember to open Xcode and code
while reading this book.

Motivations
Why do you want to learn app development? What motivates you to sacrifice the
weekends and holidays to learn how to code?

Some people begin learning app development just because of money. There is
nothing wrong with that. You may want to build your app business to earn some
side income and eventually turn it into a full-time business. That's completely
understandable. Who doesn't want to live a rich life?

As of August 2022, however, there were over 2.2 million apps on the App Store. It
is really hard to put up an app on the App Store and expect to make a load of
money overnight. You'll be easily discouraged or even give up if money is your
primary reason for building apps, especially when you come across articles like
this:

How Much Money I Made on the App Store


(https://juejin.cn/post/6844903422802706440)

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 28
Then reality set in.

199 units old = US$209 in sales = US$135 proceeds (net to me). In order to
get the app on the app store I needed to pay the $99 developer fee.

So after 2 months and 1 week my (before tax) profit was $36.

- James

Programming is hard and challenging. I find people who successfully master the
language are those who have a strong desire to build apps and are enthusiastic to
learn programming. They usually have an idea in their mind and want to turn it
into a real app. Making money is not their number one concern. They know the
app can solve their own problems and will be beneficial to others. With such a
powerful purpose in mind, they can overcome any obstacles come up.

So, think again why you want to learn programming.

Find a Buddy
"The best way to learn is to teach" is an old saying. It still works in the modern
world, however. You don't need to be an expert to teach. I'm not talking about
giving a lecture at a university or teaching a bunch of students in a formal class.
Teaching does not always happen that way. It can be as simple as sharing your
knowledge with a colleague or a classmate sitting next to you.

Try to find someone who is also interested in learning iOS programming. When
you learn something new, try to explain the materials to your buddy. For example,
after building your first app, teach your close friend how it works and how he/she
can create an app too.

What if you can't find a buddy to share what you've learned? No worries. Start a
blog on medium.com (or whatever platforms you like), write a blog post every day,
and document everything you learn.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 29
This is one of the most effective ways of learning as I learn so much while
publishing tutorials on appcoda.com, as well as, developing my first book.

Sometimes you think you know the materials well. But once you need to explain
the concept to someone else and answer questions, chances are that you didn't
understand the material thoroughly. This will motivate you to study the materials
even harder. Give this method a shot while you learn iOS programming.

Be Patient
Grit is passion and perseverance for very long-term goals. Grit is having
stamina. Grit is sticking with your future, day-in, day-out. Not just for the
week, not just for the month, but for years. And working really hard to make
that future a reality. Grit is living life like it’s a marathon, not a sprint.

- Dr. Angela Lee Duckworth

Some of my students asked, "How long would it take to become a good developer?"

It takes time to master programming and become a great developer. It usually


takes years. Not weeks, not months but years.

This book will help you kick start the journey. You will learn all the basics of Swift
and iOS programming and eventually, build an app. That said, it takes time and
lots of practices to become a professional programmer.

Be patient. Don't set your expectations too high for your first app. Just enjoy the
process, create something simple and fun. Keep reading and coding daily. You will
eventually master the skill.

Find Your App Idea

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 30
I always encourage my students to come up with their own app idea when start
learning app development. The idea doesn't have to be big. You do not need to
build the next Uber app or come up with a new idea to change the world. You just
need to start with a very small idea that solves a problem.

Let me give you a couple of the examples.

One classic example that I used to mention is Cockpit Dictionary. It is an app built
by Manolo Suarez, who is a pilot by profession. He had an app idea while learning
app programming. The idea was not fancy but solved his own problem. There are
tens of thousands of Aviation terms in abbreviated form. Even for an experienced
pilot with over 20 years of aviation experience, it is impossible to remember all the
acronyms and technical terms. Instead of using a print dictionary, he thought of
building a handy app for pilots to look up all kinds of Aviation terms. A simple, yet
a great idea to solve his own problem.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 31
Figure 1-4. Cockpit Dictionary

Another example is the NOAA Buoy Data app. While this app is no longer available
on the App Store, I still want to quote it as an example. The app was designed to
retrieve the latest weather, wind, and wave data from the National Oceanic and
Atmospheric Administration’s (NOAA) National Data Buoy Center (NDBC).
Developed by Leo Kin, he came up with the app idea during his recovery from
surgery.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 32
"After the surgery, I had to wear a neck brace for three months. During those
three months, I couldn’t move a lot and even had a hard time walking or even
raising my arms. My physical therapist advised that I go walking as much as I
can to get exercise and to build back my atrophied leg muscles.

There is an island close to where I was living that I really enjoyed walking to.
The only problem was that it can only be reached during low tide. And if the
tide came in, there’s no way to get back home except by swimming. Since I
was very physically weakened, I was very scared of getting stuck on the island
with no way back. While walking, I was always going to NOAA’s website to
check how high or low the tide was and if I had enough time to walk to the
island and back.

During one of my walks, the idea came to me that I should build an app. Even
if no one else uses the app, it wouldn’t matter because it would help me keep
track of the tides and get back in time."

- Leo Kin

His app may not interest you, but it was solving a problem he faced at the time.
Probably people on that island would benefit from his app too.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 33
Figure 1-5. NOAA Buoy Data app

Having your own app idea will give you a clear goal and motivate you to keep
learning. Now spare some time and write down three app ideas below:

1.

2.

3.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 34
UIKit vs SwiftUI
Which UI framework should you learn? As a beginner, you may have come across
these two terms: UIKit and SwiftUI. Some individuals advocate learning UIKit for
app development, while others suggest that you can bypass UIKit and directly
immerse yourself in SwiftUI, considering it as Apple's latest UI framework.

I understand that these technical terms might be confusing. Let me provide you
with a brief overview of both frameworks, so you can gain clarity on which one to
prioritize.

Figure 1-6. Building apps using UIKit and Interface Builder

First, both frameworks allow you to build great apps. The UIKit framework is the
original UI framework available since the first release of iOS. With UIKit, you can
write code to build the mobile app UI or create app layouts using Xcode's Interface

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 35
Builder. One of the downsides, however, is that the framework is more
complicated to learn as compared to SwiftUI.

Figure 1-7. Building apps using SwiftUI

With SwiftUI, you can develop the UI of your app using a declarative Swift syntax.
This means that writing UI code becomes easier and more intuitive. In comparison
to existing UI frameworks like UIKit, you can achieve the same UI design with
significantly less code.

The preview function has always been a weak point of Xcode. While you can
preview simple layouts in Interface Builder (or Storyboard), obtaining a complete
preview of the UI was often only possible once the app was loaded onto the
simulators. SwiftUI changes this by providing immediate feedback on the UI as
you code. For instance, when you add a new record to a table, Xcode dynamically

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 36
updates the UI in a preview canvas. Additionally, previewing your UI in dark mode
or making other adjustments is as simple as changing an option. This instant
preview feature streamlines UI development and significantly accelerates the
iteration process.

Now, let's address the core question: as a beginner, which framework should you
learn?

You should ask yourself why you want to learn iOS programming. What are your
goals? Do you aim to pursue a professional career as an iOS developer and secure
job opportunities? Or are you simply interested in learning something new as a
hobby?

If your goal is to establish a career in iOS development, my suggestion is to learn


both frameworks. However, it is advisable to start with UIKit, as many companies
still rely on it for app development. Acquiring UIKit skills will be invaluable in
enhancing your employability. Therefore, I recommend familiarizing yourself with
UIKit first, followed by SwiftUI.

On the other hand, if you are pursuing programming as a hobby or working on an


app as a side project, I recommend diving directly into SwiftUI. It is easier to learn
and allows you to build apps with less code. Occasionally, you may encounter the
need to utilize specific UI components from UIKit. In such instances, you can learn
how to incorporate those particular UIKit components. So, prioritize learning
SwiftUI initially, and subsequently delve into UIKit when the need arises.

Summary
That's all for the introduction. Take some time to install Xcode on your Mac,
brainstorm your app idea, and select the framework you wish to concentrate on.
We offer both UIKit and SwiftUI books, which will assist you in acquiring the
necessary skills for developing your own apps.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 37
If SwiftUI is your focus, proceed to the next chapter and we will start programming
in Swift.

Prepare yourself for the exciting journey ahead!

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 38
Chapter 2
Your First Taste of Swift with
Playgrounds

Now that you have configured everything you need to start iOS app development,
let me answer another common question from beginners before moving on. A lot
of people have asked me about what skills you need in order to develop an iOS app.
In brief, it comes down to three areas:

Learn Swift - Swift is now the recommended programming language for


writing iOS apps.
Learn Xcode - Xcode is the development tool for you to design the app UI,
write Swift code, and build your apps.
Understand the iOS software development kit - Apple provides the

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 39
software development kit for developers to make our lives simpler. This kit
comes with a set of software tools and APIs that empowers you to develop iOS
apps. For example, the SwiftUI framework which will discuss in the next
chapter is one of the essential frameworks you need to learn for building user
interface and animations. If you want to display a web page in your app, the
SDK also provides a built-in browser that lets you embed right in your
application.

You will have to equip yourself with knowledge on the above three areas. That's a
lot of stuff. But no worries. You'll learn the skills as you read through the book.

The Swift History


Let me start off by telling you a bit about the history of Swift.

In the Worldwide Developer Conference 2014, Apple surprised all iOS developers
by launching a new programming language called Swift. Swift is advertised as a
"fast, modern, safe, interactive" programming language. The language is easier to
learn and comes with features to make programming more productive.

Prior to the announcement of Swift, iOS apps were primarily written in Objective-
C. The language has been around for more than 30 years and was chosen by Apple
as the primary programming language for Mac and iOS development. I've talked to
many aspiring iOS developers. A majority of them said Objective-C was hard to
learn and its syntax looked weird. Simply put, the code scares some beginners off
from learning iOS programming.

The release of Swift programming language is probably Apple's answer to some of


these comments. The syntax is much cleaner and easier to read. I have been
programming in Swift since its beta release. It's more than 8 years for now. I can

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 40
say you're almost guaranteed to be more productive using Swift. It definitely
speeds up the development process. Once you get used to Swift programming, it
would be really hard for you to switch back to Objective-C.

It seems to me that Swift will lure more web developers or even novice to build
apps. If you're a web developer with some programming experience on any
scripting languages, you can leverage your existing expertise to gain knowledge on
developing iOS apps. It would be fairly easy for you to pick up Swift. Being that
said, even if you're a total beginner with no prior programming experience, you'll
also find the language friendlier and feel more comfortable to develop apps in
Swift.

In June 2015, Apple announced Swift 2, and that the programming language goes
open source. This is a huge deal. Since then, developers created some interesting
and amazing open source projects using the language. Not only can you use Swift
to develop iOS apps, companies like IBM developed web frameworks for you to
create web apps in Swift. Now you can run Swift on Linux too.

Following the release of Swift 2, Apple introduced Swift 3 in June 2016. This
version of the programming language, integrated into Xcode 8, was released in
Sep, 2016. This was considered as one of the biggest releases since the birth of the
language. There were tons of changes in Swift 3. APIs are renamed and more
features were introduced. All these changes helped to make the language even
better and enabled developers to write more beautiful code. That said, it took all
developers extra efforts to migrate their projects for these breaking changes.

In June 2017, Apple brought you Swift 4, along with the release of Xcode 9, with
even more enhancements and improvements. This version of Swift had a focus on
backward compatibility. That meant ideally projects developed in Swift 3 could be
run on Xcode 9 without any changes. Even if you had to make changes, the
migration from Swift 3 to 4 would be much less cumbersome than that from 2.2 to
3.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 41
In the following year, Apple only released a minor update for Swift, pushing Swift's
version number to 4.2. Even though it's not a major release, the new version also
came with a lot of language features to improve productivity and efficiency.

In late March 2019, Apple officially released Swift 5, which is a major milestone of
the programming language. While it includes many new features, the most
important change is that the Swift runtime is now included in Apple’s platform
operating systems including iOS, macOS, watchOS, and tvOS. Actually, it's a good
news for aspiring developers. This means the Swift language is more stable and
mature. Everything you learn in this book will apply to the future release of Swift.

This year, the Swift language is further updated to Swift 5.9 with even more
features such as macros.

If you're a total beginner, you may have a couple of questions in mind. Why does
Swift keep changing? If it keeps updating, is Swift ready for use?

Nearly all programming languages change over time. The same is for Swift. New
language features are added to Swift every year to make it more powerful and
developer friendly. It is somewhat similar to our spoken languages. Let's say, for
English, it still changes over time. New vocabulary and phrases such as freemium
are added to the dictionary every year.

All languages change over time, and there can be many different reasons for
this. The English language is no different.

Source: https://www.english.com/blog/english-language-has-changed

While Swift keeps evolving, it doesn't mean it is not ready for production use.
Instead, if you are going to build an iOS app, you should build it in Swift. It has
become a de facto standard for iOS app development. Companies such as
LinkedIn, Duolingo and Mozilla had already written apps entirely in Swift since its
early versions. Since the release of Swift 4, the programming language is more
stable and definitely ready for enterprises and production uses.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 42
Let's Get Started
Enough for the background and history. Let's begin to look into Swift.

To get a taste of Swift programming language, let's take a look at the following
code snippets.

Objective-C

const int count = 10;


double price = 23.55;

NSString *firstMessage = @"Swift is awesome. ";


NSString *secondMessage = @"What do you think?";
NSString *message = [NSString stringWithFormat:@"%@%@", firstMessage, seco
ndMessage];

NSLog(@"%@", message);

Swift

let count = 10
var price = 23.55

let firstMessage = "Swift is awesome. "


let secondMessage = "What do you think?"
var message = firstMessage + secondMessage

print(message)

The first block of code was written in Objective-C, while the second one was
written in Swift. Which language do you prefer? I guess you would prefer to
program in Swift, especially if you're frustrated with the Objective-C syntax. It's

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 43
clearer and readable. There is no @ sign and semi-colon at the end of each
statement. Both statements below concatenate the first and second messages
together. I believe you can probably guess the meaning of the following Swift code:

var message = firstMessage + secondMessage

but find it a bit confusing for the Objective-C code below:

NSString *message = [NSString stringWithFormat:@"%@%@", firstMessage, seco


ndMessage];

Trying out Swift in Playgrounds


I don't want to bore you by just showing you the code. There is no better way to
explore coding than actually writing code. Xcode has a built-in feature called
Playgrounds. It's an interactive development environment for developers to
experiment Swift programming and allows you to see the result of your code in
real-time. You will understand what I mean and how Swift Playgrounds works in a
while.

Assuming you've installed Xcode 15 (or up), launch the application (by clicking the
Xcode icon in Launchpad). You should see a startup dialog.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 44
Figure 2-1. The startup dialog

A Playground is a special type of Xcode file. In the top menu, click File > New >
Playground... to create a new Playground file. You'll then be prompted to select a
template for your playground. Since we focus on exploring Swift in iOS
environment, choose Blank under the iOS section to create a blank file. Click Next
to continue.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 45
Figure 2-2. Creating a Playground file

Once you confirm to save the file, Xcode opens the Playground interface. Your
screen should like this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 46
​ On the left pane of the screen, it is the editor area where you type the code. When
you want to test your code and see how it works, hit the Play button. Playground
immediately interprets the code (up to the line of the Play button) and displays the
result on the right pane. By default, Swift Playgrounds includes two lines of code.
As you can see, the result of the greeting variable appears immediately on the
right pane after you hit the Play button at line 4.

We'll write some code in Playgrounds together. Remember the purpose of this
exercise is to let you experience Swift programming and learn its basics. I will not
cover every feature of Swift. We will only focus on these topics:

1. Constants, variables and type inference


2. Control flow
3. Collection types like arrays and dictionaries
4. Optionals

These are the basic topics that you need to know about Swift. You will learn by
example. However, I'm quite sure you will be confused by some of the
programming concepts, especially you are completely new to programming. No

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 47
worries. You will find my study advice in some sections. Just follow my advice and
keep studying. And, don't forget to take a break when you're stuck.

Cool! Let's get started.

Constants and Variables


Constants and variables are two basic elements in programming. The concept of
variables (and constants) is similar to what you learned in Mathematics. Take a
look at the equation below:

x = y + 10

Here, both x and y are variables. 10 is a constant, meaning that its value is
unchanged.

In Swift, you declare variables with the var keyword and constants using the let

keyword. If you write the above equation in code, here is what it looks like:

let constant = 10
var y = 10
var x = y + constant

Type the code above in Playgrounds and then hit Play at line 5. You will see the
result below.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 48
Figure 2-4. The result of the equation

You can choose whatever name for variables and constants. Just make sure they
are meaningful. For example, you can rewrite the same piece of code like this:

let constant = 10
var number = 10
var result = number + constant

To make sure that you clearly understand the difference between constants and
variables in Swift, type the following code to change the values of constant and
number :

constant = 20
number = 50

After that, press shift+command+enter to execute the code. Other than using the
Play button, you can use the shortcut keys to run the code.

You simply set a new value for the constant and variable. But as soon as you
change the value of the constant, Xcode gives you an error in the console.
Conversely, there is no issue for number .

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 49
Figure 2-5. Errors in Playgrounds

This is the core difference between constants and variables in Swift. Once a
constant is initialized with a value, you can't change it. If you have to change the
value after initialization, use variables.

Understanding Type Inference


Swift provides developers with a lot of features to write clean-looking code. One
feature is known as Type Inference. The same code snippet we just discussed
above can be explicitly written as follows:

let constant: Int = 10


var number: Int = 10
var result: Int = number + constant

Each variable in Swift has a type. The keyword Int after colon ( : ) indicates the
type of the variable/constant is an integer. If the value stored is a decimal number,
we use the type Double .

var number: Double = 10.5

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 50
There are other types like String for textual data and Bool for boolean values
(true/false).

Now back to Type Inference, this powerful feature in Swift allows you to omit the
type when declaring a variable/constant to make your code look cleaner. The Swift
compiler can deduce the type by examining the default value given by you. This is
why we can write the code like this earlier:

let constant = 10
var number = 10
var result = number + constant

The given value (i.e. 10 ) is an integer, so the type is automatically set to Int . In
Playgrounds, you can hold the option key, and click any variable name to reveal
the variable type, deduced by the compiler.

Figure 2-6. Hold option key and select the variable to reveal its type

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 51
Feeling overwhelmed by all the new programming concept?

Just a take a break. You don't have to go through this chapter without a rest.
You can even skip this chapter and read the next one if you can't wait to build
your first app. You can always come back to this chapter to study the basics of
Swift.

Working with Text


So far, we only work with variables of the type Int and Double . To store textual
data in variables, Swift provides a type called String .

To declare a variable of the type String , you use the var keyword, give the
variable a name and assign the variable with the initial text. The text specified is
surrounded by double quotes ( " ). Here is an example:

var message = "The best way to get started is to stop talking and code."

After you key in the line of code above in Playgrounds and hit Play, you will see the
result on the right pane.

Figure 2-7. The string is shown immediately on the right pane

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 52
Swift provides different operators and functions (or methods) for you to
manipulate strings. For example, you can use the addition ( + ) operator to
concatenate two strings together:

var greeting = "Hello "


var name = "Simon"
var message = greeting + name

Figure 2-8. String concatenation

What if you want to convert the whole sentence into upper case? Swift provides a
built-in method named uppercased() to convert a string to upper case. You can
type the following code to have a try:

message.uppercased()

Xcode's editor comes with an auto-complete feature. Auto-complete is a very


handy feature to speed up your coding. As soon as you type mess , you'll see an
auto-complete window showing some suggestions based on what you have keyed
in. All you need to do is to select message and hit enter.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 53
​ Swift employs the dot syntax for accessing the built-in methods and the properties
of a variable. As you type the dot after message , the auto-complete window pops
out again. It suggests a list of methods and properties that can be accessed by the
variable. You can continue to type uppercase() or select it from the auto-complete
window.

​ Once you complete your typing, you would see the output immediately. When we
use uppercased() on message , the content of message is converted to upper case
automatically.

uppercased() is just one of the many built-in functions of a string. You can try to
use lowercased() to convert the message to lower case.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 54
message.lowercased()

Or if you want to count the number of characters of the string, you can write the
code like this:

message.count

Figure 2-11. Manipulating a string using the built-in functions

String concatenation looks really easy, right? You just add two strings together
using the + operator. However, it is not always trivial. Let's write the following
code in Playgrounds:

var bookPrice = 39
var numOfCopies = 5
var totalPrice = bookPrice * numOfCopies
var totalPriceMessage = "The price of the book is $" + totalPrice

It is quite usual to create a string that mixes both a string and a number. In the
example above, we calculate the total price of the books, and create a message that
shows the total price to the user. If you have typed the code in Playgrounds, you

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 55
will notice an error.

Figure 2-12. Debug area/Console

When Xcode finds an error in your code, the error is indicated by a red
exclamation mark with a brief error message. Sometimes, Xcode shows you the
possible fixes of the errors. But sometimes it does not.

To reveal the error details, you can refer to the debug area/console. If the console
doesn't show up in your Playground, click the debug area button at the top-right
corner.

Before I show you the solution, do you know why the code doesn't work? Give
yourself a few minutes to think about that.

First, always remember that Swift is a type-safe language. This means each
variable has a type that specifies what kind of values it can store. Let me ask you:
what is the type of totalPrice ? Recall what we learned earlier, Swift can
determine the type of a variable by examining its value.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 56
Since 39 is an integer, Swift determines that bookPrice has a type of Int , so
does numOfCopies and totalPrice .

The error message displayed in the console mentioned that the operator + cannot
concatenate a String variable with an Int variable. They must have the same
type. In other words, you have to convert totalPrice from Int to String in
order to make it work.

You can write the code like this by converting the integer to a string:

var totalPriceMessage = "The price of the book is $" + String(totalPrice)

There is an alternate way known as String Interpolations to do that. You can write
the code like this to create the totalPriceMessage variable:

var totalPriceMessage = "The price of the book is $ \(totalPrice)"

String interpolations is the recommended way to build a string from multiple


types. You wraps the variable for string conversion in parentheses, prefixed by a
backslash.

After making the changes, re-run the code by hitting the Play button. The error
should be fixed.

Control Flow Basics

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 57
As far as the confidence goes, I think you will appreciate that it is not because
you succeeded at everything you did, but because with the help of your
friends, you were not afraid to fail. And if you did fail, you got up and tried
again. And if you failed again, you got up and tried again. And if you failed
again, it might be time to think about doing something else. But it was not
just success, but not being afraid to fail that brought you to this point.

- John Roberts, Chief Justice of the United States

Source: http://time.com/4845150/chief-justice-john-roberts-
commencement-speech-transcript/

Every day we make numerous decisions. Different decisions lead to different


outcomes or actions. For example, you decide if you can wake up at 6AM
tomorrow, you will cook yourself a big breakfast. Otherwise, you will go out for
breakfast.

When writing programs, you use if-then and if-then-else statements to


examine a condition and determine what to do next. If you turn the example above
into code, it will be like this:

var timeYouWakeUp = 6

if timeYouWakeUp == 6 {
print("Cook yourself a big breakfast!")
} else {
print("Go out for breakfast")
}

You declare a variable timeYouWakeUp to store the time (in 24-hour) you wake up.
You use if statement to evaluate a condition and determine what to next. The
condition is placed after the if keyword. Here we compare the value of
timeYouWakeUp to see if it equals 6 . The == operator is used for comparison.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 58
If timeYouWakeUp does match 6 , the actions (or statements) enclosed in the curly
brackets are executed. In the code, we simply use the print function to print a
message to console.

Otherwise, the statements specified in the else block will be run to print another
message.

Figure 2-13. An example of If statement

In Playgrounds, you will see the message "Cook yourself a big breakfast!" in the
console because the value of timeYouWakeUp is initialized to 6 . You can try to
change it to other values and see what you get.

Conditional logic is very common in programming. Imagine you are developing a


login screen that requires users to input the username and password. The user can
only be logged into the app with a valid account. In this case, you may use if-else

statement to verify the username/password.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 59
The if-else statement is one of the ways in Swift to control program flow. Swift
also provides switch statements to control which code block to run. You can
rewrite the example above using switch .

var timeYouWakeUp = 6

switch timeYouWakeUp {
case 6:
print("Cook yourself a big breakfast!")
default:
print("Go out for breakfast")
}

It will achieve the same result if timeYouWakeup is set to 6 .A switch statement


considers a value (here, it is the value of timeYouWakeUp ), and compare with the
value specified in the case . The default case is indicated by the default keyword.
It is very much like the else block in the if-else statement. If the value being
evaluated doesn't match any of the cases, the default case will be executed. So if
you change the value of timeYouWakeUp to 8 , it will display the message "Go out
for breakfast."

There is no universal rule about when to use if-else and when to use switch .
Sometimes, we prefer one over the other just because of readability. Let's say, you
typically get a bonus at the end of each year. Now you are making a plan for your
next travel destination. Here is the plan:

If you get a bonus of $10000 (or more), you will travel to Paris and London.
If the bonus is between $5000 and $9999, you will travel to Tokyo.
If the bonus is between $1000 and $4999, you will travel to Bangkok.
If the bonus is less than $1000, you just stay home.

If you write the above plan in code, it looks like this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 60
var bonus = 5000

if bonus >= 10000 {


print("I will travel to Paris and London!")
} else if bonus >= 5000 && bonus < 10000 {
print("I will travel to Tokyo")
} else if bonus >= 1000 && bonus < 5000 {
print("I will travel to Bangkok")
} else {
print("Just stay home")
}

>= is a comparison operator, indicating "greater than or equal to". The first if

condition checks if the value of bonus is greater than or equal to 10000 . To


specify two simultaneous conditions, you use && operator. The second if

condition checks if the value is between 5000 and 9999. The rest of the code
should be self explanatory.

You can rewrite the same piece of code using a switch statement like below:

var bonus = 5000

switch bonus {
case 10000...:
print("I will travel to Paris and London!")
case 5000...9999:
print("I will travel to Tokyo")
case 1000...4999:
print("I will travel to Bangkok")
default:
print("Just stay home")
}

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 61
Swift has a very handy range operator ( ... ) that defines a range from lower
bound to upper bound. For example, 5000...9999 defines a range that runs from
5000 to 9999. For the first case, 10000... indicates a value that is great than
10000.

Both code blocks work exactly the same, but which way do you prefer? In this case,
I prefer the switch statement which makes the code clearer. Anyway, even if you
prefer to use if statement for the problem above, it is still correct. As you
continue to explore Swift programming, you will understand when to use if or
switch .

Understanding Arrays and Dictionaries


Now that you have a very basic knowledge of variables and control flow, let me
introduce another programming concept that you will usually work with.

So far, the variables that we used can only store a single value. Referring to the
variables in the earlier code snippet, bonus , timeYouWakeUp and totalPriceMessage

can hold a single value, regardless of the variable type.

Let's consider this example. Imagine you are creating a bookshelf application that
organizes your book collection. In your program, you will probably have some
variables holding your book titles:

var book1 = "Tools of Titans"


var book2 = "Rework"
var book3 = "Your Move"

Instead of storing a single value in each variable, is there any way to store more
than one value in it?

Swift provides a collection type known as Array that lets you store multiple values
in a variable. With an array, you can store your book titles like this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 62
var bookCollection = ["Tool of Titans", "Rework", "Your Move"]

You can also initialize an array by writing a list of values, separated by commas,
surrounded by a pair of square brackets. Again, since Swift is a type-safe language,
all values should be of the same type (e.g. String).

Accessing the values of an array may look weird to you if you just begin to learn
programming. In Swift, you use the subscript syntax to access the array elements.
The index of the first item is zero. Therefore, to refer to the first item of an array,
you write the code like this:

bookCollection[0]

If you type the code above in Playgrounds and hit Play, you should see "Tool of
Titans" shown in the result pane.

When you declare an array as var , you can modify its elements. For example, you
can add a new item to the array by calling the built-in method append like this:

bookCollection.append("Authority")

Now the array has 4 items. How can you reveal the total number of items of an
array? Use the built-in count property:

bookCollection.count

Let me ask you, how can you print the value of each item of the array to console?

Don't look at the solution yet.

Try to think.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 63
Okay, probably you will write the code like this:

print(bookCollection[0])
print(bookCollection[1])
print(bookCollection[2])
print(bookCollection[3])

It works. But there is a better way to do it. As you can see, the code above is
repetitive. If the array has 100 items, it will be quite tedious to type a hundred lines
of code. In Swift, you use a for-in loop to execute a task (or a block of code) for a
specific number of time. For example, you can simplify the code above like this:

for index in 0...3 {


print(bookCollection[index])
}

You specify the range of number ( 0...3 ) to iterate over. In this case, the block of
code in the for loop is executed for 4 times. The value of index will be changed
accordingly. When the for loop is first started to execute, the value of index is
set to 0 and it will print bookCollection[0] . After the statement is executed, the
value of index will be updated to 1 , and it will print bookCollection[1] . This
process continues until the end of the range (i.e. 3 ) is reached.

Now I have a question for you. What if there are 10 items in the array? You
probably change the range from 0...3 to 0...9 . How about later the total
number of items are increased to 100? Then you will change to range to 0...99 .

Is there a generic way to do that, instead of updating the code every time the total
number of items changes?

Do you notice a pattern for these ranges: 0...3 , 0...9 and 0...99 ?

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 64
The upper bound of the range equals to the total number of items minus 1. You can
actually rewrite the code like this:

for index in 0...bookCollection.count - 1 {


print(bookCollection[index])
}

Now regardless of the number of array items, this code snippet works.

Swift's for-in loop offers an alternate way to iterate over an array. The sample
code snippet can be rewritten as follows:

for book in bookCollection {


print(book)
}

When the array (i.e. bookCollection ) is iterated, the item of each iteration will be
set to the book constant. When the loop is first started, the first item of
bookCollection is set to book . In the next iteration, the second item of the array
will be assigned to book . The process keeps going until the last item of the array is
reached.

Now that I believe you understand how for-in loop works and how you can
repeat a task using loop, let's talk about another common collection type called
dictionary.

A dictionary is similar to an array that allows you to store multiple values in a


variable/constant. The main difference is that each value in a dictionary is
associated with a key. Instead of identifying an item using an index, you can access
the item using a unique key.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 65
Let me continue to use the book collection as an example. Each book has a unique
ISBN (short for International Standard Book Number). If you want to index each
book in the collection by its ISBN, you can declare and initialize a dictionary like
this:

var bookCollectionDict = ["1328683788": "Tool of Titans", "0307463745": "R


ework", "1612060919": "Authority"]

The syntax is very similar to an array initialization. All values are surrounded by a
pair of square brackets. The key and value pair is separated by a colon ( : ). In the
sample code, the key is the ISBN. Each book title is associated with a unique ISBN.

So how can you access a particular item? Again, it is very similar to array.
However, instead of using a numeric index, you use the unique key. Here is an
example:

bookCollectionDict["0307463745"]

This gives you the value: Tool of Titans. To iterate over all items of the dictionary,
you can also use the for-in loop:

for (key, value) in bookCollectionDict {


print("ISBN: \(key)")
print("Title: \(value)")
}

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 66
Figure 2-14. Iterate over a dictionary

As you may reveal from the message in the console, the order of the items doesn't
follow the order in the initialization. Unlike an array, this is a characteristic of
dictionaries that stores items in an unordered fashion.

You may still wonder when you will need to use a dictionary when building an app.
Let's take a look another example. There is a reason why it is known as a
dictionary. Think about how you use a dictionary, you look up a word in a
dictionary, and it gives you the word's meaning. In this case, the word is the key,
and its meaning is the associated value.

Before you move onto the next section, let's have a very simple exercise to create
an Emoji dictionary, which stores the meaning of emoji characters. To keep things
simple, this dictionary has the meaning of the following emoji characters:

- Ghost
- Poop
- Angry

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 67
- Scream
- Alien monster

Do you know how to implement the emoji dictionary using the Dictionary type?
Below is the code skeleton for the emoji dictionary. Please fill in the missing code
to make it work:

var emojiDict = // Fill in the code for initializing the dictionary //

var wordToLookup = // Fill in the Ghost emoji //


var meaning = // Fill in the code for accessing the value //

wordToLookup = // Fill in the Angry emoji //


meaning = // Fill in the code for accessing the value //

To type an emoji character on Mac, press control-command+space.

Are you able to complete the exercise?

Let's take a look at the solution and the output in figure 2-16.

Figure 2-16. Solution to the emoji dictionary exercise

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 68
I believe you can figure out the solution by yourself.

Now let's add a couple of lines of code to print the meaning variable to console.

Figure 2-16. Print the meaning variable

You will notice two things:

1. Xcode indicates both print statements have some issues.


2. The output in the console area looks a bit different from other output we went
through before. The result is correct, but what does Optional mean?

Note: In Xcode, warnings are indicated in yellow. One main


difference between warnings and errors is that your
program can still be run even if it has some warnings. As
the name suggests, a warning gives you an advanced notice
of some issues. You better fix the warnings to avoid any
potential issues.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 69
Both issues are related to a new concept in Swift called Optionals. Even if you
have some programming background, this concept may be new to you.

I hope you enjoy what you've learned so far. But if you are feeling stuck, take
a break here. Grab a coffee and relax. Or you can even skip the rest of the
chapter and try to build your first app in the next chapter. You can always
revisit this chapter anytime.

Understanding Optionals
Do you have such experience? You open an app, tap a few buttons, and it suddenly
crashes. I am quite sure you have experienced that.

Why does an app crash happen? One common cause is that the app tries to access
a variable that has no value at runtime. Then the unexpected happens.

So is there a way to prevent the crashes?

Different programming languages have different strategies to encourage


programmers to write good code or less-error-prone code. The introduction of
Optionals is Swift's way to help programmers write better code, thus prevent app
crashes.

Some developers struggle to understand the concept of Optionals. The


fundamental idea is actually quite simple. Before accessing a variable that may
have no value, Swift encourages you to verify it first. You have to make sure it has a
value before any further processing. Thus, this can avoid app crashes.

Up till now, all the variables or constants we worked with have an initial value.
This is a must in Swift. A non-optional variable guarantees to have a value. If you
try to declare a variable without a value, you get an error. You can give it a try in
Playgrounds and see what happens.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 70
Figure 2-17. Declaring a variable/constant without an initial value

In some situations, you have to declare a variable without an initial value. Imagine,
you are developing an app with a registration form. Not all fields in the form is
mandatory, some fields (e.g. job title) are optional. In this case, the variables of
those optional fields may have no values.

Technically, optional is just a type in Swift. This type indicates that the variable can
have a value or no value. To declare a variable as an optional, you indicate it by
appending a question mark ( ? ). Here is an example:

var jobTitle: String?

You declare a variable named jobTitle which is of type String and it is also an
optional. If you place the code above in Playgrounds, it will not show an error
because Xcode knows that jobTitle can have no value.

Unlike a non-optional variable that the compiler can deduce the type from its
initial value, you have to explicitly specify the type of an optional variable (e.g.
String , Int ).

If you have followed my instruction to enter the code in Playgrounds (and hit
Play), you may notice that nil is displayed in the resulting pane. For any optional
variable with no value, a special value called nil is assigned to it.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 71
Figure 2-18. A special value "nil" is assigned to an optional variable with no value

In other words, nil indicates the variable does not have a value.

If you have to assign a value to an optional variable, you can just do that as usual
like this:

jobTitle = "iOS Developer"

Now that you should have some knowledge of optionals, but how can it help us
write better code?

Try to key in the code as displayed in figure 2-19.

Figure 2-19. An error is shown when you access an optional variable

As soon as you complete typing the following line of code, Xcode indicates it by
giving an error message.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 72
var message = "Your job title is " + jobTitle

Here jobTitle was declared as an optional variable. Xcode told you that there was
a potential error for that line of code because jobTitle might have no value. You
have to do some checkings before using the optional variable.

This is how optionals can prevent you from writing bad code. Whenever you need
to access an optional variable, Xcode forces you to perform verification to find out
whether the optional has a value.

Forced Unwrapping
So how can you perform such verification and unwrap the value of the optional
variable? Swift offers a couple of ways to do that.

First, it is known as if statements and forced unwrapping. In simple words, you


use a if statement to check if the optional variable has a value by comparing it
against nil . If the optional does have a value, you unwrap its value for further
processing.

This is how it looks like in code:

if jobTitle != nil {
var message = "Your job title is " + jobTitle!
}

The != operator means "not equal". So if jobTitle does not equal to nil , it
must have a value. You can then execute the statements in the body of if

statement. When you need to access the value of jobTitle , you add an
exclamation mark ( ! ) to the end of the optional variable. This exclamation mark
is a special indicator, telling Xcode that you ensure the optional variable has a
value, and it is safe to use it.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 73
Optional Binding
Forced unwrapping is one way to access the underlying value of an optional
variable. The other way is called optional binding, and it is the recommended way
to work with optionals. At least, you do not need to use ! .

If optional binding is used, the same code snippet can be rewritten like this:

if let jobTitleWithValue = jobTitle {


var message = "Your job title is " + jobTitleWithValue
}

You use if let to find out whether jobTitle has a value. If yes, the value is
assigned to the temporary constant jobTitleWithValue . In the code block, you can
use jobTitleWithValue as usual. As you can see, there is no need to add the !

suffix.

Do you have to give a new name for the temporary constant?

No, you can actually use the same name like this:

if let jobTitle = jobTitle {


var message = "Your job title is " + jobTitle
}

Note: Even though the names are the same, there are
actually two variables in the code above. jobTitle in
black is the optional variable, while jobTitle in blue is
the temporary constant to be assigned with the optional
value.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 74
This is pretty much about Swift's optionals. Are you confused by various ? and
! symbols? I hope you do not. In case you are struggled to understand optionals,
post your questions to our Facebook group
(https://facebook.com/groups/appcoda).

Okay, do you still remember the warning displayed in figure 2-16? When you tried
to print the value of meaning , Xcode gave you some warnings. In console, even
though the value was printed, it was prefixed by "Optional".

Figure 2-20. Same as figure 2-16 showing you the warning messages

Now can you figure out why? Why the meaning variable is an optional? How can
you modify the code to remove the warning messages?

Again, don't look at the solution yet. Think.

If you look into the code, meaning is actually an optional. It is because the
dictionary may not have a value for the given key. For example, if you write this
code in Playgrounds:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 75
The meaning variable will be assigned with nil because emojiDict doesn't have a
value for the key .

Therefore, whenever we need to access the value of meaning , we have to check if it


has a value. To avoid the warning messages, we can use optional binding to test the
existence of the value.

Figure 2-21. Use optional binding to check if meaning has a value and unwrap it
accordingly

After you made the changes, the warning messages disappears. You also notice
that the values displayed in the console is no longer prefixed with Optional.

Playing around with UI

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 76
Before I close this chapter, let's have some fun to create some UI elements. What
we are going to do is to display the emoji icon and its corresponding meaning in a
view (see figure 2-22).

Figure 2-22. Displaying emoji in a view

As I mentioned at the very beginning of the chapter, other than learning Swift, you
will need to familiarize yourself with frameworks provided by the iOS SDK. One of
the essential frameworks is SwiftUI, which allows you to create interactive UIs.

You can also use Playgrounds to explore some of the UI controls, provided by the
SwiftUI framework. Now key in the code as displayed the figure below and then hit
Play to run the code.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 77
Figure 2-23. Render a view using SwiftUI

This should give you a taste of SwiftUI. You just made use of the SwiftUI
framework to render a view and some text labels on screen.

A view is the basic UI element in iOS. You can think of it as a rectangular area that
is used for showing content. The ContentView is our custom version of a generic
View . Inside the view, we add two text elements to display the emoji icon and the
label. We also change the background of the view to orange.

The following line of code is used to preview the UI in Playgrounds:

PlaygroundPage.current.setLiveView(ContentView())

This is the power of SwiftUI and iOS SDK. It comes with tons of pre-built elements
and allows developers to customize them with few lines of code.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 78
I guess you may not fully understand the SwiftUI code. No worries. I just want to
give you a very quick introduction to SwiftUI. We will walk you through some of
the most common SwiftUI components in the next chapter.

What's Next
Now you've got a taste of Swift. What do you think? Love it? I hope you find Swift
beginner friendly and this chapter won't scare you away from learning app
development.

What's coming up is that I will teach to build your first app using SwiftUI. You can
now move onto the next chapter. However, if you want to learn more about the
Swift programming language, I would recommend you to check out Apple's official
Swift Programming Language guide (https://docs.swift.org/swift-book/). You will
learn the language syntax, understand functions, optionals, and many more.

But it's not a must.

If you can't wait to build your first app, flip it over to the next chapter, and read the
guide later. You can learn more about Swift along the way.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 79
Chapter 3
Build Your First App in Swift and
SwiftUI

Learn by doing. Theory is nice but nothing replaces actual experience.

– Tony Hsieh

By now, you should have installed Xcode and gained some understanding of Swift.
If you have skipped the first two chapters, I urge you to pause here and go back to
read them. It is essential to have Xcode installed to complete all the exercises in
this book.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 80
In the previous chapter, you experimented with creating UI components using
SwiftUI. In this chapter, we will delve deeper and provide you with a
comprehensive introduction to the SwiftUI framework. Additionally, you will have
the opportunity to develop your very first iOS app.

An Introduction to SwiftUI
In WWDC 2019, Apple surprised every developer by announcing a completely new
framework called SwiftUI. It doesn't just change the way you develop iOS apps.
This is the biggest shift in the Apple developer's ecosystem (including iPadOS,
macOS, tvOS, and watchOS) since the debut of Swift.

SwiftUI is an innovative, exceptionally simple way to build user interfaces


across all Apple platforms with the power of Swift. Build user interfaces for
any Apple device using just one set of tools and APIs.

- Apple (https://developer.apple.com/xcode/swiftui/)

Developers have been debating for a long time whether we should visually design
the app UI or write the UI in code. Apple has responded to this discussion with the
introduction of SwiftUI. With this innovative framework, Apple presents
developers with a fresh method for crafting user interfaces. Please refer to the
figure below for a visual representation and take a moment to examine the
accompanying code.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 81
Figure 3-1. Programming in SwiftUI

With the release of SwiftUI, you can now develop the app's UI with a declarative
Swift syntax. This signifies that the process of writing UI code becomes simpler
and more intuitive. In comparison to established UI frameworks such as UIKit,
you can achieve the same UI design with significantly less code.

Declarative vs Imperative Programming


Similar to Java, C++, PHP, and C#, Swift is an imperative programming language.
However, SwiftUI distinguishes itself proudly as a declarative UI framework,
allowing developers to create UI in a declarative manner. But what exactly does
"declarative" mean? How does it differ from imperative programming? More
importantly, how does this change impact your coding approach?

For those who are new to programming, the distinction may not be of immediate
concern, as everything is new to you. However, if you have experience in object-
oriented programming or have previously worked with UIKit, this paradigm shift

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 82
significantly influences your approach to building user interfaces. It may require
unlearning certain old concepts and acquiring new ones.

So, what's the difference between imperative and declarative programming? If you
go to Wikipedia and search for the terms, you will find these definitions:

In computer science, imperative programming is a programming


paradigm that uses statements that change a program's state. In much the
same way that the imperative mood in natural languages expresses
commands, an imperative program consists of commands for the computer
to perform.

In computer science, declarative programming is a programming


paradigm—a style of building the structure and elements of computer
programs—that expresses the logic of a computation without describing its
control flow.

It's pretty hard to understand the actual difference, especially without a


background in computer science. Let me explain the difference using a relatable
analogy.

Instead of focusing on programming, let's talk about cooking a pizza (or any dishes
you like). Let’s assume you are instructing someone else (a helper) to prepare the
pizza, you can either do it imperatively or declaratively. To cook the pizza
imperatively, you tell your helper each of the instructions clearly like a recipe:

Rather than delving into programming directly, let's consider the process of
cooking a pizza (or any dish of your preference). Suppose you are providing
instructions to someone else (say, your helper) to prepare the pizza. In this
scenario, you have the option to guide them either imperatively or declaratively.
When cooking the pizza imperatively, you would provide your helper with explicit
instructions, akin to a step-by-step recipe like this:

1. Heat the over to 550°F or higher for at least 30 minutes

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 83
2. Prepare one-pound of dough
3. Roll out the dough to make a 10-inch circle
4. Spoon the tomato sauce onto the center of the pizza and spread it out to the
edges
5. Place toppings (including onions, sliced mushrooms, pepperoni, cooked
sausage, cooked bacon, diced peppers and cheese) on top of the sauce
6. Bake the pizza for 5 minutes

On the other hand, if you opt to cook the pizza in a declarative manner, you
wouldn't need to provide step-by-step instructions. Instead, you would simply
describe how you want the pizza to be cooked. Would you prefer a thick or thin
crust? Do you want toppings like pepperoni and bacon, or a classic Margherita
with tomato sauce? Should the pizza be 10 inches or 16 inches in diameter? By
conveying your preferences, the helper can take care of the rest and cook the pizza
accordingly.

That's the core difference between the term imperative and declarative. Now back
to UI programming. Imperative UI programming requires developers to write
detailed instructions to layout the UI and control its states. Conversely, declarative
UI programming enables developers to describe the appearance of the UI and how
it should respond to state changes.

The declarative way of coding would make the code much easier to read and
understand. Moreover, the SwiftUI framework empowers you to write
considerably less code when creating a user interface. For instance, imagine you
are tasked with building a heart-shaped button in an app. This button should be
positioned at the center of the screen and be responsive to user touches. When a
user taps the heart button, its color should transition from red to yellow.
Additionally, when the user taps and holds the heart, it should scale up with an
animation.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 84
Figure 3-2. The implementation of an interactive heart button

Take a look at figure 3-2. That's the code you need to implement the heart button.
In around 20 lines of code, you create an interactive button with a scale animation.
This is the power of the SwiftUI declarative UI framework.

Building Your First App Using SwiftUI


That's enough for the background information of the SwiftUI framework. As I
always said, you have to get your hands dirty to learn programming. Now it's time
to fire up Xcode and write your first iOS app in SwiftUI. For the rest of the chapter,
you will write code to try out different UI components such as Text, Image, Stack
Views. Furthermore, you will learn how to detect tap gesture. By combining all the
techniques, you will eventually build your first app.

First, fire up Xcode and create a new project using the App template under the iOS
category. Choose Next to proceed to the next screen.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 85
Figure 3-3. Choose the App template

Next, set the name of the project to HelloWorld. Hello World is a program for the
first-time programmer to create. It's a very simple program that outputs "Hello,
World" on the screen of a device. While your first app will be more complicated
than that, let's follow the programming tradition and name the project
"HelloWorld".

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 86
Figure 3-4. Fill in the project options

The organization identifier is a unique identifier of your app. Here I use


com.appcoda but you should set it to your own value. If you have a website, set it
to your domain in reverse domain name notation. Otherwise, you may use "com.".
For instance, your name is Pikachi. Fill in the organization identifier as
"com.pikachi".

Xcode now supports two ways to build user interface. Since this book is about
SwiftUI, please set the Interface option to SwiftUI. For the programming
language, you can set it to Swift.

For the Include Tests options, you can leave it unchecked.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 87
Click "Next" to continue. Xcode then asks you where to save the "HelloWorld"
project. Pick any folder (e.g. Desktop) on your Mac. You may notice there is an
option for source control. Just deselect it. Meanwhile, we do not need to use the
option. Click "Create" to continue.

After you confirm, Xcode automatically creates the "Hello World" project. The
screen will look like the screenshot shown in figure 3-5.

Figure 3-5. Xcode workspace with source code editor and preview pane

Familiarize Yourself with Xcode Workspace


Before we start to implement the Hello World app, let's take a few minutes to have
a quick look at the Xcode workspace environment. In the left pane is the project
navigator. You can find all your project files in this area. The center part of the

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 88
workspace is the editor area. You do all the editing stuff here (such as editing the
project setting, source code file, user interface) in this area.

Depending on the type of file, Xcode shows you different interfaces in the editor
area. For instance, if you select HelloWorldApp.swift in the project navigator,
Xcode displays the source code in the center area. Xcode comes with several
themes for you to choose from. Say, if you prefer dark themes, you can go up to the
menu and choose Xcode > Preferences > Themes to change it.

If you select the ContentView.swift file, Xcode automatically resizes the code editor
and displays an extra pane right next to it. This extra pane is the preview pane for
the ContentView . If you can't see the design canvas, you can go up to the Xcode
menu and choose Editor > Canvas to enable it.

The design canvas shows you the preview of your SwiftUI code. Xcode renders the
preview in a simulator that you choose in the simulator selection (e.g. iPhone 14/15
Pro).

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 89
Figure 3-6. Previewing the app

To give yourself more space for writing code, you can hide both the project
navigator and the inspector (see figure 3-6). If you want to resize the preview, use
the magnifying icons at the bottom-right corner.

Run Your App for the First Time


Until now, we haven't written a single line of code. The code in ContentView is
generated by Xcode. Before we write our own code, let's try to run the app using
the built-in simulator. This will give you an idea how to build and test your app in
Xcode. In the toolbar, you should see the Run button (i.e. Play button).

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 90
Figure 3-7. Test the app in a simulator

The Run button in Xcode is used to build an app and run it in the selected
simulator. In the example above, the Simulator is set to iPhone 15 Pro. If you click
the iPhone 15 Pro button, you'll see a list of available simulators such as iPhone SE
and iPhone 15 Pro Max. Let's use iPhone 15 Pro as the simulator and give it a try.

Once selected, you can click the Run button to load your app in the simulator.
Figure 3-7 shows the simulator of an iPhone 15 Pro. To terminate the app, simply
hit the Stop button in the toolbar.

Try to select another simulator (e.g. iPhone SE) and run the app. You will see
another simulator showing up on screen. The latest version of Xcode allows
developers to run multiple simulators simultaneously.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 91
Figure 3-8. Running multiple simulators at the same time

The simulator works pretty much like a real iPhone. You can click the home button
(or press shift-command-h) to bring up the home screen. It also comes with some
built-in apps. Just play around with it to familiarize yourself with Xcode and
simulator environment.

Working with Text


Now that you should be familiar with the Xcode workspace, it's time to check out
the SwiftUI code. The sample code generated in ContentView already shows you
how to display a single line of text. You initialize a Text object and pass to it the
text (e.g. Hello World) to display like this:

Text("Hello World")

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 92
The preview canvas then displays Hello World on screen. This is the basic syntax
for creating a text view. You're free to change the text to whatever value you want
and the canvas should show you the change instantaneously.

Figure 3-9. Changing the text

Changing the Font Type and Color


In SwiftUI, you can change the properties (e.g. color, font, weight) of a control by
calling methods that are known as Modifiers. Let's say, you want to bold the text.
You can use the modifier fontWeight and specify your preferred font weight (e.g.
.bold ) like this:

Text("Stay Hungry. Stay Foolish.").fontWeight(.bold)

You access the modifier by using the dot syntax. Whenever you type a dot, Xcode
will show you the possible modifiers or values you can use. For example, you will
see various font weight options when you type a dot in the fontWeight modifier.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 93
You can choose bold to bold the text. If you want to make it even bolder, use
heavy or black .

Figure 3-10. Attaching the fontWeight modifier

By calling fontWeight with the value .bold , it actually returns you a new view
that has the bolded text. What is interesting in SwiftUI is that you can further
chain this new view with other modifiers. Say, if you want to make the bolded text
a little bit bigger, you write the code like this:

Text("Stay Hungry. Stay Foolish.").fontWeight(.bold).font(.title)

The font modifier lets you change the font properties. In the code above, we
specify the title font type in order to enlarge the text. SwiftUI comes with several
built-in text styles including title, largeTitle, body, etc. If you want to further
increase the font size, replace .title with .largeTitle .

The code will be hard to read if we continue to chain more modifiers in the same
line of code. Therefore, we usually write the code in the following format by
breaking it into multiple lines:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 94
Text("Stay Hungry. Stay Foolish.")
.fontWeight(.bold)
.font(.title)

The functionality is the same but I believe you'll find the code above more easy to
read. We will continue to use this coding convention for the rest of this book.

The font modifier also lets you change the text design. Let's say, you want the
font to be rounded. You can write the font modifier like this:

.font(.system(.title, design: .rounded))

Here you specify to use the system font with title text style and rounded design.
The preview canvas should immediately respond to the change and show you the
rounded text.

Figure 3-11. Changing the font style

Working with Buttons


Button is another common UI components you need to know. It is a very basic UI
control which has the ability to handle users' touch, and trigger a certain action.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 95
To create a button using SwiftUI, you just need to use the code snippet below to
create a button:

Button {
// What to perform
} label: {
// How the button looks like
}

When creating a button, you need to provide two code blocks:

1. What action to perform - the code to perform after the button is tapped or
selected by the user.
2. How the button looks - the code block that describes the look & feel of the
button.

For example, if you just want to turn the Hello World label into a button, you can
update the code like this:

struct ContentView: View {


var body: some View {

Button {

} label: {
Text("Hello World")
.fontWeight(.bold)
.font(.system(.title, design: .rounded))
}

}
}

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 96
The Hello World text becomes a tappable button, even though we didn't specify
any follow-up actions. The text color is automatically changed to blue because this
is the default color for buttons in iOS.

Figure 3-12. Run the app to test the button

In the preview, you can tap the button to test it out. Though the button doesn't
perform any actions, you should see a blink effect when tapping the button.

Customizing the Button Style


Similar to Text , you can customize the color of the button by attaching some
modifiers. For example, you can attach the foregroundStyle and background

modifiers to make a purple button.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 97
Button {

} label: {
Text("Hello World")
.fontWeight(.bold)
.font(.system(.title, design: .rounded))
}
.foregroundStyle(.white)
.background(.purple)

After the change, your button should look like the figure below.

Figure 3-13. Changing the button's color

As you can see, the button doesn't look very good. Wouldn't it be great to add some
space around the text? To do that, you can use the padding modifier like this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 98
Figure 3-14. Attaching the padding modifier

SwiftUI also makes it very easy to create a button with rounded corners. You just
need to attach the clipShape modifier and set its value to
RoundedRectangle(cornerRadius: 20) like this:

.clipShape(RoundedRectangle(cornerRadius: 20))

The value of cornerRadius describes how rounded the corners of the button. A
larger value produces a more rounded corner, while a smaller value achieves a
shaper corner. You can change the corner radius to other values to see the effect.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 99
Figure 3-15. Creating a button with rounded corners

Adding the Button Action


A button is not useful if it doesn't perform any actions. Our objective is to make the
button speak when tapped, speaking the phrase "Hello World!"

This task may seem challenging, as it involves text-to-speech functionality.


However, Apple has made it remarkably simple, even for beginners.

As mentioned previously, the iOS SDK includes numerous remarkable frameworks


for developers to leverage. In our case, we are utilizing the SwiftUI framework to
build the user interface. To achieve text-to-speech functionality, we can rely on the
AVFoundation framework.

Before we can use the framework, we have to import it at the beginning of the
code. Right below import SwiftUI , insert the following import statement:

import AVFoundation

Next, declare a variable in ContentView to create and hold the speech synthesizer
(refer to figure 3-16):

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 100
let synthesizer = AVSpeechSynthesizer()

After that, update the code of Button like this:

Button {

let utterance = AVSpeechUtterance(string: "Hello World")


utterance.voice = AVSpeechSynthesisVoice(identifier: "com.apple.speech
.synthesis.voice.Fred")

synthesizer.speak(utterance)

} label: {
Text("Hello World")
.fontWeight(.bold)
.font(.system(.title, design: .rounded))
}
.padding()
.foregroundStyle(.white)
.background(.purple)
.clipShape(RoundedRectangle(cornerRadius: 20))

Here, we added 3 lines of code in the action block. That's the code you need to
instruct iOS to speak a piece of text for you. The first line of code specifies the text
(i.e. "Hello World"), while the second line of code sets the voice to British English.
The last line is to speak out the text with the chosen voice.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 101
Figure 3-16. Adding the action block for the button

To test the app, you need to run the app in a simulator. Click the Play button and
run the app. To test text-to-speech click the Hello World button to test out text-to-
speech.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 102
Figure 3-17. Running the Hello World in a simulator

Introducing Stack Views


Your first app works great, right? With just around 10 lines of code, you already
created an app that can translate text into speech. Presently, the button is designed
to speak "Hello World". What if you want to create another button, which speaks a
different sentence or words, above the Hello World button? How can you arrange
the UI layout?

SwiftUI provides a special type of views known as Stack Views for you to construct
complex user interfaces. More specifically, stack views lets you arrange multiple
views (or UI components) in vertical or horizontal direction. For example, if you
want to add a new button above the Hello World button, you can embed both
buttons in a VStack like this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 103
VStack {

// New Button

// Hello World Button


}

VStack is a vertical stack view for laying out views vertically. The order of the
views inside a VStack determines how the embedded views are arranged. In the
code above, the new button will be placed on the top of the Hello World button.

Now let's modify the actual code to see the changes in action. To embed the Hello
World button in a VStack , you can hold the control key and click Button . In the
context menu, choose Embed in VStack. Xcode then wraps the Hello World button
in a VStack view.

Figure 3-18. Embed the button in a VStack

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 104
Once you embedded the Hello World button in the VStack , duplicate the code of
the Hello World button to create the new button like this:

VStack {

Button {
let utterance = AVSpeechUtterance(string: "Hello Programming")
utterance.voice = AVSpeechSynthesisVoice(identifier: "com.apple.sp
eech.synthesis.voice.Fred")
synthesizer.speak(utterance)

} label: {
Text("Hello Programming")
.fontWeight(.bold)
.font(.system(.title, design: .rounded))
}
.padding()
.foregroundStyle(.white)
.background(.yellow)
.clipShape(RoundedRectangle(cornerRadius: 20))

Button {
let utterance = AVSpeechUtterance(string: "Hello World")
utterance.voice = AVSpeechSynthesisVoice(identifier: "com.apple.sp
eech.synthesis.voice.Fred")
synthesizer.speak(utterance)

} label: {
Text("Hello World")
.fontWeight(.bold)
.font(.system(.title, design: .rounded))
}
.padding()
.foregroundStyle(.white)
.background(.purple)
.clipShape(RoundedRectangle(cornerRadius: 20))
}

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 105
The label of the new button is changed to Happy Programming and its
background color is also updated to .yellow . On top of these changes, the string
parameter of AVSpeechUtterance is changed to "Happy Programming." You can
refer to figure 3-20 for the changes.

Figure 3-19. Embed the button in a VStack

This is how you arrange two buttons vertically. You can run the app for a quick
test. The Happy Programming button works exactly the same as the Hello World
button, but it speaks "Happy Programming!"

Understanding Methods
Before we end this chapter, let me introduce another basic programming concept.
Take a look at the code of ContentView again. There are quite a lot of similarities
and duplicated code for the two buttons. One duplicate is the code in the action
block of the buttons.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 106
Figure 3-20. The code block is very similar

Both blocks of code are nearly the same except that the text to read is different.
One is "Happy Programming", the other is "Hello World."

In Swift, you can define a method for this type of repetitive tasks. In this case, we
can create a method named speak inside ContentView like this:

func speak(text: String) {


let utterance = AVSpeechUtterance(string: text)
utterance.voice = AVSpeechSynthesisVoice(identifier: "com.apple.speech
.synthesis.voice.Fred")

synthesizer.speak(utterance)
}

The func keyword is used to declare a method. Following the func keyword is
the name of the method. This name identifies the method and makes it easy for the
method to be called elsewhere in your code. Optionally, a method can take in

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 107
parameters as input. The parameters are defined within the parentheses. Each of
the parameters should have a name and a type, separated by a colon ( : ). In this
example, the method accepts a text parameter which has the type String .

In the method, that's the lines of code for converting text into speech. The only
change is this line of code:

let utterance = AVSpeechUtterance(string: text)

We set the string parameter to text , which is the text passed by the method
caller.

Now that we have created the method, how can we call it? You just need to use the
method name and pass it the required parameter like this:

speak(text: "Hello World")

Let's go back to the ContentView struct to modify the code. First, create the
speak(text: String) method as shown in figure 3-21. Next, you can replace the
action block of both button by calling the speak method.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 108
Figure 3-21. Remove the duplicated code by creating the speak method

This new method doesn't change the functionality of the application. Both buttons
work exactly the same as before. However, as you can see from the final code, it's
easier to read and much cleaner.

And, what if you need to introduce another text-to-speech button to the


application? You no longer need to duplicate the 4 lines of code but just call the
speak method with the text to read. This is why we need to group common
operations into methods.

Exercise
In order to help you fully understand how to work with buttons and methods, here
is a simple exercise for you. Your task is to modify the existing code and build a
"Guess These Movies" app. The UI and functions are very similar to the Hello
World app. Each button displays a set of emoji icons. The player's task is to guess

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 109
the movie's name from those emojis. By tapping the button, the app will speak out
the correct answer. For example, when the player taps the button in blue, the app
reads "The answer is Ocean 11!"

Figure 3-22. Building a Guess these Movies app

Summary
Congratulations! You've built your first iPhone app. It's a simple app, but I believe
you already have a better understanding of Xcode, SwiftUI, and the built-in
frameworks provided by the iOS SDK. It's easier than you thought, right?

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 110
Chapter 4
Designing UI Using Stack Views

To the user, the interface is the product.

- Aza Raskin

I have given you a brief overview of SwiftUI and showed you how to work with
some basic UI components including the vertical stack view (i.e. VStack ). The first
app which we have built was pretty simple. As your app UI becomes more complex,
you will need to use different types of stack views to create the user interface. Most
importantly, you need to learn how to build a UI that fits all screen sizes.

In this chapter, I will walk you through all types of stacks and build a more
comprehensive UI, which you may come across in a real-world application. On top
of that, I will introduce you another common SwiftUI component for displaying

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 111
images. Here are the topics you will learn:

1. Use image views to display images.


2. Manage images using the built-in asset catalog.
3. Use stack views to lay out user interfaces.
4. Adapt stack views using Size Classes.

You'll be amazed how much you can get done using stack views.

Understanding VStack, HStack and ZStack


SwiftUI provides three different types of stacks for developers to combine views in
various orientations. Depending on how you're going to arrange the views, you can
either use:

HStack - arranges the views horizontally


VStack - arranges the views vertically
ZStack - overlays one view on top of another

The figure below shows you how these stacks can be used to organize views.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 112
Figure 4-1. Different types of stack view

The Sample App


Let’s first take a look at the demo app we’re going to build. I will show you how to
lay out a welcome screen like this using stack views:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 113
Figure 4-2. The sample app

In the earlier chapters, you have used VStack to arrange UI components vertically.
To build the app UI, you will need to mix different types of stack views. As you can
see, the app UI works well on all screen sizes. If you have used UIKit before, you
know it is inevitable to use auto layout to build UIs that fit all screen sizes. And,
auto layout is a complicated subject and hard to learn for beginners. The good
news is that SwiftUI no longer uses auto layout and makes it very easy to write
adaptive UI. You will understand what I mean in a while.

Creating a New Project


Now fire up Xcode and create a new Xcode project. Choose Application (under
iOS) > App and click "Next". You can simply fill in the project options as follows:

Product Name: StackViewDemo – This is the name of your app.


Team: Just leave it as it is.
Organization Identifier: com.appcoda – It's actually the domain name

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 114
written the other way round. If you have a domain, you can use your own
domain name. Otherwise, you may use "com.appcoda" or just fill in "edu.self".
Bundle Identifier: com.appcoda.StackViewDemo - It's a unique
identifier of your app, which is used during app submission. You do not need
to fill in this option. Xcode automatically generates it for you.
Interface: SwiftUI - As explained before, Xcode now supports two ways to
build UI. Please change the option to SwiftUI because we will use SwiftUI for
UI development.
Language: Swift – We'll use Swift to develop the project.
Use Core Data: [unchecked] – Do not select this option. You do not need
Core Data for this simple project.
Include Tests: [unchecked] – Do not select this option. You do not need
any tests for this simple project.

Click "Next" to continue. Xcode then asks you where to save the StackViewDemo
project. Pick a folder on your Mac. Click "Create" to continue.

Adding Images to the Xcode Project


As you may notice, the sample app has three images. The question is how can you
bundle images in Xcode projects?

In each Xcode project, it includes an asset catalog (i.e. Assets) for managing
images and icons that are used by your app. Go to the project navigator and select
the Assets folder. By default, it only contains the blank Appicon and AccentColor

sets. We are not going to talk about app icons and accent colors in this chapter, but
will revisit it later in the book.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 115
Figure 4-3. Asset Catalog

Now download this image set


(https://www.appcoda.com/resources/swift4/stackviewdemo-images.zip) and
unzip it on your Mac. The zipped archive contains a total of 5 image files:

user1.pdf
user2.png
[email protected]
[email protected]
user3.pdf

Credit: The images are provided by usersinsights.com.

iOS supports two categories of images: raster images and vector images. Common
image formats like PNG and JPEG are classified as raster images. Raster images

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 116
use a grid of pixels to form a complete image. One problem of raster images is that
it doesn't scale up well. Increasing the size of a raster image usually means a
significant loss of quality. This is why Apple recommends developers to provide
three different resolutions of images when PNG is used. In this example, the image
files comes with three versions. The one with @3x suffix, which has the highest
resolution, is for iPhone 8 Plus, iPhone 13/14 Pro and Pro Max. The one with @2x
suffix is for iPhone SE, iPhone 8, and iPhone 13/14, while the one without the @
suffix is for older devices with non-Retina display (e.g. iPad 2). For details about
how the images are used, you can further refer to this link
(https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-
images/image-size-and-resolution/).

Vector images usually have file types such as PDF and SVG. You can use tools like
Sketch and Pixelmator to create vector images. Unlike raster images, vector images
are comprised of paths instead of pixels. This allows the images to scale up without
losing any image quality. Because of this feature, you just need to provide a single
version of the image in PDF format for Xcode.

I intentionally include both image types in the example for illustration purpose.
When developing a real world app, you usually work with either one or the other.
So, which image type is more preferable? Whenever possible, ask your designer to
prepare the images in PDF format. The overall file size is smaller and the images
are scalable without losing quality.

To add the images to the asset catalog, all you need to do is drag the images from
Finder, and drop them into the set list or set viewer.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 117
Once you add the images to the asset catalog, the set view automatically organizes
the images into different wells. Later, to use the image, you just need to use the set
name of a particular image (e.g. user1). You can omit the file extension. Even if you
have multiple versions of the same image (e.g. user2), you don't have to worry
about which version (@2x/@3x) of the image to use. All these are handled by iOS
accordingly.

Layout the Title Labels with Stack Views

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 118
Now that you've bundled the necessary images in the project, let's move onto the
creation of stack views. First, open ContentView.swift . We'll start with the layout
of these two labels.

I believe you know how to create these two labels because we have used VStack

before. Stack view can arrange multiple views in both vertical and horizontal
direction. The title and subtitle labels are arranged vertically. Therefore, vertical
stack view is a suitable choice.

Now update the ContentView struct like this:

struct ContentView: View {


var body: some View {
VStack {
Text("Instant Developer")
.fontWeight(.medium)
.font(.system(size: 40))
.foregroundColor(.indigo)

Text("Get help from experts in 15 minutes")


}
}
}

We use a VStack to embed two Text views. For the Instant Developer label, we
make the font a little bit larger by setting a fixed font size (i.e. 40 points) and bold
the font by changing the font weight. To change the font's color, we attach the
foregroundColor modifier and set the color to .indigo .

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 119
Using Spacer and Padding
By default, the stack view is displayed at the center of the screen. However, if you
refer to figure 4-2, these two labels should be placed close to the status bar. How
can we move these two labels?

The trick here is to use a special SwiftUI component called Spacer . This spacer
view is a view without content that takes up as much space as it can in a stack
layout. For example, when you place a spacer view in a vertical layout, it expands
vertically as much as the stack allows.

Let's see this spacer view in action, so you will understand how it can help you
arrange the UI components.

To push both labels to the upper part of the screen, we can create another VStack

view (let's call this the root stack view) to embed the current VStack view and then
add a Spacer view.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 120
You can press and hold the command key, and then click on VStack . In the
context menu, choose Embed in VStack. Xcode will automatically wrap the
existing VStack in another VStack view.

Figure 4-8. Embedding the current VStack in another VStack view

Next, insert the Spacer view before the closing curly bracket of the root stack view
(see figure 4-9).

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 121
Figure 4-9. Adding a spacer to the root VStack view

Once you add the spacer view, it expands to take up all the available space of the
vertical stack view, pushing the labels to the top of the screen.

The two labels are still not placed at the expected position if you take a closer look
at figure 4-2. It's now too close to the top edge of the screen. We need to leave
some space between the edge and the text views.

In SwiftUI, you can use a modifier named padding to add space around a view. In
this case, you can attach the padding modifier to the root VStack view like this:

VStack {

.
.
.

}
.padding(.top, 30)

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 122
The padding modifier accepts two optional parameters. You can specify which
edge to pad and the amount of the padding. Here, we tell SwiftUI to add padding
to the top edge and set the amount to 30 points.

Figure 4-10. Adding a padding for the top edge

Padding is very useful in SwiftUI for arranging the view layout. By applying
padding to a view, you can add some space between views.

Using Images
Next, we're going to lay out the three user images. In SwiftUI, we use a view called
Image to display images. Since we already imported the images into the asset
catalog, you can write the code like this to display an image on screen:

Image("user1")

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 123
You do not need to specify the file extension (e.g. png/jpg/pdf). All you need is tell
the Image view the name of the image. To place the image under the text views,
you can insert the line of code right before Spacer() .

Figure 4-11. Adding an image view for displaying images

By default, iOS displays the image in its original size. To resize an image in
SwiftUI, we can attach the resizable modifier like this:

Image("user1")
.resizable()

iOS will stretch the image to fit the available area. Figure 4-12 shows the effect of
the modifier.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 124
Figure 4-12. Using the resizable modifier

The stretch mode doesn't take into account the aspect ratio of the original image. It
stretches each side to fit the view area. To keep the original aspect ratio, you can
apply the modifier scaledToFit like this:

Image("user1")
.resizable()
.scaledToFit()

Alternatively, you can use the aspectRatio modifier and set the content mode to
.fit . This will achieve the same result.

Image("user1")
.resizable()
.aspectRatio(contentMode: .fit)

After you apply the modifiers, the image will be automatically resized and retain
the aspect ratio.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 125
Figure 4-13. Using scaledToFit

Arranging the Images Using Horizontal Stack


Views
Now that you should understand how to display an image, let's see how to lay out
the three images side by side. Earlier, we used VStack to arrange views vertically.
The SwiftUI framework provides another type of stack views called HStack to
arrange views horizontally.

Wrap the Image view using the HStack view and add the other two image views
like this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 126
HStack {
Image("user1")
.resizable()
.scaledToFit()

Image("user2")
.resizable()
.scaledToFit()

Image("user3")
.resizable()
.scaledToFit()
}

When you embed the image views in a horizontal stack, it places the images side by
side, from left to right.

Figure 4-14. Arrange the image views side by side

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 127
The image stack is too close to the left and right edges of the screen. To add some
space, we can attach the padding modifier to the HStack like this:

HStack {
.
.
.
}
.padding(.horizontal, 20)

This tells iOS to add a space of 20 points on the left and right edges of the HStack
view.

Figure 4-15. Attaching the padding modifier to the horizontal stack

There are a couple of tweaks I want to implement for the horizontal stack view:

1. If you take a closer look at the images, they are not perfectly aligned. We want
all images are aligned to the bottom edge of the stack view.
2. Let's add some spacing between the images.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 128
The HStack view actually provides two optional parameters. One is alignment and
the other is spacing . By passing an appropriate value for these parameters, we can
easily accomplish the requirements mentioned above.

Let's change the initialization of HStack like this:

HStack(alignment: .bottom, spacing: 10) {


.
.
.
}

This tells the horizontal stack view to align all image views to the bottom edge and
add a spacing of 10 points between them.

The images should now align perfectly and looks better, right?

Adding a Label Below the Images


There is a label right below the images that we haven't added yet. The
implementation should be very straightforward. You can insert the following line
of code before the Spacer() view:

Text("Need help with coding problems? Register!")

As you can see in the preview, the text views and image views are too close to each
other. Similar to HStack , the VStack also accepts a parameter called spacing for
you to add some spaces for items in the stack view.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 129
Figure 4-16. Adding a label under the images

Now update the root VStack view like this to specify the spacing:

VStack(spacing: 20) {
.
.
.
}

You should notice the image stacks and the text views are now further apart.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 130
Figure 4-17. Adding spacing for the vertical stack view

Layout the Buttons Using a Stack View


We haven’t finished yet. Let's continue to layout the two buttons at the bottom of
the screen. Both buttons have a fixed width of 200 points.

To create the Sign up button with purple background, you can write the code like
this:

Button {

} label: {
Text("Sign Up")
}
.frame(width: 200)
.padding()
.foregroundColor(.white)
.background(Color.indigo)
.cornerRadius(10)

You should be very familiar with the code because it is very similar to that for
creating the Hello World button. The frame modifier is new to you. It's used to
limit the width of the button to 200 points.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 131
Again, to build the layout of the Sign Up and Log In buttons, we will embed them
in a VStack view like this:

VStack {
Button {

} label: {
Text("Sign Up")
}
.frame(width: 200)
.padding()
.foregroundColor(.white)
.background(Color.indigo)
.cornerRadius(10)

Button {

} label: {
Text("Log In")
}
.frame(width: 200)
.padding()
.foregroundColor(.white)
.background(Color.gray)
.cornerRadius(10)
}

You can place the code after the Spacer() view. Once you made the change, you
should see two buttons in the preview pane.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 132
Figure 4-18. Adding the buttons

Previewing the UI Using Different Devices


Xcode shows the preview of the UI using our selected simulator. Say, for me, I
selected the iPhone 14 Pro as the simulator. If you choose another simulator,
Xcode then uses an alternate simulator to render the preview.

What if we want to preview the UI on multiple simulators? How can we do that?

Let's take a look at the preview code:

struct ContentView_Previews: PreviewProvider {


static var previews: some View {
ContentView()
}
}

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 133
This code snippet is written for generating the preview of ContentView . Similar to
Text and Image views, SwiftUI allows us to attach some modifiers to
ContentView and specify the simulator we want to use.

Update the preview code like this:

struct ContentView_Previews: PreviewProvider {


static var previews: some View {
ContentView()
.previewDevice(PreviewDevice(rawValue: "iPhone 12 Pro"))
.previewDisplayName("iPhone 12 Pro")
}
}

We attached two modifiers to the ContentView . The previewDevice modifier


specifies which simulator to use. Here, it's iPhone 14 Pro. The previewDisplayName

modifier sets the name of simulator. Instead of displaying the name as Preview, it
is now shown as iPhone 14 Pro.

Figure 4-19. Updating the name of the simulator

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 134
Now it comes to the interesting part. You can preview the UI on different
simulators all at once by updating the code like this:

struct ContentView_Previews: PreviewProvider {


static var previews: some View {
Group {
ContentView()
.previewDevice(PreviewDevice(rawValue: "iPhone 12 Pro"))
.previewDisplayName("iPhone 12 Pro")

ContentView()
.previewDevice(PreviewDevice(rawValue: "iPhone 12 Pro"))
.previewDisplayName("iPhone 12 Pro")
.previewInterfaceOrientation(.landscapeLeft)

ContentView()
.previewDevice(PreviewDevice(rawValue: "iPhone 12 Pro Max"
))
.previewDisplayName("iPhone 12 Pro Max")

ContentView()
.previewDevice(PreviewDevice(rawValue: "iPad Air (4th gene
ration)"))
.previewDisplayName("iPad Air")
}
}
}

After the code changes, the preview pane should show you 4 labels including
iPhone 14 Pro, iPhone 14 Pro (Landscape), iPhone 14 Pro Max, and iPad Air. This
is a great feature such that you can preview the UI to see if it works great on all
devices.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 135
Figure 4-20. Previewing the UI on multiple simulators

To preview the UI in landscape, you can attach the previewInterfaceOrientation

modifier and set the value to .landscapeLeft or .landscapeRight .

Extracting Views for Better Code Organization


Before we continue to lay out the UI, let me show you a trick to better organize the
code. As you're going to build a more complex UI that involves several
components, the code inside ContentView will eventually become a giant code
block that is hard to review and debug. It's always a good practice to break large
blocks of code into smaller blocks so the code is easier to read and maintain.

Xcode has a built-in feature to refactor the SwiftUI code. For example, if we want
to extract the VStack holding the Sign Up and Log In buttons, you can hold the
command key and click the VStack . Then select Extract Subview to extract the
code.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 136
Figure 4-21. Extracting the VStack to a subview

Xcode extracts the code block and creates a default struct named ExtractedView .
Rename ExtractedView to VSignUpButtonGroup to give it a more meaningful name
(refer to figure 4-22 for details).

Figure 4-22. Renaming the subview

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 137
This is a very useful technique in developing SwiftUI applications. By extracting
code into a separate subview, your code is now more organized. Take a look at the
code block in ContentView . It's now much cleaner and easier to read.

Adapting Stack Views Using Size Classes


What do you think about the app layout in landscape orientation (see figure 4-20)?
It doesn't look very good on iPhone. I want to place the buttons side by side, so it
should free up more space to scale up the images.

Figure 4-23. Side-by-side buttons

Please keep in mind that this change only applies to iPhone in landscape
orientation. For iPhone in portrait orientation, both buttons' position keeps intact.
How can you do that?

This leads to the UI design concept known as Adaptive Layout. With adaptive
layout, your apps can adapt their UI to a particular device and device orientation.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 138
To achieve adaptive layout, Apple introduced a concept called Size Classes. This is
probably the most important aspect which makes adaptive layout possible. Size
classes are an abstraction of how a device is categorized depending on its screen
size and orientation.

A size class identifies a relative amount of display space for both vertical (height)
and horizontal (width) dimensions. There are two types of size classes: regular and
compact. A regular size class denotes a large amount of screen space, while a
compact size class denotes a smaller amount of screen space.

By describing each display dimension using a size class, this will result in four
abstract devices: Regular width-Regular Height, Regular width-Compact Height,
Compact width-Regular Height and Compact width-Compact Height.

The table below shows the iOS devices and their corresponding size classes:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 139
Figure 4-24. Size Classes

To characterize a display environment, you must specify both a horizontal size


class and vertical size class. For instance, an iPad has a regular horizontal (width)
size class and a regular vertical (height) size class. For our customization, we want
to provide layout specializations for iPhones in landscape orientation. In other
words, when the vertical size class is set to compact, we can change the layout of
the buttons.

So, how can we find out the device's vertical size class? The SwiftUI framework
provides the @Environment property wrapper to retrieve the vertical size class. You
can insert the following line of code to get the current size class:

@Environment(\.verticalSizeClass) var verticalSizeClass

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 140
The value of verticalSizeClass will be automatically updated whenever the
device's orientation changes.

With this variable, we can change the layout of the button group in reference to the
value of verticalSizeClass . You can replace VSignUpButtonGroup() with the
following lines of code:

if verticalSizeClass == .compact {
HSignUpButtonGroup()
} else {
VSignUpButtonGroup()
}

When the vertical size class is set to .compact , we align the button group
horizontally by calling HSignUpButtonGroup() , which is a new view we are going to
implement.

Now insert the following code to create the HSignUpButtonGroup view:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 141
struct HSignUpButtonGroup: View {
var body: some View {
HStack {
Button {

} label: {
Text("Sign Up")
}
.frame(width: 200)
.padding()
.foregroundColor(.white)
.background(Color.indigo)
.cornerRadius(10)

Button {

} label: {
Text("Log In")
}
.frame(width: 200)
.padding()
.foregroundColor(.white)
.background(Color.gray)
.cornerRadius(10)
}
}
}

The code of HSignUpButtonGroup is almost the same as that of VSignUpButtonGroup .


We just change VStack to HStack to layout both buttons side by side. Once you
made the change, the preview should update the UI accordingly. For iPhone in
landscape orientation, the buttons should be aligned horizontally.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 142
Figure 4-25. The buttons are aligned horizontally when iPhone is in landscape
orientation

Now the UI looks better on iPhone landscape. And, this is how we make use of size
classes to provide UI specialization and fine tune the UI for different screen sizes.

Preserving Vector Data


Before I end this chapter, I want to show you a feature in Xcode known as Preserve
Vector Data. I mentioned that we prefer to use vector images over raster images in
iOS development because they can scale up or down without losing their quality.
That's partially true.

When a vector image is used, Xcode automatically converts it into static images
(@1x, @2x @3x). It is pretty much like the user2 image we prepared, but the
conversion is handled by Xcode. In this case, the image quality will still be slightly
affected when the image is enlarged. If you try to run the demo on iPad Pro (12.9-
inch), you should find that the image quality is not perfect.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 143
Xcode comes with a feature called Preserve Vector Data that lets you preserve the
vector data of the images. The option is disabled by default. To enable it, you can
go to Assets.xcassets and choose one of the images. In the Attributes inspector,
tick the Preserve Vector Data checkbox to enable the option.

Figure 4-26. Enable the Preserve Vector Data option

Now if you run the app on iPad Pro (12.9-inch) again, you will find the image looks
much better. Figure 4-27 illustrates the image difference when the option is
enabled or disabled.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 144
Figure 4-27. (left) with Preserve Vector Data disabled, (right) with Preserve
Vector Data enabled

Exercise #1
To help you better understand how stack views and size classes work, let's have an
exercise. Try to build a UI like the one shown in figure 4-28. You can download the
required images from http://www.appcoda.com/resources/swift4/student-
tutor.zip

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 145
Figure 4-28. UI requirements for exercise #2

Credit: The background image is provided by Luka Dadiani.

As a hint, to implement the background image, you can attach the background

modifier like this:

VStack {
.
.
.
}
.background {
Image("background")
.resizable()
.ignoresSafeArea()
}

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 146
Inside the modifier, you can place an image as the background. The
ignoresSafeArea modifier of the Image view expands the image to take up the
whole screen. You will understand what this means when you work on the exercise.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 147
Summary
Congratulations! You have finished the chapter and learned how to build an
adaptive UI using stack views and size classes.

Stack views is very powerful view components provided by the SwiftUI framework.
By mixing VStack , HStack , and ZStack together, you can easily create complex
UIs that adapt to different screen sizes. This is just an introduction to stack views.
Later, when we build a real world app, you will learn more layout techniques using
stack views.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 148
Chapter 5
Introduction to Prototyping

If a picture is worth 1000 words, a prototype is worth 1000 meetings.

- @IDEO

How many times have you heard of someone say, "I got an app idea!"

Probably you already got one. So what's the next step?

Now that you have some basic concepts of iOS programming and SwiftUI, should
you just open Xcode and start coding your app?

As I always said, coding is just a part of the app development process. Before you
begin to code your app, you will have to go through other preparation stages. This
is not a book about software engineering. I am not going to discuss every stage of

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 149
the software development lifecycle. Instead, I want to focus on prototyping, which
is an integral part of the mobile development process.

Every time I mentioned prototype to beginners, two questions pop up:

What's a prototype?
Why prototyping?

A prototype is an early model of a product used for testing a concept or visualizing


an idea. Prototyping has been used in many industries. Before constructing a
building, an architect needs to draw a plan of the building and make a model of the
building. An aircraft company builds a prototype of an aircraft to test any design
flaws before building and assembling an airplane. Software companies also build
software prototypes to explore an idea before creating the actual application. In the
context of app development, a prototype can be an early sample of an app which is
not fully functional and contains a basic UI or even sketches.

Prototyping is the process of developing a prototype and offers many advantages.


First, it helps you visualize your idea and better communicate your idea to your
team members and users. While you are now learning and developing an app on
your own, app development rarely happens like that in a real-world environment.

You probably work in a team of programmers and UI/UX designers to build apps
for your clients. Even if you're an indie (or solo) developer, you're probably
developing an app that targets a specific group of users or a niche market. Or you
hire a designer to design the app UI for you. You have to find some ways to
communicate the app idea with your designer or test your idea with your potential
users. You can explain your idea in words, tell your users how the app works but
this is not effective enough. There is no better way than showing your app idea as a
fully functional demo.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 150
By creating a prototype, you can involve everyone (developers, designers, and
users) of the project earlier. All the involved parties will better understand how the
app works and figure out what's missing at the early development stage, way ahead
of the final product is built.

Prototyping also allows you to test an idea without building an actual app. You can
show your prototype to your potential users and get early feedback before an app is
built. This saves you both time and money. Figure 7-1 illustrates the benefits of
prototyping.

Figure 7-1. Prototyping saves you money and time

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 151
To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 152
Chapter 6
Understanding List and ForEach

That's been one of my mantras - Focus and Simplicity. Simple can be harder
than complex: You have to work hard to get your thinking clean to make it
simple. But it's worth it in the end because once you get there, you can move
mountains.

- Steve Jobs

Now that you have a basic understanding of prototyping and our demo app, we'll
work on something more interesting and build a simple app using the List view
in this chapter. Once you master the technique and list views, we'll start to build
the Food Pin app.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 153
First of all, what exactly is a list view in an iPhone app? If you have worked with
UIKit before, a list view in SwiftUI is exactly the same as a table view in UIKit. A
list view is one of the most common UI elements in iOS apps. Most apps (except
games), in some ways, make use of table view to display content. The best example
is the built-in Phone app. Your contacts are displayed in a table view. Another
example is the Mail app. It uses a table view to display your mail boxes and emails.
Not only designed for listing textual data, table view allows you to present the data
in the form of images. The TED, Google+ and Airbnb are also good examples.
Figure 6-1 displays a few more sample list-based apps. Though they look different,
all the app UIs can be built using list views.

Figure 6-1. Sample apps using list views (left to right: Techcrunch, App Store,
Product Hunt, and TED)

What we are going to do in this chapter is create a very simple list view and learn
how to populate data (images and text) into it. If you've built a table view with
UIKit before, you know it'll take you a bit of work to implement a simple table

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 154
view. SwiftUI simplifies this whole process. With just a few lines of code, you will
be able to list data in table form. Even if you need to customize the layout of the
rows, it only requires minimal effort.

Feeling confused? No worries. You'll understand what I mean in a while.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 155
Chapter 7
Customizing List Views

I think that's the single best piece of advice: Constantly think about how you
could be doing things better and questioning yourself.

- Elon Musk, Tesla Motors

In the previous chapter, we created a simple app using List to display a list of
restaurants. In this chapter, we'll customize the list view and make it look more
stylish (see figure 7-1). And, starting from this chapter and onwards, you begin to
develop a real-world app called FoodPin. It's gonna be fun!

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 156
Figure 7-1. Redesign the cell layout

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 157
Chapter 8
Displaying Confirmations and
Handling List View Selection

There is no learning without trying lots of ideas and failing lots of times.

- Jonathan Ive

Are you able to complete the previous exercise and create the redesigned row
layout? If not, don't worry. In this chapter, I will guide you through the solution
and introduce some new layout techniques. Up until now, our focus has been on
displaying data in a list view. However, you may be curious about how we can
interact with the list view and detect row selections. This is precisely what we will
discuss in this chapter.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 158
To begin, first download the complete project we built in the previous chapter. We
will continue to enhance the app and make it even better. In brief, here are what
we are going to implement:

Add an alternate design of the row layout


Bring up a menu when a user taps one of the items in the list view. The menu
offers two options: Reserve a table and Mark as favorite.
Display a heart icon when the user selects the Mark as favorite option.

Through implementing these new features, you will also learn how to better
organize the SwiftUI code and use actions sheets to display alerts in iOS.

Figure 8-1. Sample alerts in Shortcut and Medium apps

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 159
Chapter 9
Understanding Struct, Project
Organization and Code
Documentation

Most good programmers do programming not because they expect to get


paid or adulation by the public, but because it is fun to program.

- Linus Torvalds

If you have read from the very beginning of the book and have worked on all the
projects, you have come a long way. By now, you should be capable of building a
list-based iOS app using SwiftUI. We will continue enhancing the FoodPin app and

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 160
adding more features. However, before delving deeper into iOS app development
and exploring other APIs, I want to introduce you to the basics of Object-Oriented
Programming (OOP) and teach you how to write better code.

Don't be scared by the term "Object-Oriented Programming" or OOP for short. It is


not a new programming language but rather a programming concept. While some
programming books introduce the concept of OOP from the beginning, I
intentionally left it out when I started writing this book. My goal was to keep things
interesting and show you how to create an app without scaring you away with
technical terms or concepts. However, now I believe it is time to discuss OOP.
After going through eight chapters and if you are still reading the book, I believe
you are determined to learn iOS programming. I also believe that you genuinely
want to elevate your programming skills to the next level and become a
professional developer.

Okay, let's get started.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 161
Chapter 10
List Deletion, Swipe Actions,
Context Menus and Activity
Controller

If you spend too much time thinking about a thing, you'll never get it done.
Make at least one definite move daily toward your goal.

– Bruce Lee

In the previous chapter, you learned how to handle row selection. However, what
about deletion? How can we remove a row from a list view? This is a common
question when developing a list-based app. Selecting, deleting, inserting, and

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 162
updating are fundamental operations when working with data. We have already
discussed row selection, so in this chapter, let's focus on deletion. Additionally, we
will explore a couple of new features added to the FoodPin app:

1. Adding a custom action button when a user swipes horizontally in a table row.
This is usually known as swipe actions in SwiftUI.
2. Adding a social sharing feature to the app, that enables users to easily share
the restaurants.

There is a lot to learn in this chapter, but it's going to be fun and rewarding.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 163
Chapter 11
Working with Navigation View

Just build something that you'd want to use today, not something you think
people would use somehow.

– Paul Graham

First things first, what is a navigation view? Similar to list views, navigation views
are commonly used UI components in iOS apps. They offer a drill-down interface
for presenting hierarchical content. Take a look at the pre-installed Photos app,
YouTube, and Contacts. All of them utilize navigation views to display content in a
hierarchical manner. Typically, you combine a navigation view with a stack of list

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 164
views to create a sophisticated interface for your apps. However, it's important to
note that you are not obligated to use both together. Navigation views can be
employed alongside any type of view.

Creating Navigation Views


Let's head back to the FoodPin project and open the RestaurantListView.swift file.

Hold the control key and click List in RestaurantListView . In the context menu,
choose Embed.... Then change the default Container to NavigationStack . In iOS,
you use NavigationStack to create a navigation view.

Figure 11-1. Embedding the list view in a navigation view

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 165
Chapter 12
Detail View Enhancement, Custom
Fonts and Navigation Bar
Customization

To create something exceptional, your mindset must be relentlessly focused


on the smallest detail.

- Giorgio Armani

The current detail view may appear basic, but wouldn't it be great to enhance it to
the one depicted above? In this chapter, we will further improve the detail view to
exhibit additional restaurant information. Moreover, you will gain knowledge
regarding the utilization of custom fonts in SwiftUI.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 166
This chapter covers a substantial amount of material, so you may require a few
hours to work on the project. I recommend setting aside other tasks to fully
concentrate on it. If you are ready, let's proceed with refining the detail view to
achieve an impressive appearance.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 167
Chapter 13
Understanding Colors, Swift
Extensions and Dynamic Type

Fun is one of the most important and underrated ingredients in any


successful venture. If you're not having fun, then it's probably time to call it
quits and try something else.

- Richard Branson

We have built a more eye-catching detail view in the previous chapter. If you
haven't completed the exercise, you can download the full project here.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 168
In this chapter, we will focus on refining the navigation bar and detail view to
make the app UI even better and flexible. Through the exercise, you will learn a
number of topics including:

1. Understanding what a Swift Extension is and how you can apply this Swift
feature to write better code.
2. Using Color Set to define colors in the asset catalog
3. Using Dynamic Types to adjust the font size automatically

Let's get started.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 169
Chapter 14
Working with Maps

The longer it takes to develop, the less likely it is to launch.

-Jason Fried, Basecamp

The MapKit framework offers developers a range of APIs to incorporate map-


related functionalities within their apps. These functionalities include displaying
maps, navigating through maps, adding annotations for specific locations, and
incorporating overlays on existing maps. With this framework, you can easily
embed a fully functional map interface into your app without the need for
extensive coding.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 170
For SwiftUI, it provides a native Map view that allows developers to seamlessly
embed a map interface. Additionally, you have the option to display annotations
using built-in annotation views such as MapMarker .

In this chapter, we will add a map feature to the FoodPin app. The app will
showcase a small map view on the detail screen. When a user taps on the map
view, the app will present a full-screen map, allowing users to explore location
details. Throughout this chapter, you will gain insights into various aspects of the
MapKit framework, including:

How to embed a map in a view


How to translate an address into coordinates using Geocoder
How to add a pin (i.e. annotation) on map

Cool, right? It's gonna be fun. Let's get started.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 171
Chapter 15
View Animations and Blur Effect

Animation can explain whatever the mind of man can conceive. This facility
makes it the most versatile and explicit means of communication yet devised
for quick mass appreciation.

– Walt Disney

First and foremost, let's clarify what an animation is and how it is created.
Animation refers to the simulation of motion and shape transformation by rapidly
displaying a sequence of static images or frames. It creates the illusion that an
object is in motion or changing in size.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 172
For example, a growing circle animation is achieved by displaying a series of
frames. It begins with a dot, and each subsequent frame features a slightly larger
circle than the previous one. This sequence of frames creates the illusion that the
dot is progressively growing larger. Figure 15-1 depicts the sequence of static
images. To keep the example simple, the figure displays only five frames. However,
to achieve a seamless transition and a more fluid animation, one would need to
develop several additional frames.

Figure 15-1. Sequence of frames for creating an animation

Now that you have a basic understanding of how animation works, let's explore
how to create animations in SwiftUI. Let's consider our growing circle example.
We know that the animation begins with a dot (the start state) and ends with a
large red circle (the end state). The challenge lies in generating the frames between
these two states. Do you need to devise an algorithm and write hundreds of lines of
code to generate the series of frames in between? Absolutely not. SwiftUI handles
all the heavy lifting for you. The framework assists in computing the frames
between the start and end states, resulting in a seamless animation.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 173
Have you ever used the "Magic Move" animation feature in Keynote? With "Magic
Move," you can effortlessly create smooth transitions between slides. Keynote
automatically analyzes the objects between slides and generates the animations
automatically. To me, SwiftUI has brought the concept of "Magic Move" to app
development. Animations using the SwiftUI framework are automatic and
seemingly magical. You define the two states of a view, and SwiftUI takes care of
the rest, animating the changes between the two states.

There is no better way to grasp the technique than by working on a practical


example. In this chapter, we will create a new Rate button in the detail view. When
the button is tapped, the app will present a Review view where users can select the
rating for the restaurant. To enhance the user experience, we will incorporate a
blurring effect and animations into the Review view.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 174
Figure 15-2. The review view

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 175
Chapter 16
Working with Observable Objects
and Combine

Failure is an option here. If things are not failing, you are not innovating
enough.

– Elon Musk

In the previous section, we introduced the Review screen, which allows users to
rate a restaurant. However, the rating buttons currently lack functionality. The
desired behavior is for the review view to dismiss itself when a rating is selected,
and for the selected rating to be displayed in the detail view. In this chapter, we
will delve into the implementation details of this functionality.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 176
Figure 16-1. Displaying the rating in the detail view

On top of that, I will provide you with a brief introduction to Combine, a


framework that was introduced alongside SwiftUI. Combine allows for easy
observation of a single object and receiving notifications of its changes. When
combined with SwiftUI, we can trigger view updates without writing any additional
code. SwiftUI and Combine work seamlessly together, handling everything behind
the scenes.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 177
Chapter 17
Working with Forms and Camera

My biggest motivation? Just to keep challenging myself. I see life almost like
one long University education that I never had. Every day I'm learning
something new.

- Richard Branson

So far, the FoodPin app has been limited to displaying content only. We now need
to provide users with the ability to add new restaurants. In this chapter, we will
develop a new screen that features an input form for collecting restaurant
information. Within this form, users will be able to select a restaurant photo from
the built-in photo library. Throughout this process, you will learn a variety of
techniques:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 178
Creating a form input using TextField and TextEditor

Accessing the built-in photo library and working with the camera

Figure 17-1 provides a preview of the screen we are about to build. It showcases a
simple input form consisting of text fields and a text view.

Figure 17-1. Creating a New Restaurant screen for adding a new restaurant

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 179
Chapter 18
Working with Database and
SwiftData

Learn not to add too many features right away, and get the core idea built
and tested.

– Leah Culver

Congratulations on reaching this milestone! By now, you have successfully


developed a basic app that allows users to list their favorite restaurants. Up to this
point, all the restaurants have been pre-defined in the source code and stored in an
array. If you want to add a new restaurant, the simplest approach is to append it to
the existing restaurants array.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 180
However, if you follow this method, the new restaurant data will not be
permanently saved. Data stored in memory, such as an array, is volatile. Once you
quit the app, all the changes will be lost. Therefore, we need to determine a way to
persistently store the data.

To achieve permanent data storage, we need to save the data in a persistent storage
medium such as a file or a database. By saving the data to a database, for example,
the data will remain secure even if the app quits or crashes. On the other hand,
files are more suitable for storing small amounts of data that don't require
frequent modifications. Files are commonly used for storing application settings,
such as the Info.plist file.

The FoodPin app may require storage for thousands of restaurant records, with
users frequently adding or removing records. In such cases, a database is an
appropriate solution for managing a large dataset. In this chapter, I will guide you
through the SwiftData framework and demonstrate how to utilize it to handle
database operations. We will cover topics such as creating the data model and
performing CRUD (create, read, update, delete) operations using the SwiftData
framework.

You will make a lot of changes to your existing FoodPin project, but after going
through this chapter your app will allow users to save their favorite restaurants
persistently.

What’s SwiftData
First and foremost, it's important to note that the SwiftData framework should not
be confused with a database. Built on top of Core Data, SwiftData is actually a
framework designed to help developers manage and interact with data on a
persistent store. While the default persistent store for iOS is typically the SQLite

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 181
database, it's worth noting that persistent stores can take other forms as well. For
example, Core Data can also be used to manage data in a local file, such as an XML
file.

Regardless of whether you're using Core Data or the SwiftData framework, both
tools serve to shield developers from the complexities of the underlying persistent
store. Consider the SQLite database, for instance. With SwiftData, there's no need
to worry about connecting to the database or understanding SQL in order to
retrieve data records. Instead, developers can focus on working with APIs and
Swift Macros, such as @Query and @Model , to effectively manage data in their
applications.

The SwiftData framework is newly introduced in iOS 17 to replace the previous


framework called Core Data. Core Data has long been the data management APIs
for iOS development since the era of Objective-C. Even though developers can
integrate the framework into Swift projects, Core Data is not a native solution for
both Swift and SwiftUI.

In iOS 17, Apple finally introduces a native framework called SwiftData for Swift
on persistent data management and data modeling. It's built on top of Core Data
but the APIs are completely redesigned to make the most out of Swift.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 182
Chapter 19
Adding a Search Bar Using
Searchable

I knew that if I failed I wouldn't regret that, but I knew the one thing I might
regret is not trying.

– Jeff Bezos

For most list-based apps, it is common to have a search bar at the top of the
screen. How can you implement a search bar for data searching? In this chapter,
we will add a search bar to the FoodPin app. With the search bar, we will enhance
the app to allow users to search through the available restaurants.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 183
Prior to iOS 15, SwiftUI didn't come with a built-in modifier for handling search in
List views. Developers had to create their own solution. In our Mastering SwiftUI
book, we have written a chapter showing you how to create a custom search bar in
SwiftUI using TextField and display the search results.

Starting with iOS 15, the SwiftUI framework introduced a modifier named
searchable for List views. You can simply attach the modifier to a list view and
create a search field.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 184
Chapter 20
Building Walkthrough Screens
Using TabView

If you're interested in the living heart of what you do, focus on building
things rather than talking about them.

- Ryan Freitas, About.me

When launching an app for the first time, it is common to include a series of
walkthrough screens or tutorials. These screens guide users through the app's
features and functionality. Some argue that the need for walkthrough screens
implies a failure in app design. However, personally, I find most walkthrough

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 185
screens to be useful and don't dislike them. The key is to keep them concise and
avoid lengthy and boring tutorials. I won't debate whether you should include
walkthrough screens in your app or not; I simply want to show you how to do it.

App developers utilize walkthrough screens not only to showcase app features but
also to guide users through initial setup processes, such as enabling notifications
and choosing a color theme. Figure 20-1 provides an example of walkthrough
screens.

Figure 20-1. Sample Walkthrough Screens of Sorted

In this chapter, we will discuss how to use TabView to create walkthrough screens.
When I mention tab views, you may immediately think of an app with a tab bar.
However, with SwiftUI, TabView can be used to present an interface with multiple
tabs and offers more than just a standard tab interface. By changing its style, you
can easily transform a tab view into a paged scrolling view.

Let's get started.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 186
Chapter 21
Working with Tab View and Tab
Bar Customizations

If you're trying to achieve, there will be roadblocks. I've had them; everybody
has had them. But obstacles don't have to stop you. If you run into a wall,
don't turn around and give up. Figure out how to climb it, go through it, or
work around it.

- Michael Jordan

The tab bar is a row of persistently visible buttons located at the bottom of the
screen. It serves as a navigation component that opens different features of the
app. Although it was once considered less prominent in mainstream UI design, the
tab bar has regained popularity in recent times.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 187
In the era before the introduction of large-screen devices, such as the 3.5-inch and
4-inch iPhones, tab bars had one drawback: they occupied valuable screen space,
which was particularly challenging for smaller screens. However, with the release
of the larger iPhone 6 and 6 Plus models in late 2014, app developers began
replacing their existing menus with tab bars. Prominent apps like Facebook,
Whatsapp, Twitter, Quora, Instagram, and Apple Music transitioned to tab bar
navigation.

Tab bars offer the advantage of allowing users to access the core features of an app
with just a single tap, even though they consume screen space. The trade-off is
considered worthwhile.

While navigation controllers facilitate hierarchical content navigation by managing


a stack of view controllers, tab bars manage multiple view controllers that may not
necessarily have a direct relationship. Typically, a tab bar controller contains a
minimum of two tabs, and you can add up to five tabs depending on your app's
requirements.

Figure 21-1. Adding a tab bar for the FoodPin app

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 188
I already introduced TabView in the previous chapter. However, we configured it
as a paged scrolling view. In this chapter, we will use it to create a standard tab
interface as displayed in figure 21-1. We're going to create a tab bar with three
items:

Favorites - this is the restaurant list screen.


Discover - this is a new screen to discover favorite restaurants recommended
by your friends or other foodies around the globe. We will implement this tab
in the iCloud chapter.
About - this is the "About" the about screen of the app. Once again we'll keep
this page blank until the next chapter.

On top of that, we will show to customize the tab bar in SwiftUI.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 189
Chapter 22
Displaying Web Content with
WKWebView and
SFSafariViewController

I've got a theory that if you give 100% all of the time, somehow things will
work out in the end.

- Larry Bird

It is very common to have the need to display web content within your apps. The
iOS SDK offers three options for developers to achieve this:

Mobile Safari - The iOS SDK provides APIs that allow you to open a specific
URL in the built-in Mobile Safari browser. In this scenario, your users

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 190
temporarily leave the application and switch to Safari to view the web content.
WKWebView - This view enables developers to embed web content directly
within their apps. Think of WKWebView as a simplified version of Safari
specifically designed for app integration. It is responsible for loading URL
requests and displaying web content. WKWebView utilizes the Nitro JavaScript
engine and offers additional features. If your goal is to display a specific web
page, WKWebView is the recommended option for this use case.
SFSafariViewController - While WKWebView allows you to embed web
content, it does not provide a complete web browsing experience out of the
box. For example, WKWebView lacks the Back/Forward buttons that allow users
to navigate through browsing history. To offer such functionality, developers
would need to build a custom web browser using WKWebView . However, with
the introduction of SFSafariViewController , developers no longer need to
create their own web browser from scratch. By utilizing
SFSafariViewController , users can enjoy all the features of Mobile Safari
without leaving your app. It provides a seamless browsing experience within
your app, including navigation controls.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 191
Figure 22-1. The About screen of the FoodPin app

In this chapter, I will walk you through all the options and show you how to use
them to display web content. For both WKWebView and SFSafariViewController , we
will need to make use of UIViewRepresentable and UIViewControllerRepresentable to
integrate with these components because they are only available in UIKit.

To demonstrate how to show web content in SwiftUI, we will build the About tab to
display three options:

Rate us on App Store - when selected, we will load a specific iTunes link in
Mobile Safari. Users will leave the current app and switch to the App Store.
Tell us your feedback - when selected, we will load a Contact Us web page
using WKWebView.
Twitter / Facebook / Instagram - Each of these items has its own link for
the corresponding social profile. We will use SFSafariViewController to load
these links.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 192
Sounds interesting, right? Let's get started.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 193
Chapter 23
Working with CloudKit

The most impressive people I know spent their time with their head down
getting shit down for a long, long time.

- Sam Altman

Let's start with some history. In 2011, during Apple's annual Worldwide
Developers Conference (WWDC), Steve Jobs introduced iCloud as a
complementary feature for iOS 5 and OS X Lion. The announcement garnered
significant attention, although it was not entirely unexpected. With iCloud, apps
and games gained the ability to store data on the cloud and seamlessly synchronize
it between Macs and iOS devices.

However, iCloud fell short in one aspect: serving as a cloud server.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 194
Developers were restricted from utilizing iCloud for storing public data that could
be shared among users. Its functionality was limited to facilitating data exchange
exclusively between multiple devices owned by the same user. To illustrate this
limitation, let's consider our Food Pin app as an example. With the classic version
of iCloud, you would not be able to store your favorite restaurants publicly and
make them available to other users of the app. The data stored on iCloud can only
be accessed by you and cannot be shared with others.

During that time, if you desired to create a social app for data sharing among
users, you had two options. The first was to develop your own custom backend
server, complete with server-side APIs for data transfer and user authentication.
Alternatively, you could rely on third-party cloud service providers like Firebase
and Parse.

Note: Parse was a very popular cloud service at the time.


But Facebook announced the demise of the service on
January 28, 2016.

However, in 2014, Apple made significant improvements to iCloud's functionality,


providing both developers and users with new and enhanced features. The
introduction of CloudKit marked a substantial leap forward from its predecessor
and opened up vast possibilities for developers. With CloudKit, it became much
easier to develop social networking apps or incorporate social sharing features.

But what if you have a web app and want to access the same data stored on iCloud
as your iOS app? Apple took CloudKit a step further by introducing CloudKit web
services, also known as CloudKit JS. This technology leverages a JavaScript
library, allowing you to develop a web app that can access the same data on iCloud
as your native app.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 195
Figure 23-1. Storing your data to the cloud

During WWDC 2016, Apple made a significant announcement regarding the


introduction of the Shared Database feature. This update expanded the capabilities
of CloudKit, enabling developers to not only store data publicly or privately but
also share data with specific groups of users.

CloudKit simplifies the development process for developers by eliminating the


requirement to create and maintain their own server solutions. With minimal
setup and coding, CloudKit empowers your app to store various types of data,
including structured data and assets, in the cloud. This streamlined approach saves
time and effort, allowing developers to leverage the power of cloud storage without
the need for extensive backend development.

Best of all, you can get started with CloudKit for free (with limits). It starts with:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 196
10GB for assets (e.g. images)
100MB for database
2GB for data transfer

As your app becomes more popular, the CloudKit storage grows with you and adds
an additional 250MB for every single user. For each developer account, you can
scale all the way up to the following limits:

1PB assets
10TB database
200TB data transfer

That's a massive amount of free storage and is sufficient for the vast majority of
apps. According to Apple, the storage should be enough for about 10 million free
users.

With CloudKit, we were able to focus on building our app and even squeeze
in a few extras.

- Hipstamatic

In this chapter, my focus will be on guiding you through the integration of iCloud
using the CloudKit framework. However, our emphasis will solely be on the Public
database. Similar to the web views discussed in the previous chapter, SwiftUI does
not provide specific CloudKit components. Nevertheless, I will demonstrate how to
incorporate CloudKit APIs into SwiftUI projects. Specifically, you will learn how to
retrieve and manage records within the iCloud database. We will enhance the app
to allow users to anonymously share their favorite restaurants and upload them to
the public database of iCloud. All users will then be able to view these shared
favorites in the Discover tab.

There is a catch, though. To access CloudKit storage, you must enroll in the Apple
Developer Program, which costs USD 99 per year. Apple restricts CloudKit usage
to paid developers only. If you are serious about creating your app, it's time to

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 197
enroll in the program and start building some CloudKit-based apps.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 198
Chapter 24
Localizing Your App to Support
Multiple Languages

Good code is its own best documentation. As you're about to add a comment,
ask yourself, "How can I improve the code so that this comment isn't
needed?" Improve the code and then document it to make it even clearer.

- Steve McConnell

In this chapter, let's talk about localization. The iOS devices including iPhone and
iPad are available globally. The App Store is available in more than 150 countries
around the world. Your users are from different countries and speak different

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 199
languages. To deliver a great user experience and reach a global audience, you
definitely want to make your app available in multiple languages. The process of
adapting an app to support a particular language is usually known as localization.

Xcode has the built-in support for localization. It's fairly easy for developers to
localize an app through the localization feature and a few API calls.

You may have heard of the terms: localization and internationalization. You
probably think that both terms refer to the process of translation; that's partially
correct. In iOS development, internationalization is considered a milestone in
building a localized app. Before your app can be adapted to different languages,
you design and structure the app to be language and region independent. This
process is known as internationalization. For instance, your app displays a price
field. As you may know, some countries use a dot to indicate decimal place (e.g.
$1000.50), while many other countries use a comma instead (e.g. $1000,50). The
internationalization process involves designing the price field so that it can be
adapted to different regions.

Localization is the process of adapting an internationalized app for different


languages and regions. This involves translating static and visible text to a specific
language and adding country-specific elements such as images, videos, and
sounds.

In this chapter, we'll localize the FoodPin app into Chinese and German. However,
don't expect me to translate all the text in the app - I just want to show you the
overall process of localization using Xcode.

Introducing String Catalogs in Xcode 15


With the release of Xcode 15, Apple introduced an exciting feature called String
Catalogs. This feature aims to streamline the localization process for your app,
making it easier than ever to manage all your strings in one central location. By

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 200
leveraging String Catalogs, you can ensure that your app is fully localized before it
reaches your users. This new feature offers both convenience and confidence in the
localization process.

Before we proceed with the implementation, let's examine the user-facing text
within the app. There is a significant amount of user-facing text present in the
source code, such as the text fields displayed in the "New Restaurant" form. Figure
24-1 showcases a few examples of user-facing texts found in the NewRestaurantView

struct.

In earlier versions of Xcode, you have to go through a string internationalization


process that requires to modify the existing texts with the String(localized:)

macro. However, with the introduction of String Catalogs, this process is no longer
necessary. String Catalogs automatically extracts all user-facing texts for you,
eliminating the need for manual modifications.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 201
Chapter 25
Deploying and Testing Your App on
a Real iOS Device

If we want users to like our software, we should design it to behave like a


likable person: respectful, generous and helpful.

- Alan Cooper

Up till now, you have been running and testing your app on the built-in simulator.
The simulator is a great companion for app development especially if you do not
own an iPhone. While the simulator is good, you can never rely completely on the
simulator. It's not recommended to submit your app to App Store without testing
it on a real device. Chances are there are some bugs that only show up when your

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 202
app runs on a physical iPhone or over the cellular network. If you're serious about
building a great app, this is a must to test your app on a real device before
releasing it to your users.

One great news, especially for aspiring iOS developers, is that Apple no longer
requires you to enroll in the Apple Developer Program before you can test your app
on an iOS device. You can simply sign in Xcode with your Apple ID, and your app
is ready to run on your iPhone or iPad. However, please note that if your app
makes use of the services like CloudKit and Push Notifications, you still need to
enroll in the Apple Developer Program, which costs $99 per year. I know, for
some, this is a significant amount of money for some of you. But if you read the
book from the very beginning and are still with me, I believe you have
demonstrated a strong determination to build an app and deploy it to your
audience. It's not easy to make it this far! So why stop here? If you're not on a tight
budget, I highly recommend you enroll in the program so that you can continue to
learn the rest of the materials and most importantly, submit your app to App Store.

To test an app on a physical device, you will need to perform a few configurations:

Request your development certificate


Create an App ID for your app
Configure your device for development
Create a provisioning profile for your app

In the old days of iOS development, you had to manage the above configurations
all on your own through the iOS Provisioning Portal (or Member Center). The
modern version of Xcode automates the whole signing and configuration processes
by using a feature called Automatic Signing. This makes your life a lot easier. You
will see what I mean shortly.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 203
Chapter 26
Beta Testing with TestFlight and
CloudKit Production Deployment

If you are not embarrassed by the first version of your product, you've
launched too late.

- Reid Hoffman, LinkedIn

Now that you have completed the testing of your app on a real device, what's next?
Submit your app directly to App Store and make it available for download? Yes,
you can if your app is a simple one. If you're developing a high-quality app, don't
rush to get your app out, as I suggest you beta test your app before the actual
release.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 204
A beta test is a step in the cycle of a software product release. I know you have
tested your app using the built-in simulator and on your own device. Interestingly,
you may not be able to uncover some of the bugs, even though you're the app
creator. By going through beta tests, you would be amazed at the number of flaws
discovered at this stage. Beta testing is generally opened to a select number of
users. They may be your potential app users, your blog readers, your Facebook
followers, your colleagues, friends or even family members. The whole point of
beta testing is to let a small group of real people get their hands on your app, test
it, and provide feedback. You want your beta tester to discover as many bugs as
possible in this stage so that you can fix them before rolling out your app to the
public.

You may be wondering how can you conduct a beta test for your app, how beta
testers run your app before it's available on App Store and how testers report
bugs?

In iOS 8, Apple released a new tool called TestFlight to streamline the beta
testing. You may have heard of TestFlight before. It has been around for several
years as an independent mobile platform for mobile app testing. In February 2014,
Apple acquired TestFlight's parent company, Burstly. Now TestFlight is integrated
into App Store Connect (previously known as iTunes Connect) and iOS that allows
you to invite beta testers using just their email addresses.

TestFlight makes a distinction between beta testers and internal users.


Conceptually, both can be your testers at the beta testing stage. However,
TestFlight refers internal users as members of your development team who have
been assigned the Technical or Admin role in App Store Connect. You're allowed to
invite up to 100 internal users to test your app. A beta tester, on the other hand, is
considered as an external user outside your team and company. You can invite up
to 10,000 users to beta test your app.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 205
If you are going to let external users test your app, the app must be approved by
Apple before you can send out the invitation This restriction doesn't apply to
internal users. Your internal users can begin beta testing once you upload your app
to App Store Connect.

Similar to CloudKit, TestFlight is not available for free. You have to enroll in the
Apple Developer Program ($99 per year) before you can access TestFlight.

In this chapter, I will walk you through the beta test process using TestFlight. In
general, we will go through the tasks below to distribute an app for beta testing:

Create an app record on App Store Connect.


Update the build string.
Archive and validate your app.
Upload your app to App Store Connect.
Manage beta testing in App Store Connect.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 206
Chapter 27
Submit Your App to App Store

Don't let people tell you your ideas won't work. If you're passionate about an
idea that's stuck in your head, find a way to build it so you can prove to
yourself that it doesn't work.

- Dennis Crowley, FourSquare

Congratulations! You have probably worked weeks or months before coming to the
last step of app development. After beta testing and numerous bug fixing, your app
is finally ready for submission.

You already uploaded your app binary to iTunes Connect in the previous chapter,
so it is quite straightforward to submit your app to App Store. Once you submit
your app, it will be reviewed by Apple's App Review team before publishing it onto

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 207
App Store. For a first-time app developer, submitting an app to the app store can
be a nightmare. You may need to submit your app multiple times before Apple
approves it.

In this chapter, I will walk you through the app submission process and give you
some guidelines to minimize the possibility of app rejections.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 208
Chapter 28
Adopting Haptic Touch

As your first app, the FoodPin app is already quite impressive. However, if you
wish to enhance it further and incorporate some of the modern technologies
offered by iOS devices, I have two additional chapters prepared for you.

Ever since the launch of the iPhone 6s and 6s Plus, Apple introduced us to an
entirely innovative method of interacting with our phones known as 3D Touch.
This feature adds a new dimension to the user interface and provides a unique user
experience. With 3D Touch, the iPhone can not only detect your touch but also
sense the amount of pressure you apply to the display.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 209
Apple has been replacing 3D Touch with Haptic Touch on all iPhone models,
starting from the iPhone 11, 11 Pro, and 11 Pro Max. Although Haptic Touch and
3D Touch have similarities, there are distinct differences between them. While 3D
Touch relies on force touch, Haptic Touch is activated by a touch and hold gesture.

Have you ever tried pressing an app icon on the home screen with a bit more
pressure? When you do so, a set of quick actions appears, allowing you to directly
access specific parts of the app. This is an example of Haptic Touch in action,
referred to as Quick Actions.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 210
Figure 28-1. Sample Quick Actions

In this chapter, I will go through with you how to implement quick actions in
SwiftUI projects and create your custom URL type for handling these quick
actions:

New Restaurant - go to the New Restaurant screen directly


Discover restaurants - jump right into the Discover tab
Show Favorites - jump right into the Favorites tab

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 211
To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 212
Chapter 29
Working with User Notifications

Prior to iOS 10, user notifications were plain and simple, without rich graphics or
media. They were presented in text format. Depending on the user's context, the
notification could appear on the lock screen or home screen. If the user missed any
notifications, they could bring up the Notification Center to view all pending
notifications.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 213
Figure 29-1. Sample user notifications in lock screen and home screen

Since the release of iOS 10, Apple has revamped the notification system to support
user notifications in rich content and custom notification UI. By rich content, it
means you can include static images, animated GIFs, videos, and audios in the
notifications. Figure 29-2 gives you an idea of rich content notifications.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 214
Figure 29-2. Sample user notifications in rich content

You may have heard of push notifications, which have been widely adopted in
messaging apps. Actually, user notifications can be classified into two types: local
notifications and remote notifications. Local notifications are triggered by the
application itself and contained on the user's device. For example, a location-based
application will send users a notification when they are in a particular area. Or a
to-do list app displays a notification when an item is close to the due date.

Remote notifications are usually initiated by server side applications that reside on
remote servers. When the server application wants to send messages to users, it
sends a notification to Apple Push Notification Service (or APNS for short). The
service then forwards the notification to users' devices.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 215
We're not going to talk about the implementation of remote notifications in this
chapter. Instead, we will focus on discussing local notifications, and show you how
to use the new User Notifications framework to implement the rich-content
notifications.

To access the full version of the book, please get the full copy here. You will also
be able to access the full source code of the project.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 216
Appendix - Swift Basics
Swift is a new programming language for developing iOS, macOS, watchOS and
tvOS apps. As compared to Objective-C, Swift is a neat language and will definitely
make developing iOS apps easier. In this appendix, I will give you a brief
introduction of Swift. This doesn't serve as a complete guide for the programming
language but gives you all the essentials to kick start Swift programming. For the
full reference, please refer to the official documentation
(https://swift.org/documentation/).

Variables, Constants, and Type Inference


In Swift, you declare variables with the var keyword and constants using the let

keyword. Here is an example:

var numberOfRows = 30
let maxNumberOfRows = 100

These are the two keywords you need to know for variable and constant
declaration. You use the let keyword for storing a value that is unchanged.
Otherwise, use var keyword for storing values that can be changed.

Isn't it easier than Objective-C?

What's interesting is that Swift allows you to use nearly any character for both
variable and constant names. You can even use an emoji character for the naming.

You may notice a huge difference in variable declaration between Objective-C and
Swift. In Objective-C, developers have to specify explicitly the type information
when declaring a variable. Be it an int or double or NSString , etc.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 217
const int count = 10;
double price = 23.55;
NSString *myMessage = @"Objective-C is not dead yet!";

It's your responsibility to specify the type. In Swift, you no longer need to annotate
variables with type information. It provides a huge feature known as Type
inference. This feature enables the compiler to deduce the type automatically by
examining the values you provide in the variable.

let count = 10
// count is inferred to be of type Int
var price = 23.55
// price is inferred to be of type Double
var myMessage = "Swift is the future!"
// myMessage is inferred to be of type String

It makes variable and constant declaration much simpler, as compared to


Objective-C. Swift provides an option to explicitly specify the type information if
you wish. The below example shows how to specify type information when
declaring a variable in Swift:

var myMessage: String = "Swift is the future!"

No Semicolons
In Objective-C, you need to end each statement in your code with a semicolon. If
you forget to do so, you will end up with a compilation error. As you can see from
the above examples, Swift doesn't require you to write a semicolon ( ; ) after each
statement, though you can still do so if you like.

var myMessage = "No semicolon is needed"

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 218
Basic String Manipulation
In Swift, strings are represented by the String type, which is fully Unicode-
compliant. You can declare strings as variables or constants:

let dontModifyMe = "You cannot modify this string"


var modifyMe = "You can modify this string"

In Objective-C, you have to choose between NSString and NSMutableString classes


to indicate whether the string can be modified. You do not need to make a choice
in Swift. Whenever you assign a string to a variable (i.e. var ), the string can be
modified in your code.

Swift simplifies string manipulating and allows you to create a new string from a
mix of constants, variables, literals, as well as, expressions. Concatenating strings
is super easy. Simply add two strings together using the + operator:

let firstMessage = "Swift is awesome."


let secondMessage = "What do you think?"
var message = firstMessage + secondMessage
print(message)

Swift automatically combines both messages and you should see the following
message in console. Note that print is a global function in Swift to print the
message in console.

Swift is awesome. What do you think? You can do that in Objective-C by using the
stringWithFormat: method. But isn't the Swift version more readable?

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 219
NSString *firstMessage = @"Swift is awesome. ";
NSString *secondMessage = @"What do you think?";
NSString *message = [NSString stringWithFormat:@"%@%@", firstMessage, seco
ndMessage];
NSLog(@"%@", message);

String comparison is more straightforward. You can use the == operator to


compare two strings like this:

var string1 = "Hello"


var string2 = "Hello"
if string1 == string2 {
print("Both are the same")
}

Arrays
The syntax of declaring an array in Swift is similar to that in Objective-C. Here is
an example:

Objective-C:

NSArray *recipes = @[@"Egg Benedict", @"Mushroom Risotto", @"Full Breakfas


t", @"Hamburger", @"Ham and Egg Sandwich"];

Swift:

var recipes = ["Egg Benedict", "Mushroom Risotto", "Full Breakfast", "Hamb


urger", "Ham and Egg Sandwich"]

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 220
While you can put any objects in NSArray or NSMutableArray in Objective-C, arrays
in Swift can only store items of the same type. In the above example, you can only
store strings in the string array. With type inference, Swift automatically detects
the array type. But if you like, you can also specify the type in the following form:

var recipes : String[] = ["Egg Benedict", "Mushroom Risotto", "Full Breakf


ast", "Hamburger", "Ham and Egg Sandwich"]

Swift provides various methods for you to query and manipulate an array. Simply
use the count method to find the number of items in the array:

var numberOfItems = recipes.count


// recipes.count will return 5

Swift makes operations on array much simpler. You can add an item by using the
+= operator:

recipes += ["Thai Shrimp Cake"]

This also applies when you need to add multiple items:

recipes += ["Creme Brelee", "White Chocolate Donut", "Ham and Cheese Panin
i"]

To access or change a particular item in an array, pass the index of the item by
using subscript syntax just like that in Objective-C and other programming
languages:

var recipeItem = recipes[0]


recipes[1] = "Cupcake"

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 221
One interesting feature of Swift is that you can use … to change a range of values.
Here is an example:

recipes[1...3] = ["Cheese Cake", "Greek Salad", "Braised Beef Cheeks"]

This changes the item 2 to 4 of the recipes array to "Cheese Cake", "Greek Salad"
and "Braised Beef Cheeks". (Remember the first item in an array starts with the
index 0. This is why index 1 refers to item 2.)

If you print the array to console, here is the result:

Egg Benedict
Cheese Cake
Greek Salad
Braised Beef Cheeks
Ham and Egg Sandwich

Dictionaries
Swift provides three primary collection types: arrays, dictionaries, and sets. Now
let's talk about dictionaries. Each value in a dictionary is associated with a unique
key. To declare a dictionary in Swift, you write the code like this:

var companies = ["AAPL" : "Apple Inc", "GOOG" : "Google Inc", "AMZN" : "Am
azon.com, Inc", "FB" : "Facebook Inc"]

The key and value in the key-value pairs are separated by a colon. The key-value
pairs are surrounded by a pair of square brackets, each of which is separated by
commas.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 222
Like array and other variables, Swift automatically detects the type of the key and
value. But, if you like, you can specify the type information by using the following
syntax:

var companies: [String: String] = ["AAPL" : "Apple Inc", "GOOG" : "Google


Inc", "AMZN" : "Amazon.com, Inc", "FB" : "Facebook Inc"]

To iterate through a dictionary, use the for-in loop.

for (stockCode, name) in companies {


print("\(stockCode) = \(name)")
}

// You can also use the keys and values properties to


// retrieve the keys and values of the dictionary.
for stockCode in companies.keys {
print("Stock code = \(stockCode)")
}
for name in companies.values {
print("Company name = \(name)")
}

To access the value of a particular key, specify the key using the subscript syntax. If
you want to add a new key-value pair to the dictionary, simply use the key as the
subscript and assign it with a value like below:

companies["TWTR"] = "Twitter Inc"

Now the companies dictionary contains a total of 5 items. The "TWTR":"Twitter


Inc" pair is automatically added to the companies dictionary.

Set

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 223
A set is very similar to an array. While an array is an ordered collection, a set is an
unordered collection. Items in an array can be duplicated. A set stores no repeated
values.

To declare a set, you can write like this:

var favoriteCuisines: Set = ["Greek", "Italian", "Thai", "Japanese"]

The syntax is very similar to creating an array, but you have to explicitly specify the
type Set .

As mentioned, a set is an unordered collection of distinct items. If you declare a set


of duplicated values, the set will not store the duplicates. Here is an example:

Operations on sets are quite similar to an array. You can use for-in loop to iterate
over a set. But to add a new item to a set, you can't use the += operator. You have
to call the insert method:

favoriteCuisines.insert("Indian")

With sets, you can easily determine the values two sets have in common, or vice
versa. For example, you use two sets to represent the favorite cuisines of two
persons:

var tomsFavoriteCuisines: Set = ["Greek", "Italian", "Thai", "Japanese"]


var petersFavoriteCuisines: Set = ["Greek", "Indian", "French", "Japanese"
]

You want to find out the common cuisines which they both love. You can call the
intersection method like this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 224
tomsFavoriteCuisines.intersection(petersFavoriteCuisines)

This will return you the result: {"Greek", "Japanese"} .

Or if you want to determine which cuisines they don't have in common, you can
use the symmetricDifference method:

tomsFavoriteCuisines.symmetricDifference(petersFavoriteCuisines)
// Result: {"French", "Italian", "Thai", "Indian"}

Classes
In Objective-C, you create separate interface (.h) and implementation (.m) files for
classes. Swift no longer requires developers to do that. You can define classes in a
single file (.swift) without separating the external interface and implementation.

To define a class, you use the class keyword. Here is a sample class in Swift:

class Recipe {
var name: String = ""
var duration: Int = 10
var ingredients: [String] = ["egg"]
}

In the above example, we define a Recipe class with three properties including
name duration and ingredients. Swift requires you to provide the default values of
the properties. You'll end up with a compilation error if the initial values are
missing.

What if you don't want to assign a default value? Swift allows you to write a
question mark ( ? ) after the type of a value that indicates the value is optional.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 225
class Recipe {
var name: String?
var duration: Int = 10
var ingredients: [String]?
}

In the above code, the name and ingredients properties are automatically
assigned with a default value of nil . We will discuss optionals in details in later
section. To create an instance of a class, just use the below syntax:

var recipeItem = Recipe()


// You use the dot notation to access or change the property of an instanc
e.
recipeItem.name = "Mushroom Risotto"
recipeItem.duration = 30
recipeItem.ingredients = ["1 tbsp dried porcini mushrooms", "2 tbsp olive
oil", "1 onion, chopped", "2 garlic cloves", "350g/12oz arborio rice", "1.
2 litres/2 pints hot vegetable stock", "salt and pepper", "25g/1oz butter"
]

Swift allows you to subclass classes and adopt protocols. For example, if you have a
SimpleTableViewController class that extends from UIViewController and adopts
both UITableViewDelegate and UITableViewDataSource protocols, you can write the
class declaration like this:

class SimpleTableViewController : UIViewController, UITableViewDelegate, U


ITableViewDataSource

Methods

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 226
Similar to other object-oriented languages, Swift allows you to define functions in
a class known as methods. You can use the func keyword to declare a method.
Here is a sample method without return values and parameters:

class TodoManager {
func printWelcomeMessage() {
print("Welcome to My ToDo List")
}
}

In Swift, you call a method by using dot syntax:

todoManager.printWelcomeMessage()

If you need to declare a method with parameters and return values, the method
will look this:

class TodoManager {
func printWelcomeMessage(name:String) -> Int {
print("Welcome to \(name)'s ToDo List")

return 10
}
}

The syntax looks a bit awkward especially for the -> operator. The above method
takes a name parameter in String type as the input. The -> operator is used as an
indicator for methods with a return value. In the above code, you specify a return
type of Int that returns the total number of todo items. Below demonstrates how
you call the method:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 227
var todoManager = TodoManager()
let numberOfTodoItem = todoManager.printWelcomeMessage(name: "Simon")
print(numberOfTodoItem)

Control Flow
Control flow and loops employ a very C-like syntax. As you can see in the previous
section, Swift provides for-in loop to iterate through arrays and dictionaries.

for loops

In case you just want to iterate over a range of values, you can use the ... or ..<

operators. These are the new operators introduced in Swift for expressing a range
of values. Here is an example:

for i in 0..<5 {
print("index = \(i)")
}

This would print out the following result in console:

index = 0
index = 1
index = 2
index = 3
index = 4

So what's the difference between ..< and ... ? If we replace the ..< operator
with ... in the above example, this defines a range that runs from 0 to 5 and 5 is
included in the range. Here is the console result:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 228
index = 0
index = 1
index = 2
index = 3
index = 4
index = 5

if-else statement

Just like Objective-C, you can use if statement to execute code based on a certain
condition. The syntax of the if-else statement is pretty similar to that in
Objective-C. Swift just makes the syntax even simpler in that you no longer need to
enclose the condition within a pair of round brackets.

var bookPrice = 1000;


if bookPrice >= 999 {
print("Hey, the book is expensive")
} else {
print("Okay, I can affort it")
}

switch statement

I'd just like to highlight the switch statement in Swift that is a dramatic
improvement compared to its Objective-C counterpart. Take a look at the following
sample switch statement. Do you notice anything special?

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 229
switch recipeName {
case "Egg Benedict":
print("Let's cook!")
case "Mushroom Risotto":
print("Hmm... let me think about it")
case "Hamburger":
print("Love it!")
default:
print("Anything else")
}

First up, the switch statement can now handle strings. You can't do switching on
NSString in Objective-C. You had to use several if statements to implement the
above code. At last, Swift brings us this most sought after utilization of switch
statement.

Another interesting feature that you may notice is that there is no break. Recalled
that in Objective-C, you need to add a break in every switch case. Otherwise, it will
fall through to the next case. In Swift, you do not need to add the break statement
explicitly. Switch statements in Swift do not fall through the bottom of each case
and into the next one. Instead, as soon as the first matching case completes, the
entire switch statement completes its execution.

On top of that, the switch statement now supports range matching. Take a look at
the below code:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 230
var speed = 50
switch speed {
case 0:
print("stop")
case 0...40:
print("slow")
case 41...70:
print("normal")
case 71..<101:
print("fast")
default:
print("not classified yet")
}

// as the speed falls within the range of 41 and 70, it'll print normal to
console

The switch case lets you check values within a certain range by using two new
operators: ... and ..< . Both operators serve as a shortcut for expressing a
range of values.

Consider the sample range of "41...70", the ... operator defines a range that runs
from 41 to 70, including both 41 and 70. If we use the ..< operator instead of
... in the example, this defines a range that runs from 41 to 69. In other words,
70 is excluded from the range.

Tuples
Swift introduces an advanced type that is not available in Objective-C known as
tuples. Tuples allow developers to create a group of values and pass it around.
Consider that you're developing a method call to return multiple values, you can
now use tuples as a return value instead of returning a custom object.

Tuples treat multiple values as a single compound value. Here is an example:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 231
let company = ("AAPL", "Apple Inc", 93.5)

The above code creates a tuple that includes stock code, company name and stock
price. As you may be aware, you're allowed to put any value of any type within a
tuple. You can decompose the values of tuples and use it like this:

let (stockCode, companyName, stockPrice) = company


print("stock code = \(stockCode)")
print("company name = \(companyName)")
print("stock price = \(stockPrice)")

A better way to use tuple is to give each element in tuple a name and you can
access the element value by using dot notation. Here is another example:

let product = (id: "AP234", name: "iPhone X", price: 599)


print("id = \(product.id)")
print("name = \(product.name)")
print("price = USD\(product.price)")

A common use of tuples is to serve as a return value. In some cases, you want to
return multiple values in a method without using a custom class. You can use
tuples as the return value like the following example:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 232
class Store {
func getProduct(number: Int) -> (id: String, name: String, price: Int)
{
var id = "IP435", name = "iMac", price = 1399
switch number {
case 1:
id = "AP234"
name = "iPhone X"
price = 999
case 2:
id = "PE645"
name = "iPad Pro"
price = 599
default:
break
}

return (id, name, price)


}
}

In the above code, we create a method call named getProduct that takes in a
number and returns a product as tuple. You can call the method and store the
return value like below:

let store = Store()


let product = store.getProduct(number: 2)
print("id = \(product.id)")
print("name = \(product.name)")
print("price = USD\(product.price)")

Optionals Overview

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 233
What is optional? When declaring variables in Swift, they are designated as non-
optional by default. In other words, you have to assign a non-nil value to the
variable. If you try to set a nil value to a non-optional, the compiler will say, "Nil
cannot be assigned to type String!"

var message: String = "Swift is awesome!" // OK


message = nil // compile-time error

The same applies when declaring properties in a class. The properties are
designated as non-optional by default.

class Messenger {
var message1: String = "Swift is awesome!" // OK
var message2: String // compile-time error
}

You will get a compile-time error for message2 because it's not assigned with an
initial value. If you have written in Objective-C before, you may be a bit surprised.
In Objective-C or another programming language (e.g. Javascript), you won't get
any compile-time error when assigning nil to a variable or declaring a property
without initial value.

However, it doesn't mean you can't declare a property without assigning an initial
value in Swift. Swift introduces optional type to indicate the absence of a value. It
is defined by adding a question mark ? operator after the type declaration. Here is
an example:

class Messenger {
var message1: String = "Swift is awesome!" // OK
var message2: String? // OK
}

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 234
You can still assign a value when the variable is defined as optional. However if the
variable is not assigned with any value like the below code, its value automatically
defaults to nil .

Why Optionals?
Swift is designed for safety. As Apple mentioned, optionals are an example of the
fact that Swift is a type safe language. As you can see from the above examples,
Swift's optionals provide compile-time checks that would prevent some common
programming errors happening at run-time. Let's go through the below example
and you will have a better understanding of the power of optionals.

func findStockCode(company: String) -> String? {


if (company == "Apple") {
return "AAPL"
} else if (company == "Google") {
return "GOOG"
}

return nil
}

var stockCode: String? = findStockCode(company: "Facebook")


let text = "Stock Code - "
let message = text + stockCode // compile-time error
print(message)

This function accepts a company name and returns the corresponding stock code.
As you can see from the code, it can only supports two companies including Apple
and Google. The return value can be AAPL, GOOG, or nil.

Consider that if Swift doesn't have the optional feature, what will happen when we
execute the code above? As the method returns nil for Facebook, a runtime
exception will be thrown when running the app. In the worst case, the app may

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 235
crash.

With Swift's optionals, instead of discovering the error at runtime, it reveals the
error at compile time. Since stockCode is defined as an optional, Xcode
immediately detects a potential error ("value of optional type String? is not
unwrapped) and tells you to correct it.

As you can see from the example, Swift's optionals reinforce the nil-check and offer
compile-time cues to developers. Thus, the use of optionals contributes to better
code quality.

Unwrapping Optionals
So how can we make the code work? Apparently, we need to test if stockCode

contains a nil value or not. We modify the code as follows:

var stockCode: String? = findStockCode(company: "Facebook")


let text = "Stock Code - "
if stockCode != nil {
let message = text + stockCode!
print(message)
}

We used if to perform the nil-check. Once we know the optional must contain a
value, we unwrap it by placing an exclamation mark ( ! ) to the end of the
optional's name. In Swift, this is known as forced unwrapping. You use the !

operator to unwrap an optional and reveal the underlying value.

Referring to the above example, we only unwrap the stockCode optional after the
nil-check. We know the optional must contain a non-nil value before unwrapping
it using the ! operator. It is always recommended to ensure that an optional
contains a value before unwrapping it.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 236
But what if we forget the verification like below?

var stockCode:String? = findStockCode(company: "Facebook")


let text = "Stock Code - "
let message = text + stockCode! // runtime error

There will be no compile-time error. The compiler assumes that the optional
contains a value as forced unwrapping is used. When you run the app, a runtime
error is shown in the console.

Optional Binding
Other than forced unwrapping, optional binding is a simpler and recommended
way to unwrap an optional. You use optional binding to check if the optional
contains a value or not. If it does contain a value, unwrap it and put it into a
temporary constant or variable.

There is no better way to explain optional binding than using an example. We


convert the sample code in the previous example into optional binding:

var stockCode: String? = findStockCode(company: "Facebook")


let text = "Stock Code - "
if let tempStockCode = stockCode {
let message = text + tempStockCode
print(message)
}

The if let (or if var ) are the two keywords of optional binding. In plain
English, the code says, "If stockCode contains a value, unwrap it, set its value to
tempStockCode and execute the conditional block. Otherwise, just skip the block."
As tempStockCode is a new constant, you no longer need to use the ! suffix to
access its value.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 237
You can further simplify the code by evaluating the function in the if statement:

let text = "Stock Code - "


if var stockCode = findStockCode(company: "Apple") {
let message = text + stockCode
print(message)
}

Here stockCode is not an optional. There is no need to use the ! suffix to access
its value in the conditional block. If a nil value is returned from the function, the
block will not be executed.

Optional Chaining
Before explaining optional chaining, let's tweak the original example. We create a
new class named Stock with the code and price properties, which are optionals.
The findStockCode function is modified to return a Stock object instead of String.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 238
class Stock {
var code: String?
var price: Double?
}

func findStockCode(company: String) -> Stock? {


if (company == "Apple") {
let aapl: Stock = Stock()
aapl.code = "AAPL"
aapl.price = 90.32

return aapl

} else if (company == "Google") {


let goog: Stock = Stock()
goog.code = "GOOG"
goog.price = 556.36

return goog
}

return nil
}

We rewrite the original example as below. We first find the stock code/symbol by
calling the findStockCode function. And then we calculate the total cost needed
when buying 100 shares of the stock.

if let stock = findStockCode(company: "Apple") {


if let sharePrice = stock.price {
let totalCost = sharePrice * 100
print(totalCost)
}
}

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 239
As the return value of findStockCode() is an optional, we use optional binding to
check if it contains an actual value. Apparently, the price property of the Stock

class is an optional. Again we use the if let statement to test if stock.price

contains a non-nil value.

The above code works without any error. Instead of writing nested if let , you
can simplify the code by using Optional Chaining. The feature allows us to chain
multiple optionals together with the ?. operator. Here is the simplified version of
the code:

if let sharePrice = findStockCode(company: "Apple")?.price {


let totalCost = sharePrice * 100
print(totalCost)
}

Optional chaining provides an alternative way to access the value of price. The
code now looks a lot cleaner and simpler. Here I just cover the basics of optional
chaining. You can find further information about optional chaining in Apple's
Swift guide.

Failable Initializers
Swift has a feature called Failable Initializers. Initialization is the process of
providing initial values to each of the stored properties of a class. In some cases,
the initialization of an instance may fail. Now such failure can be reported using a
failable initializer. The resulting value of a failable initializer either contains the
object or nil . You will need to use if let to check if the initialization is
successful or not. Let me give you an example:

let myFont = UIFont(name : "AvenirNextCondensed-DemiBold", size: 22.0)

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 240
The initialization of the UIFont object will fail if the font file doesn't exist or is
unreadable. This initialization failure will report using a failable initializer. The
returned object is an optional that can either be the object itself or nil. Thus, we
need to use if let to handle the optional:

if let myFont = UIFont(name : "AvenirNextCondensed-DemiBold", size: 22.0)


{

// Further processing

Generics
The concept of Generics is not new and has been around for a long time in other
programming languages like Java. For iOS developers, however, you may be new
to Generics.

Generic Functions

Generics are one of the most powerful features of Swift and allow you to write
flexible functions. So what are Generics exactly? Well, let's take a look at an
example. Suppose you're developing a process function:

func process(a: Int, b: Int) {


// do something
}

The function accepts two integer values for further processing. What if you need to
take in other types of values like Double ? You probably write another function like
this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 241
func process(a: Double, b: Double) {
// do something
}

Both functions look very similar. Assuming the bodies of the functions are
identical, the main difference is the types of inputs they take in. With Generics, you
can simplify them into one generic function that handles multiple input types:

func process<T>(a: T, b: T) {
// do something
}

Now it defines a placeholder type instead of an actual type name. The <T> after
the function name indicates that this is a generic function. For the function
arguments, the actual type name is replaced with a generic type T .

You can call the process function in the same way. The actual type to use in place
of T will be determined each time the function is called.

process(a: 689, b: 167)

Generic Functions with Type Constraints


Let's take a look at another example. Suppose you're writing another function to
compare if two integer values are equal.

func isEqual(a: Int, b: Int) -> Bool {


return a == b
}

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 242
If you need to compare other types of value such as String, you'll write another
function like this:

func isEqual(a: String, b: String) -> Bool {


return a == b
}

With Generics, you'll combine the two functions into one:

func isEqual<T>(a: T, b: T) -> Bool {


return a == b
}

Again, we use T as a placeholder of the value types. But if you test out the above
code in Xcode, the function will not compile. The problem lies with the a==b

equality check. Though the function accepts values with any types, not every type
can support the equal to operator ( == ). This is why Xcode indicates an error. In
this case, you need to apply a type constraint for the generic function.

func isEqual<T: Equatable>(a: T, b: T) -> Bool {


return a == b
}

You write type constraint by placing a protocol constraint after a type parameter's
name, separated by a colon. Here the Equatable is the protocol constraint. In other
words, the function will only accept values that support the Equatable protocol.

In Swift, it comes with a standard protocol called Equatable. For any types
conforming to the Equatable protocol, they support the equal to ( == ) operator.
All standard types like String , Int , Double support the Equatable protocol.

So you can use the isEqual function like this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 243
isEqual(a: 3, b: 3) // true
isEqual(a: "test", b: "test") // true
isEqual(a: 20.3, b: 20.5) // false

Generic Types
You are not limited to use Generics in functions. Swift allows you to define your
own generic types. This can be custom classes or structure. The built-in Array and
Dictionary are examples of generic types.

Let's take a look at the below example:

class IntStore {
var items = [Int]()

func addItem(item: Int) {


items.append(item)
}

func findItemAtIndex(index: Int) -> Int {


return items[index]
}
}

The IntStore class is a simple class to store an array of Int items. It provides
two methods for:

Adding a new item to the store


Returning a specific item from the store

Apparently, the IntStore class supports items in Int type. Wouldn't it be great if
you can define a generic ValueStore class that manages any types of values? Here
is the generic version of the class:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 244
class ValueStore<T> {
var items = [T]()

func addItem(item: T) {
items.append(item)
}

func findItemAtIndex(index: Int) -> T {


return items[index]
}
}

Like what you have learned in the Generic functions section, you use a placeholder
type parameter (T) to indicate a generic type. The type parameter after the class
name indicates the class is a generic type.

To instantiate the class, you write the type to be stored in the ValueStore within
angle brackets.

var store = ValueStore<String>()


store.addItem(item: "This")
store.addItem(item: "is")
store.addItem(item: "generic")
store.addItem(item: "type")
let value = store.findItemAtIndex(index: 1)

You can call the method the same way as before.

Computed Properties
A computed property does not actually store a value. Instead, it provides its own
getter and setter to compute the value. Here is an example:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 245
class Hotel {
var roomCount: Int
var roomPrice: Int
var totalPrice: Int {
get {
return roomCount * roomPrice
}
}

init(roomCount: Int = 10, roomPrice: Int = 100) {


self.roomCount = roomCount
self.roomPrice = roomPrice
}
}

The Hotel class has two stored properties: roomPrice and roomCount . To
calculate the total price of a hotel, we can simply multiply roomPrice by
roomCount . In the past, you might create a method that performs the calculation
and returns the total price. With Swift, you can use computed properties instead.
In the example, totalPrice is a computed property. Rather than storing a fixed
value, it defines a custom getter that actually performs the calculation and returns
the total price of the rooms. Just like stored properties, you can access the
computed property through dotted syntax:

let hotel = Hotel(roomCount: 30, roomPrice: 100)


print("Total price: \(hotel.totalPrice)")
// Total price: 3000

Optionally, you can define a custom setter for the computed property. Consider the
same example again:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 246
class Hotel {
var roomCount: Int
var roomPrice: Int
var totalPrice: Int {
get {
return roomCount * roomPrice
}

set {
let newRoomPrice = Int(newValue / roomCount)
roomPrice = newRoomPrice
}
}

init(roomCount: Int = 10, roomPrice: Int = 100) {


self.roomCount = roomCount
self.roomPrice = roomPrice
}
}

Here we define a custom setter to calculate the new room price when the value of
total price is updated. When a new value of totalPrice is set, a default name of
newValue can be used in the setter. Base on newValue , you can then perform the
calculation and update the roomPrice accordingly.

Could you use methods instead of computed properties? Sure. To me, it is a matter
of coding style. Computed properties are especially useful for performing simple
conversions and calculations. As you can see from the above example, the
implementation is much cleaner.

Property Observers

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 247
Property observers are one of my favorite features of Swift. Property observers
observe and respond to changes in a property's value. The observers are called
every time a property's value is set. You have the option to define two kinds of
observers on a property:

willSet is called just before the value is stored.


didSet is called immediately after the new value is stored.

Consider the Hotel class again. For instance, we want to limit the room price to a
thousand dollars. Whenever a caller sets the room price to a value larger than
1000, we will set it to 1000. You can then use a property observer to monitor the
value change like this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 248
class Hotel {
var roomCount: Int
var roomPrice: Int {
didSet {
if roomPrice > 1000 {
roomPrice = 1000
}
}
}

var totalPrice: Int {


get {
return roomCount * roomPrice
}

set {
let newRoomPrice = Int(newValue / roomCount)
roomPrice = newRoomPrice
}
}

init(roomCount: Int = 10, roomPrice: Int = 100) {


self.roomCount = roomCount
self.roomPrice = roomPrice
}
}

Say, you set the roomPrice property to 2000 . The didSet observer will be called
and perform the validation. Because the value is larger than 1000, the room price
is then set it to 1000. As you can see, property observers are particularly useful for
value change notifications.

Failable Casts

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 249
as! (or as? ) is known as a failable cast operator. You have to either use as! or
as? to downcast an object to a subclass type. If you're quite sure that the
downcasting will succeed, you can use as! to force the casting. Here is an
example:

let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, f


or: indexPath) as! RestaurantTableViewCell

If you're not sure whether the casting will succeed, just use the as? operator. By
using as? , it returns an optional value, but in case the downcasting fails, the value
will be nil .

repeat-while
Apple introduces a new control flow operator called repeat-while , which is to
replace the classic do-while loop. Here is an example:

var i = 0
repeat {
i += 1
print(i)
} while i < 10

repeat-while evaluates its condition at the end of each pass through the loop. If
the condition is true , it repeats the block of code again. It exits the loop when the
condition evaluates to false .

for-in where Clauses

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 250
Not only can you iterate over all items in an array using a for-in loop, you can
define a condition to filter the items using the where clause. When you loop
through an array, for example, only those items that meet the criteria will be
processed.

let numbers = [20, 18, 39, 49, 68, 230, 499, 238, 239, 723, 332]
for number in numbers where number > 100 {
print(number)
}

In the above example, it only prints out those numbers that are greater than 100.

Guard
The guard keyword was first introduced in Swift version 2. According to Apple's
documentation, a guard is described like this:

A guard statement, like an if statement, executes statements depending on


the Boolean value of an expression. You use a guard statement to require that
a condition must be true in order for the code after the guard statement to be
executed.

Before I further explain the guard statement, let's go straight to the following
example:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 251
struct Article {
var title: String?
var description: String?
var author: String?
var totalWords: Int?
}

func printInfo(article: Article) {


if let totalWords = article.totalWords, totalWords > 1000 {
if let title = article.title {
print("Title: \(title)")
} else {
print("Error: Couldn't print the title of the article!")
}
} else {
print("Error: It only works for article with more than 1000 words."
)
}
}

let sampleArticle = Article(title: "Swift Guide", description: "A beginner


's guide to Swift 2", author: "Simon Ng", totalWords: 1500)
printInfo(article: sampleArticle)

In the code above, we create a printInfo function to display the title of an article.
However, we will only print the information for an article with more than a
thousand words. As the variables are optionals, we use if let to verify if the
optional contains a value or not. If the optional is nil , we display an error
message. If you execute the code in Playgrounds, it should display the title of the
article.

In general, the if-else statements follow this pattern:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 252
if some conditions are met {
// do something
if some conditions are met {
// do something
} else {
// show errors or performs other operations
}
} else {
// show errors or performs other operations
}

As you may notice, if you have to test more conditions, it will be nested with more
conditions. There is nothing wrong with that programmatically. But in terms of
readability, your code will get messy if there are a lot of nested conditions.

This is where the guard statement comes in. The syntax of guard looks like this:

guard else {
// what to do if the condition is not met
}
// continue to perform normal actions

If the condition, defined in the guard statement is not met, the code inside the
else branch is executed. On the other hand, if the condition is met, it skips the
else clause and continues the code execution.

If you rewrite the sample code using guard , it is a lot cleaner:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 253
func printInfo(article: Article) {
guard let totalWords = article.totalWords, totalWords > 1000 else {
print("Error: It only works for article with more than 1000 words."
)
return
}

guard let title = article.title else {


print("Error: Couldn't print the title of the article!")
return
}

print("Title: \(title)")
}

With guard , you focus on handling the condition you don't want. Furthermore, it
forces you to handle one case at a time, avoiding nested conditions. Thus, the code
is cleaner and easier to read.

Error Handling
When developing an app or any programs, you'll need to handle every possible
scenario, whether it's good or bad. Obviously, things may go wrong. Say, if you're
developing an app that connects to a cloud server, your app has to deal with
situations where the Internet connection is unavailable or the cloud server is failed
to connect.

In the older version of Swift, it lacks a proper error handling model. As an


example, you handle error conditions like this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 254
let request = NSURLRequest(URL: NSURL(string: "http://www.apple.com")!)
var response: NSURLResponse?
var error: NSError?
let data = NSURLConnection.sendSynchronousRequest(request, returningRespon
se: &response, error: &error)

if error == nil {
print(response)
// Parse the data
} else {
// Handle error
}

When calling a method that may cause a failure, you normally pass it with an
NSError object (as a pointer). If there is an error, the object will be assigned with
the corresponding error. You then check if the error object is nil or not and
respond to the error accordingly.

That's how you handle errors in the early version of Swift.

Note: NSURLConnection.sendSynchronousRequest() has been deprecated in iOS


9. As most readers are familiar with the usage, it is used in the example.

try / throw / catch

Beginning from Swift 2, it comes with an exception-like model using try-throw-

catch keywords. The same code snippet will become this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 255
let request = URLRequest(url: URL(string: "https://www.apple.com")!)
var response:URLResponse?
do {
let data = try NSURLConnection.sendSynchronousRequest(request, returni
ng: &response)
print(response)

// Parse the data


} catch {
// handle error
print(error)
}

Now you use a do-catch statement to catch errors and handle them accordingly.
As you may notice, we put a try keyword in front of the method call. With the
introduction of the error handling model, some methods can throw errors to
indicate failures. When we invoke a throwing method, you will need to put a try

keyword in front of it.

How do you know if a method throws an error? As you type the method in the
built-in editor, the throwing methods are indicated by the throws keyword.

Now that you should understand how to call a throwing method and catch the
errors, how do you indicate a method or function that can throw an error?

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 256
Imagine you're modelling a lite shopping cart. Customers can use the cart to
temporarily store and check out their items, but this cart will throw an error for the
following conditions:

The shopping cart can only store a maximum of 5 items. Otherwise, it throws
a cartIsFull error.
There must be at least one item in the shopping cart during checkout.
Otherwise, it throws a cartIsEmpty error.

In Swift, errors are represented by values of types conforming to the Error

protocol.

Usually, you use an enumeration to model the error conditions. In this case, you
can create an enumeration that adopts Error like this for the shopping cart
errors:

enum ShoppingCartError: Error {


case cartIsFull
case emptyCart
}

For the shopping cart, we create a LiteShoppingCart class to model its functions.
Here is a sample code snippet:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 257
struct Item {
var price:Double
var name:String
}

class LiteShoppingCart {
var items:[Item] = []

func addItem(item: Item) throws {


guard items.count < 5 else {
throw ShoppingCartError.cartIsFull
}

items.append(item)
}

func checkout() throws {


guard items.count > 0 else {
throw ShoppingCartError.emptyCart
}
// Continue with the checkout
}
}

If you take a closer look at the addItem method, you probably notice the throws

keyword. We append the throws keyword in the method declaration to indicate


that the method can throw an error. In the implementation, we use guard to
ensure the total number of items is less than 5. Otherwise, we throw the
ShoppingCartError.cartIsFull error.

To throw an error, you just write the throw keyword, followed by the actual error.
For the checkout method, we have a similar implementation. If the cart does not
contain any items, we throw the ShoppingCartError.emptyCart error.

Now, let's see what happens when performing a checkout on an empty cart. I
recommend you to fire up Xcode and use Playgrounds to test out the code.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 258
let shoppingCart = LiteShoppingCart()
do {
try shoppingCart.checkout()
print("Successfully checked out the items!")
} catch ShoppingCartError.cartIsFull {
print("Couldn't add new items because the cart is full")
} catch ShoppingCartError.emptyCart {
print("The shopping cart is empty!")
} catch {
print(error)
}

As the checkout method can throw an error, we use the do-catch statement to
catch the errors. If you execute the above code in Playgrounds, it will catch the
ShoppingCartError.emptyCart error and print the error message accordingly,
because we haven't added any items.

Now insert the following code in the do clause, right before calling the checkout

method:

try shoppingCart.addItem(item: Item(price: 100.0, name: "Product #1"))


try shoppingCart.addItem(item: Item(price: 100.0, name: "Product #2"))
try shoppingCart.addItem(item: Item(price: 100.0, name: "Product #3"))
try shoppingCart.addItem(item: Item(price: 100.0, name: "Product #4"))
try shoppingCart.addItem(item: Item(price: 100.0, name: "Product #5"))
try shoppingCart.addItem(item: Item(price: 100.0, name: "Product #6"))

Here we try to add a total of 6 items to the shoppingCart object. Again, it will
throw an error because the shopping cart cannot hold more than 5 items.

When catching errors, you can identify the exact error (e.g.
ShoppingCartError.cartIsFull ) to match, so you can provide very specific error
handling.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 259
If you do not specify a pattern in the catch clause, Swift will match any errors and
automatically bind the error to the error constant. As a best practice, you should
try to catch the specific errors that are thrown by the throwing method. At the
same time, you should write a catch clause that matches any errors. This ensures
all possible errors are handled.

Availability Checking
If all users are forced to upgrade to the latest version of iOS, this would make our
developers’ life much easier. Apple has tried hard to promote users to upgrade
their iOS devices. However, there are still some users who are reluctant to upgrade
their devices. Thus, in order to reach more users, our apps have to cater for
different versions of iOS (e.g. iOS 13, iOS 14 ,and iOS 15).

If you just use the latest version of APIs in your app, this may cause errors when
the app runs on older versions of iOS. When using an API that is only available on
the latest version of iOS, you will need to do some kinds of verification before using
the class or calling the method.

Say, the refreshable modifier for List is only available on iOS 15 (or later). If
you use the modifier on older versions of iOS, you’ll end up with an error.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 260
Swift has built-in support for checking API availability. You can easily define an
availability condition so that the block of code will only be executed on certain iOS
versions. Here is an example:

if #available(iOS 15.0, *) {
List {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}
.refreshable {
// update item
}
} else {
// Fallback on earlier versions
List {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}
}

You use the #available keyword in the if statement. In the availability


condition, you specify the OS versions (e.g. iOS 15) you want to verify. The * is
required and indicates that the if clause is executed on the minimum
deployment target and any other versions of OS. For the example, the body of the
if will be executed on iOS 15 or up, and other platforms such as watchOS.

What if you want to develop a class or method, which is available to certain


versions of OS? Swift lets you apply the @available attribute on
classes/methods/functions to specify the platform and OS version you want to
target. Say, for example, you’re developing a class named SuperFancy and it is only
available for iOS 15 or later. You can apply @available like this:

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 261
@available(iOS 15.0, *)
class SuperFancy {
// implementation
}

If you try to use the class on an Xcode project that supports multiple versions of
iOS, Xcode will show you the errors.

Note: You cannot test availability check in Playgrounds. If you want to give it a
try, create a new Xcode project to test out the feature.

Beginning iOS 17 Programming with Swift and SwiftUI - Sample | AppCoda © 2023 262

You might also like