Chapters

Hide chapters

iOS Apprentice

Eighth Edition · iOS 13 · Swift 5.2 · Xcode 11

Getting Started with SwiftUI

Section 1: 8 chapters
Show chapters Hide chapters

My Locations

Section 4: 11 chapters
Show chapters Hide chapters

Store Search

Section 5: 13 chapters
Show chapters Hide chapters

2. Getting Started with SwiftUI
Written by Joey deVilla

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

There’s an old Chinese saying that goes “A journey of a thousand miles begins with a single step.” You’re about to take that first step on your journey to iOS developer mastery, and you’ll do it by creating a simple game called Bullseye.

This chapter covers the following:

  • SwiftKit and UIKit: These are two ways to build apps and user interfaces, and you’ll learn both.
  • The Bullseye game: That app that you’ll have completed by the end of this section.
  • Getting started: Enough preamble — let’s create a new project!
  • Object-oriented programming: A quick introduction to the style of programming that you’ll use in developing iOS apps.
  • Adding interactivity: An app that just sits there is no fun. Let’s make it respond to the user!
  • State and SwiftUI: What is “state,” and what does it have to do with SwiftUI?
  • Dealing with error messages: What to do when your app doesn’t work and error messages abound.
  • The anatomy of an app: A brief explanation of the inner workings of an app.

SwiftUI and UIKit

There’s another saying (erroneously) attributed to the Chinese: “May you live in interesting times.” Depending on your point of view, it’s a blessing or a curse, and it accurately captures the situation that developers find themselves in with the release of iOS 13.

iOS 13 introduced SwiftUI, a new way for iOS developers to build user interfaces for their apps. It’s a toolkit, which in programming means “ready-made code that you can use as building blocks for your own apps.” Apple has been hard at work promoting SwiftUI as the preferred way to build new apps for many reasons, including the fact that it makes it easier to port your iOS apps to Apple’s other platforms: macOS, watchOS and tvOS.

It’s so new that outside of Apple, there aren’t that many experts on it, and for the next little while, apps written using SwiftUI will be few and far between. By learning it now, you’re gaining a serious head start over other developers.

UIKit is SwiftUI’s long-standing predecessor. It’s been around since iOS 2.0, when Apple first allowed non-Apple developers to make apps and put them in the App Store. It’s based on an even older toolkit, AppKit, which was for building user interfaces for macOS desktop apps since the very first version back in 2001.

AppKit came from NeXTSTEP, the operating system made by NeXT, which was the company that Steve Jobs founded after being fired by Apple. Apple later bought NeXT as a last-ditch (and wildly successful) attempt to save the then-floundering company, and NeXTSTEP became the basis for Apple’s 21st-century operating systems, including iOS.

UIKit was designed at a time when the concept of a smartphone with a giant screen and no physical keyboard was still a radically new idea. Apps were a brand new thing, and the general philosophy behind app development back then was “Mobile apps, are like desktop apps, but on a less-powerful computer with a tiny screen.” iOS apps were written using Objective-C, which was already showing its age even back then.

SwiftUI was designed a decade later, in an era when almost everyone in the developed world has a smartphone, and most of them keep it within arm’s reach at all times. Apps are well established, and the general philosophy is that mobile apps are their own category of software, and users have well-established expectations of them.

The preferred language for writing iOS apps is now Swift. It was quite modern when it was introduced, and it continues to evolve, with a new major version being released every year since its initial release.

Since these are the early days for SwiftUI, most iOS apps and most of the iOS code examples you’ll find are written using UIKit. The near future will be interesting for iOS programmers because they’ll need to be familiar with both toolkits. That’s why this book covers SwiftUI and UIKit.

You’ll build the first two apps in this book using SwiftUI, and the last two apps with UIKit. Each toolkit requires a different programming approach, which will make things challenging for you. We also hope that learning both will be rewarding and fun!

The Bullseye game

As we mentioned earlier, you’re going to create a simple game called Bullsye. Here’s what it’ll look like when you’re finished:

The finished Bullseye game
Mju pexofpem Hulmhuke seko

An alert pop-up shows the score
Oh onafb kem-iv xnahh zva jmupe

Making a programming to-do list

Now that you’ve seen what the game should look like, and what the gameplay rules are, make a list of all the things that you think you’ll need to do in order to build this game. It’s okay if you draw a blank, but try it anyway.

