DEV Community

Cover image for SwiftUI & ChatGPT. The world is changing. Again.
Sergey Leschev
Sergey Leschev

Posted on • Updated on

SwiftUI & ChatGPT. The world is changing. Again.

Fast app prototyping with SwiftUI & ChatGPT

Everything that follows from this point forward is my input prompts, followed by ChatCGP’s responses, complete with sample code in Swift.

Hey ChatGPT, can you make a SwiftUI registration form with name, address and city fields?

import SwiftUI

struct RegistrationForm: View {
    @State private var name: String = ""
    @State private var address: String = ""
    @State private var city: String = ""

    var body: some View {
        Form {
            TextField("Name", text: $name)
            TextField("Address", text: $address)
            TextField("City", text: $city)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

The RegistrationForm struct conforms to the View protocol and defines a body property that returns a Form view. The Form view contains TextField views for each of the form fields, and the @State property wrapper is used to manage the state of each field.

Can you move the fields to a view model?

Move the form fields to a separate view model in order to better manage the state and logic of the form.

import SwiftUI

struct RegistrationForm: View {
    @ObservedObject var viewModel: RegistrationFormViewModel

    var body: some View {
        Form {
            TextField("Name", text: $viewModel.name)
            TextField("Address", text: $viewModel.address)
            TextField("City", text: $viewModel.city)
        }
    }
}

class RegistrationFormViewModel: ObservableObject {
    @Published var name: String = ""
    @Published var address: String = ""
    @Published var city: String = ""
}
Enter fullscreen mode Exit fullscreen mode

The RegistrationForm struct has an @ObservedObject property that references an instance of the RegistrationFormViewModel class. This allows the RegistrationForm view to bind to the properties of the view model using the $ prefix, just as it did with the @State properties in the previous example.

The RegistrationFormViewModel class defines @Published properties for each of the form fields, which allows the view to be notified when the values of these properties change. This allows the view to update automatically when the user changes the form fields.

This approach helps to keep the view logic and state management separate from the view itself, making the code easier to understand and maintain.

What if I need to validate that none of the fields are empty?

If you need to validate that none of the fields in the form are empty, you can add a method to the RegistrationFormViewModel class that checks the values of the form fields and returns a Bool indicating whether the form is valid or not.

class RegistrationFormViewModel: ObservableObject {
    @Published var name: String = ""
    @Published var address: String = ""
    @Published var city: String = ""

    var isValid: Bool {
        return !name.isEmpty && !address.isEmpty && !city.isEmpty
    }
}
Enter fullscreen mode Exit fullscreen mode

The isValid property uses the isEmpty property of each of the form fields to determine whether the form is valid or not. If all of the fields are not empty, the isValid property will return true, otherwise it will return false.

You can then use this property in the view to enable or disable a submit button or to display an error message if the form is not valid.

struct RegistrationForm: View {
    @ObservedObject var viewModel: RegistrationFormViewModel

    var body: some View {
        Form {
            TextField("Name", text: $viewModel.name)
            TextField("Address", text: $viewModel.address)
            TextField("City", text: $viewModel.city)

            if !viewModel.isValid {
                Text("All fields are required")
                    .foregroundColor(.red)
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

The RegistrationForm view checks the value of the isValid property and, if the form is not valid, it displays an error message using a Text view. This allows the user to know which fields need to be filled out in order to make the form valid.

Can we add a Save button to that form?

Add a Save button to the form by using a Button view in the RegistrationForm struct.

struct RegistrationForm: View {
    @ObservedObject var viewModel: RegistrationFormViewModel

    var body: some View {
        Form {
            TextField("Name", text: $viewModel.name)
            TextField("Address", text: $viewModel.address)
            TextField("City", text: $viewModel.city)

            if !viewModel.isValid {
                Text("All fields are required")
                    .foregroundColor(.red)
            }

            Button(action: {
                // Save the form data here
            }) {
                Text("Save")
            }
            .disabled(!viewModel.isValid)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

The RegistrationForm view includes a Button view with an action closure that is called when the button is tapped. This closure can be used to save the form data to a database or other storage location.

The Button view also has a disabled modifier that disables the button if the isValid property of the RegistrationFormViewModel is false. This ensures that the form must be filled out correctly before the user can save the data.

Can you create a User struct based on the form information?

A User struct that could be used to represent the data from the form:

struct User {
    var name: String
    var address: String
    var city: String
}
Enter fullscreen mode Exit fullscreen mode

This User struct defines properties for each of the form fields, such as name, address and city. These properties can be used to store the values entered by the user in the form.

Create an instance of the User struct using the values from the form:

let user = User(
    name: viewModel.name,
    address: viewModel.address,
    city: viewModel.city
)
Enter fullscreen mode Exit fullscreen mode

The user constant is initialized with the values from the RegistrationFormViewModel instance. You can then use this User instance to save the data to a database or other storage location, or to pass the data to another part of your app for further processing.

And how do I populate the fields on the view model from the struct?

class RegistrationFormViewModel: ObservableObject {
    @Published var name: String = ""
    @Published var address: String = ""
    @Published var city: String = ""

    var isValid: Bool {
        return !name.isEmpty && !address.isEmpty && !city.isEmpty
    }

    func populate(with user: User) {
        name = user.name
        address = user.address
        city = user.city
    }
}
Enter fullscreen mode Exit fullscreen mode

Use this method to populate the form fields:

let user = User(
    name: "Oliver Doe",
    address: "100 Main St",
    city: "Anytown"
)

viewModel.populate(with: user)
Enter fullscreen mode Exit fullscreen mode

The user constant is initialized with some sample data, and then the populate(with:) method is called on the viewModel instance, passing in the user instance as a parameter. This will set the values of the view model's properties to match the values of the User instance, which will in turn populate the form fields with the data from the User instance.


Contacts
I have a clear focus on time-to-market and don't prioritize technical debt. And I took part in the Pre-Sale/RFX activity as a System Architect, assessment efforts for Mobile (iOS-Swift, Android-Kotlin), Frontend (React-TypeScript) and Backend (NodeJS-.NET-PHP-Kafka-SQL-NoSQL). And I also formed the work of Pre-Sale as a CTO from Opportunity to Proposal via knowledge transfer to Successful Delivery.

πŸ›©οΈ #startups #management #cto #swift #typescript #database
πŸ“§ Email: sergey.leschev@gmail.com
πŸ‘‹ LinkedIn: https://linkedin.com/in/sergeyleschev/
πŸ‘‹ LeetCode: https://leetcode.com/sergeyleschev/
πŸ‘‹ Twitter: https://twitter.com/sergeyleschev
πŸ‘‹ Github: https://github.com/sergeyleschev
🌎 Website: https://sergeyleschev.github.io
🌎 Reddit: https://reddit.com/user/sergeyleschev
🌎 Quora: https://quora.com/sergey-leschev
🌎 Medium: https://medium.com/@sergeyleschev

Top comments (0)