Chapters

Hide chapters

iOS Apprentice

Eighth Edition · iOS 13 · Swift 5.2 · Xcode 11

My Locations

Section 4: 11 chapters
Show chapters Hide chapters

Store Search

Section 5: 13 chapters
Show chapters Hide chapters

8. The Final App
Written by Joey deVilla

You might be thinking, “Okay, Bullseye is now done and I can move on to the next app!” If you were, I’m afraid that you’re in for some disappointment — there’s just a teensy bit more to do in the game.

“But the task list is complete!” you might say, and you’d be right. It’s just that software has a way of finding more things for you to do. In this chapter, we’ll add a few more touches to Bullseye to make it truly polished. One of these touches is absolutely necessary for apps to be published in the App Store. And finally, there’s the matter of trying out Bullseye on a real device instead of the Simulator.

Don’t worry; you’re almost done!

Here are the specific items covered in this chapter:

  • Including animation: Add some animation to make the start of a new round or game a bit more dynamic.
  • Adding an icon: Giving the app its own distinctive icon, replacing the default blank one.
  • Display name: Set the display name — the one users see on the home screen — for the app.
  • Running the app on a device: How to configure everything to run your app on an actual device.

Adding a title to the navigation bar

The NavigationView object that Bullseye uses to take the user from the main screen to the “About” screen and back adds a translucent navigation bar that runs across the top of the screen. This bar gives the user a visual hint that the app has more than one screen and also provides a place for navigation controls, such as the Back button that automatically appears on the “About” screen:

The 'About' screen, with the navigation bar displaying a 'Back' button
The 'About' screen, with the navigation bar displaying a 'Back' button

The navigation bar seems a little less useful on the main screen. There, it’s an empty translucent strip that gives the user the impression that the developer — that’s you! — didn’t quite finish working on the user interface:

The main screen with a blank navigation bar
The main screen with a blank navigation bar

We can solve this problem and do a little app marketing at the same time by putting a title into the navigation bar when it’s on the main screen. We can do this with a method available to any view object called navigationBarTitle(), which accepts a Text object to set text that appears in the center of the navigation bar.

The navigationBarTitle() method can be called from any view inside the NavigationView. To make it easy to see that the NavigationView is getting a title, we’ll call navigationBarTitle() from the first Spacer in the main screen’s NavigationView.

➤ Change the start of ContentView’s body variable to the following:

var body: some View {
  NavigationView {
    VStack {
      Spacer().navigationBarTitle("🎯 Bullseye 🎯")

➤ Run the app. You should see a title in the formerly blank navigation bar:

The main screen with a navigation bar with a title
The main screen with a navigation bar with a title

When you navigate away from a page with navigation bar title, the “Back” button on the destination page displays the name of the page you just left:

The 'About' screen with a 'Bullseye' back button in the navigation bar
The 'About' screen with a 'Bullseye' back button in the navigation bar

We can also add a navigation bar title to the “About” page. Once again, it’s a matter of calling the navigationBarTitle() method from any of its views. We’ll cakk it from the first Text element on that screen.

➤ Change the start of AboutView’s body variable to the following:

var body: some View {
  Group {
    VStack {
      Text("🎯 Bullseye 🎯")
        .modifier(AboutHeadingStyle())
        .navigationBarTitle("About Bullseye")

➤ Run the app and press the Info button. The “About” page will now have a title:

The 'About' screen with a navigation bar title
The 'About' screen with a navigation bar title

Including animation

There’s one last improvement that you can add to the app: Animation. iOS contains a technology called Core Animation that makes it very easy to add animation effects to your app’s views. With Core Animation, you can get several different kinds of animation with very little code. SwiftUI gives you access to Core Animation’s power and, with it, you can add subtle animations (with an emphasis on subtle!) that can make your app a delight to use.

Right now, when a new round or game begins, the slider simply snaps to its randomly-determined position. You’ll add an animation to the slider so that it slides to that randomly-determined position instead.

➤ In the Slider row section of ContentView’s body property, change the line that defines the slider to look like this:

Slider(value: $sliderValue, in: 1...100)
  .accentColor(Color.green)
  .animation(.easeOut)

➤ Run the app. You can either play a few rounds or, if you’re feeling impatient, you can simply press the Start over button over and over again. Either way, you’ll see the slider slide to its new random position.

The call to the slider’s animation() method added the animation effect to the slider. It takes a parameter that specifies the kind of animation that should be used. In this case, you provided a parameter called .easeOut, which is an “ease out” animation. “Ease out” means that as the slider approaches its destination it slows down a little, making its motion look more natural.

The animation() method is called whenever the app changes the position of the slider, which in turn happens when the app changes the value of the sliderValue property. This means that the animation takes place whenever the game starts, at the start of a new round, and at the start of a new game.

Adding an icon

You’re almost done with the app, but there are still a few loose ends to tie up. You may have noticed that the app has a really boring white icon. That won’t do!

➤ Open the asset catalog (Assets.xcassets) and select AppIcon:

The AppIcon group in the asset catalog
The AppIcon group in the asset catalog

It turns out that there isn’t just one icon for an app, but 18 of them, to account for various device screen resolutions and different uses. They range in size from a minuscule 20 by 20 pixels for use in notifications to an enormous 1024 by 1024 pixels for the App Store.

Importing icons is like importing images — it’s a drag-and-drop process.

➤ In Finder, open the Resources folder for this book and then open the Icon folder. Drag the Icon-40.png file into the 2x slot in the area marked iPhone Notification / iOS 7 - 13 / 20pt:

Dragging the icon into the asset catalog
Dragging the icon into the asset catalog

You’ve probably figured out that the numbers in the filenames in the Icon folder indicate their dimensions in pixels. The Icon-40.png file is a 40-pixel by 40-pixel icon. So why are you dragging the Icon-40.png file into the slot marked 20pt and not Icon-20.png?

The reason is that the filenames specify the icon size in pixels and the slots specify the icon size in points. On pre-Retina iPhones, one point was equal to one pixel. Retina iPhones and iPads have twice the pixel density. So, on those devices, one point is equal to two pixels. The Retina HD iPhones — the X, XS, XS Max, and any iPhone with a “+” in its name — have three times the pixel density. For them, one point is equal to three pixels.

Also, if you look at each of the slots, they’ve conveniently put the pixel dimensions in each one.

➤ Drag the Icon-60.png file into the 3x slot next to it. This is for the iPhone Plus devices with their 3x resolution.

➤ For the iPhone / Settings - iOS 7 - 13 / 29pt slots, drag the Icon-58.png file into the 2x slot and Icon-87.png into the 3x slot. What, you don’t know your times table for 29?

➤ For the iPhone Spotlight / iOS 7 - 13 / 40pt slots, drag the Icon-80.png file into the 2x slot and Icon-120.png into the 3x slot.

➤ For the iPhone App / iOS 7 - 13 / 60pt slots, drag the Icon-120.png file into the 2x slot and Icon-180.png into the 3x slot.

That’s four icons in two different sizes. Phew!

The other AppIcon groups are mostly for the iPad.

➤ Drag the specific icons — based on size — into the proper slots for iPad. Notice that the iPad icons need to be supplied in 1x and 2x sizes but not 3x. You can either do the math to match pixel and point sizes or use the points specified in each slot to figure out which icons need to go in which iPad slots.

The full set of icons for the app
The full set of icons for the app

➤ Run the app and close it. You’ll see that the icon has changed on the Simulator’s springboard. If not, remove the app from the Simulator and try again (sometimes the Simulator keeps using the old icon and re-installing the app will fix this).

The icon on the Simulator's springboard
The icon on the Simulator's springboard

Display name

The text below the app’s icon on the Home screen is its display name. It can be different from the project name, and it often has to be — there’s a limited amount of space under any app’s icon, and display names can be only one line long.

You started with the project with the name Bullseye. Xcode automatically used it as the app’s display name. Sometimes, as you work on a project, you’ll come up with a better one. Let’s pretend that this happened, and in a fit of inspiration, you decided to change the name of the app to Bullseye🎯 (note the “bullseye” emoji added at the end).

➤ Go to the Project Settings screen. The very first option is Display Name. Change this to Bullseye🎯:

Changing the display name of the app
Changing the display name of the app

In case you’ve forgotten, you access the macOS emoji keyboard by pressing ctrl + ⌘ + space.

As with many of your project’s settings, you can also find the display name in the app’s Info.plist file. Let’s take a look.

➤ From the Project navigator, select Info.plist.

The display name of the app in Info.plist
The display name of the app in Info.plist

The row Bundle display name contains the new name you’ve just entered.

Note: If Bundle display name is not present, the app will use the value from the field Bundle name. That has the special value “$(PRODUCT_NAME)”, meaning Xcode will automatically put the project name, BullsEye, in this field when it adds the Info.plist to the application bundle. By providing a Bundle display name you can override this default name and give the app any name you want.

➤ Run the app and quit it to see the new name under the icon.

The bundle display name setting changes the name under the icon
The bundle display name setting changes the name under the icon

Guess what — your very first app is complete!

You can find the project files for the finished app under 08 - The Final App in the Source Code folder.

Running the app on a device

So far, you’ve run the app on the Simulator. That’s nice, but you probably didn’t take up learning iOS development simply to make apps for pretend devices. You want to make apps that run on real iPhones and iPads and even distribute them in the App Store! There’s hardly anything more satisfying than seeing an app that you made running on your own device — except showing off the fruits of your labor to other people!

Don’t get me wrong: Developing your apps on the Simulator works very well. When developing, it’s very convenient to spend most of your time with the Simulator and only test the app on a device every so often.

However, you do need to run your creations on a real device in order to test them properly. There are some things the Simulator simply can’t do. For example, if your app needs the iPhone’s accelerometer, you have no choice but to test that functionality on an actual device. You can’t just sit there and shake your Mac! (Well, you can, but it’ll have no effect.)

In the past, you needed a paid Developer Program account to run apps on your iPhone. These days, you can do it for free. All you need is an Apple ID, and the latest Xcode makes it easier than ever before.

Configuring your device for development

➤ Connect your iPhone, iPod touch or iPad to your Mac using a USB cable.

➤ From the Xcode menu bar select Window ▸ Devices and Simulators to open the Devices and Simulators window. Yours will look similar to the one shown below:

The Devices and Simulators window
The Devices and Simulators window

The left column contains a list of devices that are currently connected to your Mac and which can be used for development.

➤ Click on a device name in the left column to select it.

If this is the first time you’re using the selected device with Xcode, the window will show a message that says something like: “iPhone is not paired with your computer.” To pair the device with Xcode, you’ll need to unlock the device first. Once you’ve unlocked it, an alert will pop up on the device asking you to trust the computer you’re trying to pair with. Tap on Trust to continue.

Xcode will now refresh the page and let you use the device for development. Give it a few minutes and see the progress bar in the main Xcode window. If it takes too long, you may need to unplug the device and plug it back in.

At this point it’s possible you may get the error message: “An error was encountered while enabling development on this device.” You’ll need to unplug the device and reboot it. Make sure to restart Xcode before you reconnect the device.

Also, note the checkbox that says Connect via network? That checkbox (gasp!) allows you to deploy and debug code on your iPhone over WiFi!

That takes care of deploying to your device — cool!

Adding your developer account to Xcode

The next step is setting up your Apple ID with Xcode. It’s okay to use the same Apple ID that you’re already using with iTunes and your iPhone for hobby projects. However, if you run a business you might want to create a new Apple ID strictly for that purpose. Of course, if you’ve already registered for a paid Developer Program account, you should use that Apple ID.

➤ Open the Accounts pane in the Xcode Preferences window:

The Accounts preferences
The Accounts preferences

➤ Click the + button at the bottom, select Add Apple ID from the list of options and click Continue:

Xcode Account Type selection
Xcode Account Type selection

Xcode will ask for your Apple ID:

Adding your Apple ID to Xcode
Adding your Apple ID to Xcode

➤ Type your Apple ID username and click Next.

Xcode will ask for your Apple ID password:

Entering your Apple ID password
Entering your Apple ID password

Xcode verifies your account details and adds it to the stored list of accounts.

Note: It’s possible that Xcode is unable to use the Apple ID your provided. For example, if it has been used with a Developer Program account in the past that is now expired. The simplest solution is to make a new Apple ID. It’s free and only takes a few minutes. appleid.apple.com

You still need to tell Xcode to use this account when building your app.

Code signing

➤ Go to the Project Settings screen for your app target. In the General tab go to the Signing & Capabilities section.

The Signing options in the Project Settings screen
The Signing options in the Project Settings screen

In order to allow Xcode to put an app on your device, the app must be digitally signed with your Development Certificate. A certificate is an electronic document that identifies you as an iOS application developer and is valid only for a specific amount of time. Creating and using a development certificate is free.

Apps that you want to submit to the App Store must be signed with another certificate, the Distribution Certificate. To create and use a distribution certificate, you must be a member of the paid Developer Program.

In addition to a having a valid certificate, you also need a Provisioning Profile for each app you make. Xcode uses this profile to sign the app for use on your particular device or devices. The specifics don’t really matter. just know that you need a provisioning profile or the app won’t be installed on your device.

Making the certificates and provisioning profiles used to be a really frustrating and error-prone process. Fortunately, those days are over: Xcode now makes it really easy. When the Automatically manage signing option is enabled, Xcode will take care of all this business with certificates and provisioning profiles and you don’t have to worry about a thing.

➤ Click on Team to select your Apple ID.

Xcode will now automatically register your device with your account, create a new Development Certificate and download and install the Provisioning Profile on your device. These are all steps you had to do by hand in the past, but now Xcode takes care of all that.

You could get some signing errors like these:

Signing/team set up errors
Signing/team set up errors

The app’s Bundle Identifier must be unique. If another app is already using that identifier, your app can’t use it. That’s why it’s suggested that you start the Bundle ID with your own domain name. The fix is easy: change the Bundle Identifier field to something else and try again.

It’s also possible you get this error (or something similar):

No devices registered
No devices registered

Xcode must know about the device that you’re going to run the app on. That’s why you were told to connect your device first. Double-check that your device is still connected to your Mac and that it is listed in the Devices window.

Running the app on your device

If everything goes smoothly, go back to Xcode’s main window and click on the dropdown in the toolbar to change where you will run the app. The name of your device should be in that list somewhere. It should look something like this:

Setting the active device
Setting the active device

You’re all set and ready to go!

➤ Tap Run to launch the app.

At this point, you may get a pop-up with the question: “Codesign wants to sign using key… in your keychain.” If so, answer with Always Allow. This is Xcode trying to use the new Development Certificate you just created — you just need to give it permission first.

Does the app work? Awesome! If not, read on…

When things go wrong…

There are a few things that can go wrong when you try to put the app on your device, especially if you’ve never done this before, so don’t panic if you run into problems.

The device is not connected

Make sure your iPhone, iPod touch or iPad is connected to your Mac. The device must be listed in Xcode’s Devices window and there should not be a yellow warning icon.

The device does not trust you

You might get this warning:

Quick, call security!
Quick, call security!

On the device itself, there will be a pop-up with the text: “Untrusted Developer. Your device management settings do not allow using apps from developer…”

If this happens, open the Settings app on the device and go to General ▸ Profile. Your Apple ID should be listed in that screen. Tap it, followed by the Trust button. Then, try running the app again.

The device is locked

If your phone locks itself with a passcode after a few minutes, you might get this warning:

The app won't run if the device is locked
The app won't run if the device is locked

Simply unlock your device by holding the home button, typing in the 4-digit passcode or using FaceID and tap Run again.

Signing certificates

If you’re curious about these certificates, then open the Preferences window and go to the Accounts tab. Select your account and click the Manage Certificates… button in the bottom-right corner.

This brings up another panel, listing your signing certificates:

The Manage Certificates panel
The Manage Certificates panel

When you’re done, close the panel and go to the Devices and Simulators window. You can see the provisioning profiles that are installed on your device by right-clicking the device name and choosing Show Provisioning Profiles.

The provisioning profiles on your device
The provisioning profiles on your device

The “iOS Team Provisioning Profile” is the one that allows you to run the app on your device. By the way, they call it the “team” profile because often there is more than one developer working on an app and they can all share the same profile.

You can have more than one certificate and provisioning profile installed. This is useful if you’re on multiple development teams or if you prefer to manage the provisioning profiles for different apps by hand.

To see how Xcode chooses which profile and certificate to sign your app with, go to the Project Settings screen and switch to the Build Settings tab. There are a lot of settings in this list, so filter them by typing signing in the search box. Also make sure All is selected, not Basic.

The screen will look something like this:

The Code Signing settings
The Code Signing settings

Under Code Signing Identity it says iOS Developer. This is the certificate that Xcode uses to sign the app. If you click on that line, you can choose another certificate. Under Provisioning Profile you can change the active profile. Most of the time, you won’t need to change these settings but at least you know where to find them now.

And that concludes everything you need to know about running your app on an actual device.

The end… or the beginning?

It’s been a bit of a journey to get to this point — if you’re new to programming, you’ve had to get a lot of new concepts into your head. I hope your brain didn’t explode! At the very least, you should have gotten some insight into what it takes to develop an app.

I don’t expect you to totally understand everything that you did, especially not the parts that involved writing Swift code and the finer points of building a user interface with SwiftUI. It is perfectly fine if you didn’t, as long as you’re enjoying yourself and you sort of get the basic concepts of objects, methods and variables. If you were able to follow along and do the exercises, you’re in good shape!

I encourage you to play around with the code a bit more. The best way to learn programming is to do it, and that includes making mistakes and messing things up. I hereby grant you full permission to do so! Maybe you can add some cool new features to the game (and if you do, please let me know).

In the Source Code folder for this book, you can find the complete source code for the Bullseye app. If you’re still unclear about anything you did between the start of the project and this finished product, it might be a good idea to look at this cleaned up source code.

If you’re interested in how the graphics for Bullseye were made, take a peek at the Photoshop files in the Resources folder. The wood background texture was made by Atle Mo from subtlepatterns.com.

If you’re feeling exhausted after all that coding, pour yourself a drink and put your feet up for a bit. You’ve earned it! On the other hand, if you just can’t wait to get coding again, let’s move on to our next app!

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.
© 2026 Kodeco Inc.