Skip to content

Commit d86beca

Browse files
committed
👌🏻Some refactorings and renamings following code review
- changed userName to username - extracted view model into separate file
1 parent b1890db commit d86beca

File tree

3 files changed

+90
-48
lines changed

3 files changed

+90
-48
lines changed

SwiftUI-Combine.xcodeproj/project.pbxproj

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 50;
6+
objectVersion = 51;
77
objects = {
88

99
/* Begin PBXBuildFile section */
@@ -14,6 +14,7 @@
1414
882C7EB3231D7AE000B9AFC5 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 882C7EB2231D7AE000B9AFC5 /* Preview Assets.xcassets */; };
1515
882C7EB6231D7AE000B9AFC5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 882C7EB4231D7AE000B9AFC5 /* LaunchScreen.storyboard */; };
1616
882C7EC1231D7AE100B9AFC5 /* SwiftUI_CombineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 882C7EC0231D7AE100B9AFC5 /* SwiftUI_CombineTests.swift */; };
17+
88AC600223294399007E504C /* UserViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88AC600123294399007E504C /* UserViewModel.swift */; };
1718
F4EAB782D9A69D55169AA082 /* Pods_SwiftUI_CombineTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAED7B4B2E771F456C8D9A44 /* Pods_SwiftUI_CombineTests.framework */; };
1819
FA4B1DD302AA565FF9C19D95 /* Pods_SwiftUI_Combine.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 10ACBDCE50933F4EC1241D62 /* Pods_SwiftUI_Combine.framework */; };
1920
/* End PBXBuildFile section */
@@ -42,6 +43,7 @@
4243
882C7EBC231D7AE100B9AFC5 /* SwiftUI-CombineTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwiftUI-CombineTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
4344
882C7EC0231D7AE100B9AFC5 /* SwiftUI_CombineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUI_CombineTests.swift; sourceTree = "<group>"; };
4445
882C7EC2231D7AE100B9AFC5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
46+
88AC600123294399007E504C /* UserViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserViewModel.swift; sourceTree = "<group>"; };
4547
90842E7EA5DF6F7316755E72 /* Pods-SwiftUI-Combine.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftUI-Combine.debug.xcconfig"; path = "Target Support Files/Pods-SwiftUI-Combine/Pods-SwiftUI-Combine.debug.xcconfig"; sourceTree = "<group>"; };
4648
A874CED7A50631579A1CC107 /* Pods-SwiftUI-CombineTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftUI-CombineTests.debug.xcconfig"; path = "Target Support Files/Pods-SwiftUI-CombineTests/Pods-SwiftUI-CombineTests.debug.xcconfig"; sourceTree = "<group>"; };
4749
E12A138418FFFE624CC418C6 /* Pods-SwiftUI-CombineTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftUI-CombineTests.release.xcconfig"; path = "Target Support Files/Pods-SwiftUI-CombineTests/Pods-SwiftUI-CombineTests.release.xcconfig"; sourceTree = "<group>"; };
@@ -85,7 +87,6 @@
8587
A874CED7A50631579A1CC107 /* Pods-SwiftUI-CombineTests.debug.xcconfig */,
8688
E12A138418FFFE624CC418C6 /* Pods-SwiftUI-CombineTests.release.xcconfig */,
8789
);
88-
name = Pods;
8990
path = Pods;
9091
sourceTree = "<group>";
9192
};
@@ -112,9 +113,10 @@
112113
882C7EA8231D7ADF00B9AFC5 /* SwiftUI-Combine */ = {
113114
isa = PBXGroup;
114115
children = (
116+
88AC5FFF23294361007E504C /* ViewModels */,
117+
88AC60002329436F007E504C /* Views */,
115118
882C7EA9231D7ADF00B9AFC5 /* AppDelegate.swift */,
116119
882C7EAB231D7ADF00B9AFC5 /* SceneDelegate.swift */,
117-
882C7EAD231D7ADF00B9AFC5 /* ContentView.swift */,
118120
882C7EAF231D7AE000B9AFC5 /* Assets.xcassets */,
119121
882C7EB4231D7AE000B9AFC5 /* LaunchScreen.storyboard */,
120122
882C7EB7231D7AE000B9AFC5 /* Info.plist */,
@@ -140,6 +142,22 @@
140142
path = "SwiftUI-CombineTests";
141143
sourceTree = "<group>";
142144
};
145+
88AC5FFF23294361007E504C /* ViewModels */ = {
146+
isa = PBXGroup;
147+
children = (
148+
88AC600123294399007E504C /* UserViewModel.swift */,
149+
);
150+
path = ViewModels;
151+
sourceTree = "<group>";
152+
};
153+
88AC60002329436F007E504C /* Views */ = {
154+
isa = PBXGroup;
155+
children = (
156+
882C7EAD231D7ADF00B9AFC5 /* ContentView.swift */,
157+
);
158+
path = Views;
159+
sourceTree = "<group>";
160+
};
143161
/* End PBXGroup section */
144162

145163
/* Begin PBXNativeTarget section */
@@ -309,6 +327,7 @@
309327
buildActionMask = 2147483647;
310328
files = (
311329
882C7EAA231D7ADF00B9AFC5 /* AppDelegate.swift in Sources */,
330+
88AC600223294399007E504C /* UserViewModel.swift in Sources */,
312331
882C7EAC231D7ADF00B9AFC5 /* SceneDelegate.swift in Sources */,
313332
882C7EAE231D7ADF00B9AFC5 /* ContentView.swift in Sources */,
314333
);

SwiftUI-Combine/ContentView.swift renamed to SwiftUI-Combine/ViewModels/UserViewModel.swift

Lines changed: 16 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
//
2-
// ContentView.swift
2+
// UserViewModel.swift
33
// SwiftUI-Combine
44
//
5-
// Created by Peter Friese on 02/09/2019.
5+
// Created by Peter Friese on 11/09/2019.
66
// Copyright © 2019 Google LLC. All rights reserved.
77
//
88

9-
import SwiftUI
9+
import Foundation
1010
import Combine
1111
import Navajo_Swift
1212

13-
class UserModel: ObservableObject {
13+
class UserViewModel: ObservableObject {
1414
// input
15-
@Published var userName = ""
15+
@Published var username = ""
1616
@Published var password = ""
1717
@Published var passwordAgain = ""
1818

1919
// output
20-
@Published var userNameMessage = ""
20+
@Published var usernameMessage = ""
2121
@Published var passwordMessage = ""
22-
@Published var valid = false
22+
@Published var isValid = false
2323

2424
private var cancellableSet: Set<AnyCancellable> = []
2525

26-
private var isUserNameValidPublisher: AnyPublisher<Bool, Never> {
27-
$userName
26+
private var isUsernameValidPublisher: AnyPublisher<Bool, Never> {
27+
$username
2828
.debounce(for: 0.8, scheduler: RunLoop.main)
2929
.removeDuplicates()
3030
.map { input in
@@ -43,7 +43,7 @@ class UserModel: ObservableObject {
4343
.eraseToAnyPublisher()
4444
}
4545

46-
private var isPasswordsEqualPublisher: AnyPublisher<Bool, Never> {
46+
private var arePasswordsEqualPublisher: AnyPublisher<Bool, Never> {
4747
Publishers.CombineLatest($password, $passwordAgain)
4848
.debounce(for: 0.2, scheduler: RunLoop.main)
4949
.map { password, passwordAgain in
@@ -84,7 +84,7 @@ class UserModel: ObservableObject {
8484
}
8585

8686
private var isPasswordValidPublisher: AnyPublisher<PasswordCheck, Never> {
87-
Publishers.CombineLatest3(isPasswordEmptyPublisher, isPasswordsEqualPublisher, isPasswordStrongEnoughPublisher)
87+
Publishers.CombineLatest3(isPasswordEmptyPublisher, arePasswordsEqualPublisher, isPasswordStrongEnoughPublisher)
8888
.map { passwordIsEmpty, passwordsAreEqual, passwordIsStrongEnough in
8989
if (passwordIsEmpty) {
9090
return .empty
@@ -103,20 +103,20 @@ class UserModel: ObservableObject {
103103
}
104104

105105
private var isFormValidPublisher: AnyPublisher<Bool, Never> {
106-
Publishers.CombineLatest(isUserNameValidPublisher, isPasswordValidPublisher)
106+
Publishers.CombineLatest(isUsernameValidPublisher, isPasswordValidPublisher)
107107
.map { userNameIsValid, passwordIsValid in
108108
return userNameIsValid && (passwordIsValid == .valid)
109109
}
110110
.eraseToAnyPublisher()
111111
}
112112

113113
init() {
114-
isUserNameValidPublisher
114+
isUsernameValidPublisher
115115
.receive(on: RunLoop.main)
116116
.map { valid in
117-
valid ? "" : "User name must at leat have 3 characters"
117+
valid ? "" : "User name must at least have 3 characters"
118118
}
119-
.assign(to: \.userNameMessage, on: self)
119+
.assign(to: \.usernameMessage, on: self)
120120
.store(in: &cancellableSet)
121121

122122
isPasswordValidPublisher
@@ -138,37 +138,8 @@ class UserModel: ObservableObject {
138138

139139
isFormValidPublisher
140140
.receive(on: RunLoop.main)
141-
.assign(to: \.valid, on: self)
141+
.assign(to: \.isValid, on: self)
142142
.store(in: &cancellableSet)
143143
}
144144

145145
}
146-
147-
struct ContentView: View {
148-
149-
@ObservedObject private var userModel = UserModel()
150-
151-
var body: some View {
152-
Form {
153-
Section(footer: Text(userModel.userNameMessage).foregroundColor(.red)) {
154-
TextField("Username", text: $userModel.userName)
155-
.autocapitalization(.none)
156-
}
157-
Section(footer: Text(userModel.passwordMessage).foregroundColor(.red)) {
158-
SecureField("Password", text: $userModel.password)
159-
SecureField("Password again", text: $userModel.passwordAgain)
160-
}
161-
Section {
162-
Button(action: { }) {
163-
Text("Sign up")
164-
}.disabled(!self.userModel.valid)
165-
}
166-
}
167-
}
168-
}
169-
170-
struct ContentView_Previews: PreviewProvider {
171-
static var previews: some View {
172-
ContentView()
173-
}
174-
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//
2+
// ContentView.swift
3+
// SwiftUI-Combine
4+
//
5+
// Created by Peter Friese on 02/09/2019.
6+
// Copyright © 2019 Google LLC. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
11+
struct ContentView: View {
12+
13+
@ObservedObject private var userViewModel = UserViewModel()
14+
@State var presentAlert = false
15+
16+
var body: some View {
17+
Form {
18+
Section(footer: Text(userViewModel.usernameMessage).foregroundColor(.red)) {
19+
TextField("Username", text: $userViewModel.username)
20+
.autocapitalization(.none)
21+
}
22+
Section(footer: Text(userViewModel.passwordMessage).foregroundColor(.red)) {
23+
SecureField("Password", text: $userViewModel.password)
24+
SecureField("Password again", text: $userViewModel.passwordAgain)
25+
}
26+
Section {
27+
Button(action: { self.signUp() }) {
28+
Text("Sign up")
29+
}.disabled(!self.userViewModel.isValid)
30+
}
31+
}
32+
.sheet(isPresented: $presentAlert) {
33+
WelcomeView()
34+
}
35+
}
36+
37+
func signUp() {
38+
self.presentAlert = true
39+
}
40+
}
41+
42+
struct WelcomeView: View {
43+
var body: some View {
44+
Text("Welcome! Great to have you on board!")
45+
}
46+
}
47+
48+
struct ContentView_Previews: PreviewProvider {
49+
static var previews: some View {
50+
ContentView()
51+
}
52+
}

0 commit comments

Comments
 (0)