It's time again and I started learning the iOS programming again as SwiftUI looks cool.
I spent couple of weeks going through the swift programming documentation and watched the WWDC videos.
Note: This is an ongoing blog, which I update as I add more features to my TodoApp. Learning
Follow along the
Swift documentation. Try to code along the examples. Just go through the documentation even if you don't understand the whole thing just try to read all the documentation and get yourself aware with the concepts. This is will help later while reading the code of some
open source project.
And.. read the documentation again. This is what I am doing now, this time try to understand and repeat until it becomes muscle memory. this is ongoing process.
SwiftUI
Videos
One of my colleague suggested WWDC videos and watch them in the order.
Blogs
After going through all those videos and tutorials, I have decided to start creating something. So what is first app everyone build, it's Todo app.
Download the Github repo to follow along and try the completed features.
Features
- Create a new Todo
- Context menu to Complete or Delete a Todo
- Show completed tasks
- Add Priority
- Add Date
Upcoming
- Edit
- Persist the data
- Add Notification
- Add Location
- Login functionality
Learnings while doing TodoApp
SF Symbols
There are system image which can be used in the app and easier way to find them is to install the SF Symbols app on your Mac. Here is the link to the SF Symbols.
https://developer.apple.com/design/human-interface-guidelines/sf-symbols/overview/
Use it in the code like
Image(systemName: "checkmark.seal.fill")
Layout
TodoRow has 3 elements in the row. The task description, priority and Due date. So I had the description set to fixed width of 200 to show the description. But it does not feel correct.
So the better option is to use the layoutPriority modifier and set it to 1 for task description to take what ever space it needs and let the rest of the elements trimmed.
Adding a ContextMenu
Adding a context menu is simple as using the contextMenu modifier.
.contextMenu(menuItems: {
TodoContextMenu(todo: todo)
})
that provider takes viewBuilder so we can use a separate view to create those context menu options
HStack{
Button(action: {
self.userData.todos[self.todoIndex].isCompleted.toggle()
}, label: {
HStack{
Text("Complete")
.foregroundColor(.green)
Image(systemName: "checkmark.circle.fill")
.foregroundColor(.green)
}
})
Button(action: {
self.userData.todos.remove(at: self.todoIndex)
}, label: {
HStack{
Text("Delete")
.foregroundColor(.red)
Image(systemName: "trash")
.foregroundColor(.red)
}
})
}
Note: I believe there is a bug in swiftUI and the context menu shows text only in black and ignores the styling.
@Environment
Environment is a wrapper object to provide environment values to the view.
EnvironmentValues has list of environment values you can access.
I have used the Presentation to dismiss the view and go back to the list page.
@Environment(\.presentationMode) var presentationMode
So, after the todo is created successfully, use is navigated back to list page.
.alert(isPresented: self.$saved, content: {
Alert(title: Text("Success"), message: Text("Todo created successfully with \(self.todo.priority.name) and due by \(self.todo.dueDate.ShortDate)"), dismissButton: .cancel(Text("Ok"), action: {
self.presentationMode.wrappedValue.dismiss()
}))
})
Extensions
Existing types can be extended with extensions. I have created a extension ShortDate for Date to provide short date string for display purposes
extension Date {
var ShortDate: String {
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
return dateFormatter.string(from: self)
}
}
this can now be used in the code like other Date properties
Text(todo.dueDate.ShortDate)
Core Data
Alright, now we have the basic structure in place and our code is working with adding and deleting the Todos.Now, need to learn how to persist data. There may be different ways to persist the data and Core
Data is one of them and will try that.
Setting up Core Data Stack
When I created the project I did not choose to add Core data. So, to add core data model to the existing project follow the steps in
documentation.
So first thing we always need to do while get the list of data. That is done using the @FetchRequest and then we need to filter the content of that list. This can be done by passing the NS Predicate to the fetch request.
The repo is updated with using the core data.
CRUD operations with CoreData
Local Notifications
Preparing iOS app for Release
App Icons
No comments:
Post a Comment