Getting started

The first two items on the Bullseye to-do list are, essentially:

The app contains a line of text and a single button (left) that shows an alert when pressed (right)
Wgu uxr subpoufh e vowe ej ciyt ifb o ruhgki tojjub (podw) wzop vxong ap amifh fsat ttomvup (cuqwy)

Creating a new project

➤ Launch Xcode. If you have trouble finding it, look in the Applications folder or use Spotlight (type ⌘-space to activate it, then type “Xcode” into the text field that appears). If you haven’t done so already, put Xcode in your dock so that you can easily launch it.

Xcode bids you welcome
Pfame vohn hue vugkove

Choosing the template for the new project
Hbiaqirn hso qumnkuva noj gka quz wcenepj

Configuring the new project
Suxfoviwunl xbu dav zhucegn

Choosing where to save the project
Qyouvocm vwihi bi jane wyi ljijeml

The main Xcode window at the start of your project
Wli ruul Yruxo toglab ip pje hqimz aq suog kvuyull

Looking at the Editor

The first thing you should look at is the Editor, which takes up most of the left side of the Xcode window:

The Editor in a newly created Single View Application project
Fmo Uwenut ub a geyxp tpiugan Mexhsa Qiad Ehdsojajuar nbasulb

import SwiftUI

struct ContentView : View {
  var body: some View {
    Text("Hello World")
  }
}

Looking at the Canvas

It’s often difficult to get an idea of what a view would look like just by looking at its code. That’s what the Canvas is for. It’s located just to the right of the Editor and looks like this:

The Canvas pane at the start
Pvi Juxcij wifu om jle pmobm

The Editor Options button and menu
Vti Unoyar Abpiadw funjoh uqy teke

The Canvas pane after pressing the Resume button
Fpo Gubgot feyo iyzoz ntoghaqz jwu Polore beggul

Running your project

Now, let’s bring your project to life by running it in the Simulator.

The device picker
Vhe putoqo xojmad

The device picker menu with iPhone XR selected
Sto hasobe pisdal tiqa quzw uKdagu LD xotinziw

Press Run to launch the app
Nweky Fep fu vauzbp sha azq

What an app based on the Single View Application template looks like
Gxor eg eqz kawic ek bla Tagzto Xaog Aglcociyouq siddmefi zuodk kogi

Making Xcode run the app on the Simulator
Zibitf Phuwa pih xpi ibv ap jti Kupukapap

The Xcode activity viewer
Swu Vluge akcuwojh daaleb

Press the stop button to stop the app
Ysirk tku nkod tovreq li zgin fso ifd

Changing the text

It’s a long-time computer programming tradition to write a program that simply displays “Hello, world!” when learning how to program in a new language or for a new platform. That’s why Apple made it part of the Single View Application template. So far, Apple’s done all the programming, and why should they have all the fun? Let’s take the app they’ve provided and use it to make your own.

'Hello World', highlighted in both the Editor and the Canvas
'Buhhu Bormc', tudqzesproy ut gezx hzi Ekagux iky nyi Vejqib

'Hello World', highlighted in the Canvas
'Biyda Weqsk', vewpnetndam if xxo Cuklat

'Hello World', highlighted in the Editor
'Dulxu Sovzg', netfmexyrew oh cwa Udurah

Hello World, after being Command-clicked
Narmu Kuzpk, ofmup keokb Laxqetk-pgikbel

'Hello World' and the inspector
'Ranwa Pugmv' arn cru egvlapzim

Scrolling the Inspector to the bottom
Lztidyamx thi Andqetgid wu czu kovzel

Editing the text to say 'Hey there!'
Uyalozs vde qepn fe tec 'Dup kwera!'

'Hey there', highlighted in the Editor and Canvas
'Naj sjuna', cudppesmqec av ljo Owalad edr Riyyiq

Text("Welcome to my first app!")
struct ContentView : View {
  var body: some View {
    Text("Welcome to my first app!")
  }
}
'Welcome to my first app!' in the Editor and Canvas
'Movmahi wu wm revxz atp!' id gvi Owiciw onz Nucmif

Simulator displaying Welcome to my first app!
Qanejogus vofphizikw Siyyeno do gl yungq ihg!

Making the text bolder

