Skip to content

Commit 4414f11

Browse files
Abizerndaniellevass
authored andcommitted
Cookie Clicker in SwiftUI (#23)
* Start SwiftUI tutorial with Creating an Xcode Project * Add suggestion to try running the preview * Add gif * Add a Button below the label, with gif * Use the button to toggle the label's string * Clean up Xcode chaff * Gif for working counter * Get the functionality working * Change the font of the label with gif * Final spacing and image * Final corrections and the summary * Remove suggested task relating to Autolayout * Link to the new tutorial using index and sidebars * Minor corrections to the wording * Use `if/let` instead of a ternary operator * Add an extension task to disable the button * Add more explanation around State variables
1 parent 2f40c1f commit 4414f11

File tree

14 files changed

+1957
-1624
lines changed

14 files changed

+1957
-1624
lines changed
97.4 KB
Loading
47.7 KB
Loading
58.2 KB
Loading
3.66 MB
Loading
5.54 MB
Loading
Loading
2.83 MB
Loading
42.3 KB
Loading

src/docs/cookie-clicker-storyboard.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
---
2-
title: iOS Clicker Worksheet
2+
title: Cookie Clicker with Storyboards
33
---
44

55
This tutorial is an intro to the world of iOS development, and will help you build your first iOS app.
66

7-
We'll be building a counter app, where the user will press a button and increment the number on the screen.
7+
We'll be building a cookie clicker app, where the user will tap a cookie and increment the number of times they've tapped.
88

99
## Pre-requisites
1010

src/docs/cookie-clicker-swiftui.md

+343
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,343 @@
1+
---
2+
title: Cookie Clicker with SwiftUI
3+
---
4+
5+
This tutorial is an introduction to the world of iOS development using Apple's latest UI framework: [SwiftUI](https://developer.apple.com/xcode/swiftui/)
6+
7+
We'll be building a counter app, where the user will press a button and increment the number on the screen.
8+
9+
## Pre-requisites
10+
11+
In order to work through this tutorial, you will need a Mac with Xcode 11 installed. Xcode 11 is the minimum version that supports SwiftUI. It is useful to have Mac OSX Catalina installed to see live previews in Xcode, but you can still use Mac OS X Mojave.
12+
13+
Download and install Xcode from the App Store. This may take a while — its a big program. If you are at a Codebar ask the coaches before downloading it from the App Store as they frequently have a copy on a USB drive which will save some installation time, but it would be better if you come to the workshop with it installed.
14+
15+
## Creating a Project
16+
17+
### 1. Open Xcode and click Create a new Xcode project
18+
19+
![step1](assets/cookie_clicker_swiftui/step1.png)
20+
21+
### 2. Select Single View Application from the **iOS > Application list**, and click **Next**
22+
23+
![step2](assets/cookie_clicker_swiftui/step2.png)
24+
25+
### 3. Fill in the project details:
26+
27+
- Product Name: Clicker
28+
- Team: None
29+
- Organization Name: Whatever you want — your name is always a good fill-in
30+
- Organization Identifier: com.(OrganizationName)
31+
32+
Make sure Swift is selected as the language.
33+
34+
Make sure SwiftUI is selected as the User Interface.
35+
36+
Make sure the three boxes at the bottom are unchecked, we won't be using those options in this tutorial.
37+
38+
Click Next
39+
40+
![step3](assets/cookie_clicker_swiftui/step3.png)
41+
42+
### 4. Select a sensible place to save your project, then hit **Create**.
43+
44+
Take some time to look around the project that's been created with your coach. What files are there? How do you run your app?
45+
46+
If you are running on Mac OS X Catalina, try running the preview to see what the default project provides.
47+
48+
If this is your first time running Xcode, then this may take a few minutes. This is normal, the next time you run the preview it will be much faster.
49+
50+
## Add a Button
51+
52+
### 5. Open up the **Navigation Area** in Xcode, and then the `ContentView.swift` file and its associated Canvas.
53+
54+
![step4](assets/cookie_clicker_swiftui/step4.gif)
55+
56+
If you click on the `Resume` button in the top right, and you are running on Mac OS X Catalina you will see a preview of the **Hello World** application that the template has provided for you.
57+
58+
### 6. Edit the Canvas and add a Button
59+
60+
When using SwiftUI the Canvas provides a live view of your code. Editing the Canvas will also update your code! We shall be adding code from the Editor a little later on, but for now just add a button to the canvas.
61+
62+
- Open the Library
63+
- Make sure you are browsing the Views
64+
- Search for Button
65+
- Drag the button under the label
66+
67+
### ![step5](assets/cookie_clicker_swiftui/step5.gif)
68+
69+
If you look at the Editor, you can see that this has created a `VStack` with both the label and the button. A `VStack` is a built in view that arranges the contained views vertically.
70+
71+
### 7. Run the app on the Simulator or the canvas.
72+
73+
You can either run the app in the simulator or use the live preview in the Canvas to see the visual effect of pressing the button.
74+
75+
Celebrate appropriately!
76+
77+
Try changing the `VStack` to an `HStack` Are the results what you expect?
78+
79+
A `HStack` is a view that arranges its contained views horizontally.
80+
81+
However, it would be even more awesome if our button actually did something.
82+
83+
## Make the Button do something
84+
85+
To do this we are going to need some state in our view.
86+
87+
### 8. Create some state for the view
88+
89+
Create a state variable at the top of the definition of `ContentView`. We make it `private` because it is internal to the view, and we give it a default value of `false` which implicitly makes `showGreeting` a variable that holds a `Bool` (Now is the time to ask your Coach questions).
90+
91+
```swift
92+
struct ContentView: View {
93+
@State private var showGreeting = false
94+
95+
var body: some View {
96+
<...>
97+
```
98+
99+
We are going to use this to configure what is displayed on the screen.
100+
101+
### 9. Configure the view to display according to the state
102+
103+
Change the string that is displayed in the `Text` view depending on this state:
104+
105+
```swift
106+
if showGreeting {
107+
Text("Hello World")
108+
} else {
109+
Text("")
110+
}
111+
```
112+
113+
When `showGreeting` is `true` the label will display the greeting, otherwise it will be empty.
114+
115+
### 10. Use the Button's action to change the state
116+
117+
When you dragged the button onto the canvas it created an empty `action` This is a closure, and when the button is tapped it will perform whatever code is written in this closure. We are going to use this to toggle the `showGreeting` state.
118+
119+
Edit the Button code look like this:
120+
121+
```swift
122+
Button(action: { self.showGreeting.toggle() })
123+
```
124+
125+
The `ContentView.swift` file should now look like this:
126+
127+
```swift
128+
import SwiftUI
129+
130+
struct ContentView: View {
131+
@State private var showGreeting = false
132+
133+
var body: some View {
134+
VStack {
135+
if showGreeting {
136+
Text("Hello World")
137+
} else {
138+
Text("")
139+
}
140+
Button(action: {self.showGreeting.toggle()}) {
141+
Text("Button")
142+
}
143+
}
144+
}
145+
}
146+
147+
struct ContentView_Previews: PreviewProvider {
148+
static var previews: some View {
149+
ContentView()
150+
}
151+
}
152+
```
153+
154+
### Interlude: What is @State?
155+
156+
SwiftUI is a _declarative_ framework. That means that you write the view to show different things according to its state, and actions change the state, and let the framework handle redrawing the views when these change. If you have done any iOS programming with UIKit before this will be very different. We don't update properties and tell the view to redraw; we just update the properties.
157+
158+
We can use normal constants and variables in SwiftUI, but when we use `@State` variables we are telling the framework that these are the values that the view depends on. SwiftUI keeps track of these internally, and when they change the view is redrawn.
159+
160+
161+
### 11. Run the app in the Simulator or by using the Canvas's live preview feature
162+
163+
As you tap the button, the greeting appears and disappears!
164+
165+
/giphy Celebrate
166+
167+
168+
This is not trivial. You have learned an important part of developing using SwiftUI. You create state, you write your view to respond to the state, and you have actions that change the state. The framework takes care of redrawing the view when the state changes.
169+
170+
If you have done any iOS development before, or even the other CodeBar tutorial, you can see how little code is needed. There are no `ViewController`s. There are no `Storyboards`. You write code and see the results immediately.
171+
172+
173+
## Make the Counter
174+
175+
There are two major tasks for making the counter app. Firstly, _the functionality_ - getting the counter to increment on button clicks and showing the new number. Secondly _the UI_, getting an app that looks nice and is easy to use. This tutorial will create the functionality first and then move on to the UI. You may choose to tackle the tasks in the alternate order. Have a brief discussion with your Coach about the pros and cons of each approach.
176+
177+
### 12. Create the Counter functionality
178+
179+
We are a good way towards this, we already have a `Button` with an action, and a `Text` view that displays something.
180+
181+
Change the state variable to hold a number instead of a `Bool`
182+
183+
```swift
184+
@State private var count = 0
185+
```
186+
187+
Since the state is variable is now a number and not a string, change the `Text` view to display this:
188+
189+
```swift
190+
Text("\(count)")
191+
```
192+
193+
Finally change the `Button`'s action to increment this variable
194+
195+
```swift
196+
Button(action: { self.count += 1 })
197+
```
198+
199+
The entire file should now look like this
200+
201+
```swift
202+
import SwiftUI
203+
204+
struct ContentView: View {
205+
@State private var count = 0
206+
207+
var body: some View {
208+
VStack {
209+
Text("\(count)")
210+
Button(action: { self.count += 1 }) {
211+
Text("Button")
212+
}
213+
}
214+
}
215+
}
216+
217+
struct ContentView_Previews: PreviewProvider {
218+
static var previews: some View {
219+
ContentView()
220+
}
221+
}
222+
```
223+
224+
### 13. Run the app in the Simulator on the Canvas live preview to see the counter working
225+
226+
![step6](assets/cookie_clicker_swiftui/step6.gif)
227+
228+
229+
## Make it look better
230+
231+
Having the button and the label so close together isn't the nicest looking UI. Nor is it the easiest to use. And the text for the counter seems a little small. Let's fix these things
232+
233+
### 14. Increase the size of the numbers
234+
235+
In the canvas Cmd + Click on the `Text` view, this brings up an inspector.
236+
237+
Select the `show SwiftUI Inspector...` option.
238+
239+
Choose `Large Title` for the font.
240+
241+
![step7](assets/cookie_clicker_swiftui/step7.gif)
242+
243+
Notice that in the editor, the modifier has been added to the `Text` view that matches this choice.
244+
245+
Working with your coach, try to apply other sizes and styles to this `Text` view.
246+
247+
### 15. Add some spacing
248+
249+
Let's add some separation between the elements. `VStack`s are quite helpful in laying items out. All that needs to be done is for some spacers to be added between the elements and the it will handle layout.
250+
251+
Add a `Spacer()` above and below the `Text` view. The entire file should now look like this:
252+
253+
```swift
254+
import SwiftUI
255+
256+
struct ContentView: View {
257+
@State private var count = 0
258+
259+
var body: some View {
260+
VStack {
261+
Spacer()
262+
Text("\(count)")
263+
.font(.largeTitle)
264+
Spacer()
265+
Button(action: { self.count += 1 }) {
266+
Text("Button")
267+
}
268+
}
269+
}
270+
}
271+
272+
struct ContentView_Previews: PreviewProvider {
273+
static var previews: some View {
274+
ContentView()
275+
}
276+
}
277+
```
278+
279+
And the Canvas shows the result:
280+
281+
![step8](assets/cookie_clicker_swiftui/step8.png)
282+
283+
## Summary
284+
285+
Congratulations! You've just created your first SwiftUI iOS app. You've learned how to move around Xcode and edit your code. You've added UI elements from the library and configured them. You've seen how to use previews, live previews, and the simulator. You've seen how SwiftUI is declarative. This is a good start!
286+
287+
## Bonus : Run your app on your Apple device
288+
289+
Running your app in the simulator is cool, but you know what's even cooler? Running your app in your Apple devices! Couple years back, you need to have a developer account to run your app in a physical device, but luckily know Apple allows us to run our app using your everyday Apple account.
290+
291+
### Pre-requisites
292+
293+
- 📱 Apple device (the more recent device the better) + cable
294+
- An Apple account
295+
296+
### A. Add your account in Xcode
297+
298+
- From the menubar, go to `Xcode > Preferences...`
299+
- Click the `Accounts` tab (the second tab)
300+
- On bottom left, press the + icon
301+
- Select `Add Apple ID...`
302+
- Insert your Apple ID's credentials
303+
304+
![add_apple_id](assets/cookie_clicker_storyboard/bonus_step1.png)
305+
306+
### B. Configure your project's signing
307+
308+
- Go to `Navigator` area, select `Project navigator` tab, select your project name
309+
- Select your app target in the `Targets` tab
310+
- In the `Signing` area, select your account as the team name
311+
312+
![select_team](assets/cookie_clicker_storyboard/bonus_step2.png "Select team")
313+
314+
### C. Configure your device 📱
315+
316+
- Plug your Apple device to your development machine (this will trigger Xcode to [processes symbol files from your devices](http://stackoverflow.com/a/19706886/851515), which will take a sometime)
317+
- Instead of running on simulator, select your device instead
318+
![select device](assets/cookie_clicker_storyboard/bonus_step3a.png "Select your apple device")
319+
- Press the play button to run the app!
320+
- Errm... not so fast. We need to allow codesign to access our keychain, press `Always Allow`
321+
![allow keychain](assets/cookie_clicker_storyboard/bonus_step3b.png "Allow codesign to access keychain")
322+
- Almost there, you will be prompted to verify your account in your device
323+
![verify alert](assets/cookie_clicker_storyboard/bonus_step3c.png "Verify account developer")
324+
- Now on your iOS device, go to `Settings` > `General` > `Profiles & Device Management`, tap your account under `Developer App`, tap `Trust '<your apple account email>'`, and confirm by tapping `Trust` again
325+
![verify account](assets/cookie_clicker_storyboard/bonus_step3d.png "Verify account in your device")
326+
- Back at Xcode, press play button to build and run again
327+
- 🎉
328+
329+
It's great to see that Apple makes it easy for us to try our app in our actual hands. Happy testing!
330+
331+
------
332+
333+
## Extension Tasks
334+
335+
If you've finished all of the above why not think about some of the following ideas:
336+
337+
* Disable the button when the counter reaches, say, 10. so the number can't get larger.
338+
339+
* make a new button that decreases the count. Can you turn it into a two player game?
340+
341+
* make the background change after a set amount of clicks? How about creating an array of colours to change every set interval e.g. after 5 taps.
342+
343+
* change your button into a picture button, you could make a cookie clicker? Make the picture change after a set amount of clicks.

src/website/i18n/en.json

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
"cookie-clicker-storyboard": {
1212
"title": "iOS Clicker Worksheet"
1313
},
14+
"cookie-clicker-swiftui": {
15+
"title": "Cookie Clicker with SwiftUI"
16+
},
1417
"intro": {
1518
"title": "Getting set up for iOS development"
1619
},

0 commit comments

Comments
 (0)