SwiftUI — How to setup a project

Martin Lasek
Jun 5, 2019 · 7 min read
Image for post
Image for post

In this tutorial, we will take a small step back and when setting up a new project understand the entry point of our App, how all views are connected to each other and to our code and finally explain how SwiftUI works 😊

Also, you can watch the video tutorial for this article:

SwiftUI is the new UI framework developed by Apple. It provides a new API allowing you to write code that works on all Apple platforms. Yes you heard right! All Apple platforms: iOS, iPadOS, watchOS and tvOS!

Requirements

Writing our first SwiftUI code

import SwiftUIstruct Hero: Identifiable {
let id: UUID = UUID()
let name: String
}
struct ContentView: View {
let heros = [
Hero(name: "Iron Man"),
Hero(name: "Thor")
Hero(name: "Spider-Man")
]
var body: some View {
List(heros) { hero in
Text(hero.name)
}
}
}

Done. I’m not joking. There’s no hidden code or black magic happening. This is all it needs! And here’s what this code looks like:

Image for post
Image for post

Excited? But also a tiny bit intimidated? No worries it becomes intuitive pretty quick. First let‘s take a small step back and understand the entry point of the App, how all views are connected to each other and to our code and finally explain what this code here means 😊

Index

  1. Understand the entry point of the App
  2. Understand the canvas (Simulator) next to your code
  3. Define your SwiftUI View as the first View on App launch
  4. Where to go from here

1. Create a new project including SwiftUI

Image for post
Image for post
Xcode-Beta: Create a new project by selecting Single View App.

Next, make sure that Use SwiftUI is checked before you finally determine where to create the project:

Image for post
Image for post

2. Understand the entry point of the App

This is probably what you see right now:

Image for post
Image for post

Go ahead and delete (Move to Trash) both files AppDelegate.swift and ContentView.swift. Now go inside SceneDelegate.swift and add @UIApplicationMain at the top of the SceneDelegate class and let this class conform to UIApplicationDelegate — with that you are simply saying that this is the entry point of your application to start running your code. Finally, delete all the functions inside this class except of this one:

Image for post
Image for post

No fear — go and select for example the iPhone XR as a simulator and hit run!
It will launch your project and greet you with a working app! Yes it is a black screen hahah but what else should it show if we haven’t coded anything yet.

3. Understand the canvas (Simulator) next to your code

Image for post
Image for post
We’re not using the SwiftUI View — we want to build it ourselves right? I named the file AwesomeView.swift

Inside our new awesome file add the following code:

import SwiftUIstruct AwesomeView: View {
var body: some View {
Text("Hey! This is aawweesomee!")
}
}

We are defining a struct and when conforming to the protocol View we have one required implementation this protocol is asking for and that is the computed body property of type some View. This new Swift 5.1 keyword some means that the computed property can return anything when that something at least conforms to the View protocol. Which is true for Text. And with Swift 5.1 we also don’t have to add the return keyword anymore. The last line of a function or closure will be returned automagically.

This right here is a SwiftUI View. Our first SwiftUI View!

Let’s add some more code to trigger the fancy canvas that shows a live preview of every line of code that we are writing:

import SwiftUIstruct AwesomeView: View {
var body: some View {
Text("Hey! This is aawweesomee!")
}
}
#if DEBUG
struct AwesomeView_Previews: PreviewProvider {
static var previews: some View {
AwesomeView()
}
}
#endif

I’ll explain in a second how this struct works — it’s nothing fancy I promise!

First, go on the top right corner click on that hamburger-like menu icon and click on the Editor and Canvas menu point:

Image for post
Image for post
You can also reveal the canvas with cmd+option+enter or hide it with cmd+enter.

Next click on Resume or on Try again depending on your canvas state:

Image for post
Image for post

This shows you a preview of all the Views that you return in the closure inside the AwesomeView_Previews struct. It’s only one View you are returning there. It’s an instance of our AwesomeView!

Image for post
Image for post

How does this struct work? How is this code connected to the canvas?

Xcode statically discovers types that conform to the PreviewProvider protocol in your app, and generates previews for each provider it discovers.

At the end you can call those structs whatever you want, having it named Whatever_Previews is just a convention provided by Apple to quickly see what this struct is for just conform to PreviewProvider to see the canvas.

Try editing your code on the left and see how the canvas reloads live 😍

4. Define your SwiftUI View as the first View on App launch

So inside SceneDelegate.swift add the following code:

import UIKit
import SwiftUI
@UIApplicationMain
class SceneDelegate: UIResponder, UIWindowSceneDelegate, UIApplicationDelegate {
var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { if let windowScene = scene as? UIWindowScene { // (1)
let window = UIWindow(windowScene: windowScene)
self.window = window
// (2)
let vc = UIHostingController(rootView: AwesomeView())
window.rootViewController = vc
// (3)
window.makeKeyAndVisible()
}

}
}

We will have to (1) instantiate a new UIWindow with the size of our phone screen that we get passed in here as a scene and assign it to the window property. We then (2) instantiate a UIHostingController which is a ViewController but it is capable of holding the new SwiftUI View. Here we pass in an instance of our AwesomeView that we want to have displayed as the first View. Finally, we will (3) make the window key and visible. Basically telling our app that this is our active window.

If you now run your App it will show your AwesomeView in the simulator 🥳

Image for post
Image for post

Question: How does Xcode know that the class SceneDelegate inside SceneDelegate.swift is the class to ask for the initial (root) View that your App should show on launch?

I’m glad you asked Watson! This is defined in the info.plist have a look:

Image for post
Image for post
Inside Application Scene Manifest if you expand it — you’ll find the Delegate Class Name

The best way to understand how something works is to break and then fix it!
Let’s double click that $(PRODUCT_MODULE_NAME).SceneDelegate and rename it to $(PRODUCT_MODULE_NAME).martinlasek and run the app!

It will show you a black screen because the app launches but with no window let alone a View! Let’s go inside SceneDelegate.swift and rename the class to martinlasek as well — like so:

import UIKit
import SwiftUI
@UIApplicationMain
class martinlasek: UIResponder, UIWindowSceneDelegate, UIApplicationDelegate {
var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { window = UIWindow(frame: UIScreen.main.bounds)
let vc = UIHostingController(rootView: AwesomeView())
window?.rootViewController = vc
window?.makeKeyAndVisible()
}
}

Try running the App: it will work again! Because the class name matches!

That’s it! You made it! You successfully implemented the first SwiftUI App 🎉

5. Where to go from here

I am really happy you read my article! If you have any suggestions or improvements of any kind let me know! I’d love to hear from you! 😊

Flawless iOS

🍏 Community around iOS development, mobile design, and…

Martin Lasek

Written by

I'm an always optimistic, open minded and knowledge seeking fullstack developer passionate about UI/UX and changing things for the better :)

Flawless iOS

🍏 Community around iOS development, mobile design, and marketing

Martin Lasek

Written by

I'm an always optimistic, open minded and knowledge seeking fullstack developer passionate about UI/UX and changing things for the better :)

Flawless iOS

🍏 Community around iOS development, mobile design, and marketing

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store