ChatGPT is a variant of the GPT (Generative Pre-trained Transformer) language model, which is a tool for generating natural language text.
A new Gold Standard of AI-based language generation to create written content at the speed of thought.
It has been trained on a large dataset by OpenAI which is capable of generating human-like text based on the input it receives.
For example, you could use ChatGPT to generate text for user interfaces, such as button labels or error messages. You could also use ChatGPT to generate code snippets or sample data for testing or other purposes.
However, it is important to keep in mind that ChatGPT is a machine-learning model, so the quality of its output will depend on the quality and relevance of the input it receives.
Therefore, it is important to carefully consider the prompts you provide and to review the generated output to ensure it is accurate and appropriate for your needs.
To use ChatGPT for these purposes, you would simply need to provide it with relevant prompts and then use the generated text as needed in your app development process.
For example, you might input the prompt “Write a short story about a person who discovers a hidden treasure” to get ChatGPT to generate a short story about finding a hidden treasure.
Here are a few tips for using ChatGPT effectively:
Today we’ll create a TODO app by using ChatGPT and we’ll learn how to question ChatGPT for getting proper output from it.
Everything that follows from this point forward is my input prompts, followed by ChatCGP’s responses, complete with sample code.
Let’s start with our first question.
Its answer may not be the same for you as it may vary all the time. Even for me, if I ask the same question within 1–2 minutes, it will give different responses!
Can you create a simple todo app in SwiftUI?
Yes, I can provide an example of a simple to-do app built with SwiftUI. Here is an example of a basic Todo app that allows users to add, remove, and mark tasks as complete:
import SwiftUI
class Todo {
var task: String
var isComplete: Bool
}
struct TodoList: View {
@State var todos: [Todo] = []
var body: some View {
NavigationView {
VStack {
List {
ForEach(todos.indices) { index in
HStack {
Text(self.todos[index].task)
Spacer()
Button(action: {
self.todos[index].isComplete.toggle()
}) {
Image(systemName: self.todos[index].isComplete ? "checkmark.square" : "square")
}
}
}
.onDelete { indexSet in
self.todos.remove(atOffsets: indexSet)
}
}
HStack {
TextField("New task", text: $newTask)
Button(action: {
self.todos.append(Todo(task: self.newTask, isComplete: false))
self.newTask = ""
}) {
Image(systemName: "plus")
}
}
.padding()
}
.navigationBarTitle("Todo")
.navigationBarItems(trailing: EditButton())
}
}
@State private var newTask = ""
}
struct TodoList_Previews: PreviewProvider {
static var previews: some View {
TodoList()
}
}
This example uses a struct called Todo
to represent a task in the app, which contains the task
itself and a isComplete
flag. The TodoList
struct displays the list of todos and a text field for adding new tasks, with a button that appends the new task to the list when tapped.
The list of todos is stored in an array, and the app uses the List
and ForEach
views to display the tasks. Tasks can be marked as complete by tapping on the corresponding button and can be deleted by swiping left and hitting the delete button.
You can also customize the UI to your specific needs and it is just a simple example, it doesn’t include all the functionalities you may need in a complete Todo App.
But I’m not satisfied with this answer as its data class doesn’t have the id field that we need and the created view structure for UI is also not that much clear.
To get an answer with all the requirements we have to ask a more clarified question to ChatGPT with all details, like
Can you design a todo application that includes a data class with an “id” field, and also has a well-organized, view-divided structure?
But as the ChatGPT allows us continuous questioning we can ask it accordingly like,
Can you provide its data class that has an id field and then create a todo app in a proper way that has a view-divided structure?
As given in the above question, it’s not required to mention all the core things in the question each time when we are asking for assistance, we can phrase our questions as if we were speaking to a person.
And it’ll give us a proper answer like this,
Sure! Here’s an example of a Todo
data class that includes an id
field, and a more structured version of the Todo app that separates the views into different structs:
import SwiftUI
class Todo: Identifiable {
var id = UUID()
var task: String
var isComplete: Bool
init(task: String, isComplete: Bool = false) {
self.task = task
self.isComplete = isComplete
}
}
class TodoListViewModel: ObservableObject {
@Published var todos: [Todo]
init(todos: [Todo] = []) {
self.todos = todos
}
func addTodo(task: String) {
todos.append(Todo(task: task))
}
func deleteTodo(at indexSet: IndexSet) {
todos.remove(atOffsets: indexSet)
}
func toggleComplete(id: UUID) {
if let index = todos.firstIndex(where: {$0.id == id}) {
todos[index].isComplete.toggle()
}
}
}
struct TodoListView: View {
@ObservedObject var viewModel: TodoListViewModel = .init()
var body: some View {
NavigationView {
VStack {
List {
ForEach(viewModel.todos) { todo in
TodoRow(todo: .constant(todo), toggleComplete: self.viewModel.toggleComplete)
}
.onDelete { indexSet in
self.viewModel.deleteTodo(at: indexSet)
}
}
TodoTextField(addTodo: self.viewModel.addTodo)
}
.navigationBarTitle("Todo")
.navigationBarItems(trailing: EditButton())
}
}
}
struct TodoRow: View {
@Binding var todo: Todo
var toggleComplete: (UUID) -> Void
var body: some View {
HStack {
Text(todo.task)
Spacer()
Button {
self.toggleComplete(self.todo.id)
} label: {
Image(systemName: todo.isComplete ? "checkmark.square" : "square")
}
}
}
}
struct TodoTextField: View {
var addTodo: (String) -> Void
@State private var newTask = ""
var body: some View {
HStack {
TextField("New task", text: $newTask)
Button {
self.addTodo(self.newTask)
self.newTask = ""
} label: {
Image(systemName: "plus")
}
}
.padding()
}
}
In this version, the Todo
class conforms to the Identifiable
protocol and includes an id
field. The TodoListView
struct displays the list of todos and a text field for adding new tasks. It has a TodoListViewModel
as an observed object, which provides the data and logic for the view.
The TodoListView
uses List
and ForEach
views to display each task. Each task is represented by a TodoRow
struct that is being reused for each to-do in the list.
The TodoTextField
struct contains the text.
Now, based on our understanding, we can separate all the views in different files according to our project architecture needs.
But if we need to test ChatGPT for that then we can also do that by asking,
I want to make this app with MVVM architecture, can you arrange views and class according to that?
If you are not satisfied with the answer even if your question is proper then you can also Regenerate Response
.
If you have used this code and tried to run it, then you may have noticed that the to-do item cell is not able to toggle the value of isCompleted
.
Now let’s try to solve that problem with the help of ChatGPT by asking,
From the given code I’m not able to update the state of `isCompleted` flag, can you help me out to find out the cause of this issue?
And maybe its answer will not help us to fix this issue even if tried with the Regenerate Response
option so many times, because ChatGPT can not be correct all the time.
We can not expect to get 100% correct answers from the ChatGPT prompt, after all, it’s an AI not human in this case our knowledge will help.
Here the problem is we have added the TODO data class as Class
not Struct
. The model class should be added as a struct in any case.
Let’s fix it and try to run.
Now if we want to write a unit test for the ViewModel class then also we can do that easily.
Can you write unit test for it’s viewmodel class?
Sure! Here’s an example of how you might write unit tests for the TodoListViewModel
class using the XCTest framework:
import XCTest
@testable import TodoApp
class TodoListViewModelTests: XCTestCase {
var viewModel: TodoListViewModel!
override func setUp() {
viewModel = TodoListViewModel()
}
override func tearDown() {
viewModel = nil
}
func testAddTodo() {
viewModel.addTodo(task: "Test Todo")
XCTAssertEqual(viewModel.todos.count, 1)
XCTAssertEqual(viewModel.todos.first?.task, "Test Todo")
XCTAssertEqual(viewModel.todos.first?.isComplete, false)
}
func testDeleteTodo() {
viewModel.todos = [Todo(task: "Test Todo 1"), Todo(task: "Test Todo 2")]
viewModel.deleteTodo(at: IndexSet(integer: 0))
XCTAssertEqual(viewModel.todos.count, 1)
XCTAssertEqual(viewModel.todos.first?.task, "Test Todo 2")
}
func testToggleC omplete() {
viewModel.todos = [Todo(task: "Test Todo")]
viewModel.toggleComplete(id: viewModel.todos.first!.id)
XCTAssertEqual(viewModel.todos.first?.isComplete, true)
viewModel.toggleComplete(id: viewModel.todos.first!.id)
XCTAssertEqual(viewModel.todos.first?.isComplete, false)
}
}
Now if you have doubts about any written test then you can confirm or ask for write correct one, like
I don’t think that the deleteTODO function test is correct, can you please write its correct test?
I apologize for any confusion. The test testDeleteTodo()
provided previously was checking the count of elements after removing one element and checking its value.
But the better way to test the deleteTodo(at:)
method is to check if the element you want to delete is really removed from the to-do list, using XCTAssertEqual
or other assertion methods. Here's an example of how you could test the deleteTodo(at:)
function:
func testDeleteTodo() {
let task1 = Todo(task: "Test Todo 1")
let task2 = Todo(task: "Test Todo 2")
viewModel.todos = [task1, task2]
let id = task1.id
viewModel.deleteTodo(at: IndexSet(integer: 0))
XCTAssertEqual(viewModel.todos.count, 1)
XCTAssertNil(viewModel.todos.first(where: { $0.id == id }))
}
It first creates two Todo objects, then adds these objects to the todos array, deletes the first element, and then tests if it’s removed by checking its id is not available in the todo array.
Please let me know if you have any further questions or if there is anything else that I can help you with.
Now, if we are mocking our project dependency using a third-party library and want to write a test using the same, then let’s see how we can do that.
Let’s ask,
Can you mock its dependency using cuckoo and then write a test with that library?
But if you ask like this it will consider the previous question and answer accordingly, like it’ll write a test only for the deleteTodo
method, you can try but for now, I'll ask,
Can you mock the project’s dependency using cuckoo and then write a unit test with that library for the ViewModel?
Sure, here’s an example of how you could write unit tests for the TodoListViewModel
class using Cuckoo :
import XCTest
import Cuckoo
class TodoListViewModelTests: XCTestCase {
var viewModel: TodoListViewModel!
var mockViewModel: MockTodoListViewModel!
override func setUp() {
mockViewModel = MockTodoListViewModel()
viewModel = mockViewModel
}
func testAddTodo() {
let task = "Test Todo"
mockViewModel.stub(mockViewModel.addTodo(task: task))
viewModel.addTodo(task: task)
mockViewModel.verify(mockViewModel.addTodo(task: task), times(1))
}
func testDeleteTodo() {
let indexSet = IndexSet(integer: 0)
mockViewModel.stub(mockViewModel.deleteTodo(at: indexSet))
viewModel.deleteTodo(at: indexSet)
mockViewModel.verify(mockViewModel.deleteTodo(at: indexSet), times(1))
}
func testToggleComplete() {
let id = UUID()
mockViewModel.stub(mockViewModel.toggleComplete(id: id))
viewModel.toggleComplete(id: id)
mockViewModel.verify(mockViewModel.toggleComplete(id: id), times(1))
}
}
Here in each test method, first, you’re stubbing the corresponding method of mockViewModel
and then calling the actual method on viewModel
object and finally you're verifying that the corresponding method on mockViewModel
has been called the expected number of times (1 in this case).
By using this library, you can write the test of ViewModel without its dependency, and also it will increase the speed of your test. If you have any questions or run into any issues, please let me know.
It’s enough if we want to create a single-screen app but what if we want to add a navigation view and add more than 1 screen?
Let’s explore that with GPT,
Make sure to ask questions with enough detail so that ChatGPT can give a proper answer.
Can you design the to-do task detail screen that has all the detail related to the task and that can be opened with the click of the task cell from the home screen?
Sure! Here’s an example of how you could design a TodoTaskDetailView
that displays all the details of a Todo
task and can be opened with the click of a task cell on the home screen:
struct TodoTaskDetailView: View {
@ObservedObject var todo: Todo
var body: some View {
VStack {
Text(todo.task)
Spacer()
HStack {
if todo.isComplete {
Text("Completed")
.foregroundColor(.green)
} else {
Text("Incomplete")
.foregroundColor(.red)
}
Spacer()
}
}
.padding()
.navigationBarTitle("Task Detail")
}
}
You can open this TodoTaskDetailView
by implementing NavigationLink
inside the ForEach
loop of the home screen's List
view. The NavigationLink
will be used to navigate to this detail screen and will pass the selected Todo
object through the todo
property.
struct TodoListView: View {
@ObservedObject var viewModel: TodoListViewModel = .init()
var body: some View {
NavigationView {
List {
ForEach(viewModel.todos) { todo in
NavigationLink(destination: TodoTaskDetailView(todo: todo)) {
TodoRow(todo: .constant(todo), toggleComplete: self.viewModel.toggleComplete)
}
}
.onDelete { indexSet in
self.viewModel.deleteTodo(at: indexSet)
}
}
.navigationBarTitle("Todo")
.navigationBarItems(trailing: EditButton())
}
}
}
You can also use Button
or onTapGesture
instead of NavigationLink
if you want to present the detail view modally instead of pushing it onto a navigation stack. Please let me know if you have any questions or if you need further assistance.
That’s it for now as a start-up app. You can explore ChatGPT by questioning in multiple ways.
It’s just about how to ask someone to get proper information or an answer same as the PQA (Precision Questions & Answers).
Hope it’ll help you get basic insights and the usage of ChatGPT.
Have fun with ChatGPT!!!
Keep Chatting… ⌨️🤖
Revolutionizing the way we interact with machines, bringing us one step closer to creating truly intelligent, human-like AI
Sometimes it’s possible with ChatGPT that it may give different answers if we ask for the same question many times, So you can try that too by trying with the same or different questions until you get your expected output.
ChatGPT is a powerful and versatile tool that can be used for a wide range of applications.
Don’t be afraid to experiment and have fun with it — you never know what exciting and creative ideas you might come up with!
Get started today
Let's build the next
big thing!
Let's improve your business's digital strategy and implement robust mobile apps to achieve your business objectives. Schedule Your Free Consultation Now.
Get Free ConsultationGet started today
Let's build the next big thing!
Let's improve your business's digital strategy and implement robust mobile apps to achieve your business objectives. Schedule Your Free Consultation Now.
Get Free Consultation