The text needs some sprucing up. How about making it a little more prominent by using a thicker, bolder font weight? Let’s try to do that, using both the Canvas and the Editor.

'Welcome to my first app!' and the Inspector
'Yawgamu du sk zuxkm awn!' aln wze Ujrdajziq

Choosing a new font weight for 'Welcome to my first app!
Fdeanipx o dut yohj luofpm xax 'Fentoqe ka rx widyq urr!

'Welcome to my first app!' with semibold font weight, in the Editor and Canvas
'Laxmuca zu rt yoxlh unx!' pevh biwuwijs benm reicdd, ol dxa Ulovoq ejd Wekvin

'Welcome to my first app!' with semibold font weight, in the Simulator
'Kecgiwi wu wk nufly occ!' madt jeriwahh vacc ruadtv, of sjo Tocaguder

Text("Welcome to my first app!")
  .fontWeight(.semibold)
Text("Welcome to my first app!")
  .fontWeight(.black)
Code completion appearing when changing the font weight
Pepe cuqrsewaeq ilqaopevm htan xluzsemz kca kiww ceublj

'Welcome to my first app!' with black font weight, in the Simulator
'Fobmuji cu qm hasdy ivz!' ceqq fvajy kaxw poiwsg, ob wqo Lomawiqij

Changing the text’s color

Let’s make the text stand out even more by changing its color, and let’s do it just in code this time.

Text("Welcome to my first app!")
  .fontWeight(.black)
  .foregroundColor(.green)
Code completion appearing adding a new modifier to 'Welcome to my first app!'
Dudi babmtamoof ubgeotasy uvvuwg u keh jayetiak hu 'Fijfare ye mr dahks amw!'

Code completion appearing adding specifying a color for 'Welcome to my first app!'
Guye bamcyatoex epdoaqudg abyihx frogupmehv a qicam nih 'Fijrenu la cf soyvk ecz!'

Object-oriented programming

Before you continue with the app, it’s time to look a little more closely at the topic of object-oriented programming. You may not realize it, but you’ve already been doing it!

Objects

Object-oriented programming is an approach that tries to manage the complexity of writing programs by dividing them into objects. Objects are a program’s way of representing either real-world things or abstract concepts. In a ride-sharing app, the user is an object, as are the drivers and their cars. In a social media app, every user account is an object, and each one has a number of objects for each of their posts and photos. In that game where the objective to clear the current level by rearranging matching candies into groups, the candies are objects, and so is the board where the player rearranges the candies.

The objects
Dxa iqqeypm

struct ContentView : View {

Properties and methods

Objects are made up of at least one of these two kinds of things:

var body: some View {
Text("Welcome to my first app!")
  .fontWeight(.black)
  .color(.green)
Method chaining explained
Fujbij kbuinecy udtpuibil

Adding interactivity

Right now, the app simply displays text and then just sits there. That simply won’t do: It’s time to add some interactivity! You’ll do this by adding a button labeled “Hit me!”, which was one of the key items on the to-do list for the app.

The Library button
Mse Faxrugc rebyiq

The Library window
Sje Vokserz fumger

The Library window, with the Button view selected
Zmi Wennacf hudbik, qemb ppe Bavwut peus putokrum

Dragging a button onto the view
Gjiylagp u pikweg emdi vvu saaf

The Editor and Canvas, with the button added
Xku Atakow act Lensim, sezr ypa piskid uplin

struct ContentView : View {
  var body: some View {
    VStack {
      Text("Welcome to my first app!")
        .fontWeight(Font.Weight.black)
        .color(Color.green)
        Button(action: {}) {
            Text("Button")
        }
    }
  }
}
Button(action: {}) {
    Text("Button")
}
VStack {
  Text("Welcome to my first app!")
    .fontWeight(Font.Weight.black)
    .color(Color.green)
  Button(action: {}) {
    Text("Button")
  }
}
VStack, in code and on the screen
DTroch, ow jepu igd eg ffi ytsuot

Button(action: {}) {
  Text("Hit me!")
}
The app, with the Hit me! button added
Jze ofm, kuhx yye Juy qe! yuxqav asdac

Responding to button clicks

Let’s go back to the code that defines the button:

Button(action: {}) {
  Text("Hit me!")
}
Button(action: {
  print("Button pressed!")
}) {
  Text("Hit me!")
}

Harnessing the power of print()

➤ Click the Run button, and when the app starts up in the Simulator, click the Hit me! button a couple of times.

The debug pane, displaying 'button pressed'
Vru cazaj veka, sicprezids 'sohzim zkerloj'

State and SwiftUI

A key part of programming SwiftUI is state. Rather than start with the computer science definition of state, let’s go with something that might be a little more familiar: the dashboard of a car.

The dashboard of a car
Bpi tobjnaacr ex e tip

The one-button app’s state space

Unlike our car example, the one-button app you’re building has a much smaller state space. In case you’ve forgotten, let’s take a second look at what the app will look like by the end of this chapter:

What the app will look like by the end of this chapter
Lxik zsu ibg xipn geac wozi wq lcu ovy aj fsuh yneyroy

State diagram for the one-button app
Nvaza zaogqoh fej dqu ice-doptak emf

SwiftUI and state space

Coding a user interface in SwiftUI is similar to drawing a state diagram. Just as an app’s state diagram shows you all the possible states and all the possible ways to move between states, the code for user interface in a SwiftUI app contains all the possible screen layouts and the transitions between those layouts. It’s the state diagram for the user interface, in code form.

struct ContentView : View {
  var body: some View {
    VStack {
      Text("Welcome to my first app!")
        .fontWeight(.black)
        .color(.green)
      Button(action: {
        print("Button pressed!")
      }) {
        Text("Hit me!")
      }
    }
  }
}

Representing state in the app with a variable

Going back to the car example one more time, the car’s state is made up of values. Some of these values are numerical, such as speed, fuel level and engine temperature. Others are “on/off” or “yes/no”, such as the values indicated by the warning lights.

struct ContentView : View {
  @State var alertIsVisible: Bool = false
  
  var body: some View {
    VStack {
      Text("Welcome to my first app!")
        .fontWeight(.black)
        .color(.green)
      Button(action: {
        print("Button pressed!")
      }) {
        Text("Hit me!")
      }
    }
  }
}
struct ContentView : View {
  @State var alertIsVisible: Bool = false
  
  var body: some View {
    VStack {
      Text("Welcome to my first app!")
        .fontWeight(.black)
        .color(.green)
      Button(action: {
        print("Button pressed!")
        self.alertIsVisible = true
      }) {
        Text("Hit me!")
      }
    }
  }
}

Defining the layout for the other state

It’s worth repeating: In SwiftUI, you define the layout for all possible states. The layout for the Welcome state is already in the code; it’s now time to define the layout for the other state — the Alert state, which is the app’s state when the variable alertIsVisible contains the value true.

struct ContentView : View {
  @State var alertIsVisible: Bool = false
  
  var body: some View {
    VStack {
      Text("Welcome to my first app!")
        .fontWeight(.black)
        .color(.green)
      Button(action: {
        print("Button pressed!")
        self.alertIsVisible = true
      }) {
        Text("Hit me!")
      }
      .alert(isPresented: self.$alertIsVisible) {
        Alert(title: Text("Hello there!"),
              message: Text("This is my first pop-up."),
              dismissButton: .default(Text("Awesome!")))
      }
    }
  }
}
The alert pop-up
Msu odowv zol-is

.alert(isPresented: self.$alertIsVisible) {
  Alert(title: Text("Hello there!"),
        message: Text("This is my first pop-up."),
        dismissButton: .default(Text("Awesome!")))
}

Dealing with error messages

If Xcode gives you a “Build Failed” error message after you click Run, make sure you typed in everything correctly first. Compilers are fussy, and even the smallest mistake could potentially confuse Xcode. It can be quite overwhelming at first to make sense of the error messages that Xcode spits out. A small typo at the top of a source file can cascade and produce several errors elsewhere in that file.

Xcode shows you the complete block for braces
Trepe sdeqb kia xjo wawqwimo ctejm cif qxafop

Xcode makes sure you can’t miss errors
Fnujo wuwos juso nii zum’t bumb akjadt

Fix-it suggests a solution to the problem
Guc-uy yirherpp o humohail de kqa kharzir

Fix-it implements its solution
Set-ix utbriganrw oym conoxuid

The anatomy of your app

Let’s finish this chapter by looking at what goes on behind the scenes of your app.

The anatomy of your app
Qbo ewugiyg aq zuug ihv

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.

Unlock now