Creating a simple note taking app for iOS in Swift
This article describes details of a simple note taking app I created in Swift for iOS.
The final product
Here is a short summary about the final app I built. With the app it is possible to:
- Display and create notes
- Edit notes
- Delete notes
The app will store for each note:
- The title of the note
- The creation or last change date and time of the note
- The text of the note
The new note will only be created if the note title and note text are filled. The date and time stored for the note is updated with the current date and time, when the note is edited.
The app uses UIKit, and integrates with Core Data. As a starting point the Master-detail app template is used.
Display and create notes
The app start with a screen showing the list of notes.
Displaying a note shows a screen where the note title, creation / last edited date and time, and the note text are shown.
The creation of new notes is done from the note list screen using the + button. The OK button on the create screen is only active when both the description and the text of the note are filled. The back button leaves the create screen without creating the new note.
From the display screen it is possible to navigate to an edit screen, which is the same as the create screen, except for that it will modify the edited note. The change can be saved with the OK button.
Deletion can be done by using the Edit button on the list screen. Alternatively the note can be dragged to the left, which will also delete the note.
Keywords: Apple, iOS, Swift, UIKit, Core Data, note taking app
DISCLAIMER: THE VIEWS AND OPINIONS EXPRESSED IN THIS ARTICLE ARE THOSE OF THE AUTHOR AND DO NOT REFLECT THE OFFICIAL POLICY OR POSITION OF THE EMPLOYER OF THE AUTHOR. THE ARTICLE IS NOT ENDORSED BY, DIRECTLY AFFILIATED WITH, MAINTAINED, AUTHORIZED, OR SPONSORED BY ANY CORPORATION OR ORGANIZATION. THE INFORMATION CONTAINED ON THIS ARTICLE IS INTENDED SOLELY TO PROVIDE GENERAL GUIDANCE ON MATTERS OF INTEREST FOR THE PERSONAL USE OF THE READER, WHO ACCEPTS FULL RESPONSIBILITY FOR ITS USE. ALTHOUGH THE AUTHOR HAS MADE EVERY EFFORT TO ENSURE THAT THE INFORMATION IN THIS ARTICLE WAS CORRECT AT THE TIME OF THE WRITING, THE AUTHOR DOES NOT ASSUME AND HEREBY DISCLAIM ANY LIABILITY TO ANY PARTY FOR ANY LOSS, DAMAGE, OR DISRUPTION CAUSED BY ERRORS OR OMISSIONS, WHETHER SUCH ERRORS OR OMISSIONS RESULT FROM NEGLIGENCE, ACCIDENT, OR ANY OTHER CAUSE.
Table of Content
The article is divided into the following sections:
- Why Swift and iOS?
- XCode Project Setup
- Integration with Core Data
- Creating the UI
- Handling the actions
- Closing words
Why Swift and iOS?
I’m not absolutely new to iOS development, although in the recent years I did not closely follow the innovation in this area. I met the iOS development first in 2011. I started to develop a mobile app prototype for the project I was working on those times. Back then Swift did not exist yet, Swift first appeared on June 2, 2014. I started learning Objective-C with the online courses of Stanford University, courses of Paul Hegarty were my favourites.
I really liked programming in Objective-C, and I wanted to learn more. However later on my interest turned to different technologies, and I didn’t continue with Objective-C. Some time ago I picked up iOS development again, and I started again with the Paul Hegarty’s Swift course on Youtube. It is a very good course to learn Swift and iOS development, with great example apps.
According to TIOBE Index for January 2019, (TIOBE index measures programming language popularity) Apple’s Swift language is on place 15.
Is it worth learning Swift nowadays? Using Swift means using Apple-based hardware, and Apple’s technology for development. No-one knows how successful the iOS platform is gong to be in the upcoming years. Even with these risks I think it definitely makes sense to start learning Swift. It will broaden your technological knowledge and understanding.
I am always excited to learn a new programming language. My opinion is that every programming language I learn offers me a new way of thinking. Writing high-quality and high-performance code has always been an art. For me getting in touch with a technology I’ve never worked with before is always time well-spent. This is especially true with a programming language with high interest.
Apple open-sourced Swift and received a lot of help from the community to grow over the last few years. Ever since its inception, it has become tremendously popular and more mature than ever. Talking about the future of this amazing programming language, the developers are not going to abandon Swift because there is nothing like a native app with good performance and a good flow. (Source: Here’s Why You Should Learn Apple’s Open Source Programming Language Swift — Analytics India Magazine)
For this tutorial you will need the following:
- A computer that runs Mac (If you don’t own an Apple computer, you can use MacinCloud, for example.)
- Operating system: macOS Mojave
- XCode (I use version
- Basic Swift knowledge
As a starting point I create a new XCode project, and start with the Master-Detail App template.
I fill the details of the new app the following way:
I don’t check “Use Core Data” because I will integrate with Core Data manually.
After creation of the new app, we can build and run it in the simulator. As you can see, this template app is a simple master-detail app, with which we can add new entries (time stamps) to a list.
By selecting an element in the list we can see a details screen.
It is also possible to remove entries from the list.
This app will be the starting point for our new iOS note taking app.
XCode Project Setup
The XCode project we build will look have the following classes and groups.
CoreDataModel group contains the model file for the Core Data integration.
Note group contains the implementation of Swift class handling the note object itself.
Storage group contains the implementation of the storage of the notes. This implementation is buit on the core data helper class, which is in the
Helpers group contains utility implementations for the date conversion and for the core data integration.
UI group contains the implementation of the ViewControllers, the UITableViewCell implementation assets (which is not used in this project), and the StoryBoards. (The LaunchScreen is not used in this project.)
The root folder contains the AppDelegate and the Info.plist which are created by XCode.
Integration with Core Data
For storing the notes on the mobile device I use Core Data. In Core Data we need to define a data model, which we will use in the app to store the data.
Creating a new Core Data model
In order to integrate with Core Data, we need a new Core Data model. This can be created in XCode.
Our Core Data model looks like the following. We have an entity, Note, and we have 4 attributes:
- noteId: the internal identifier of the note. Autogenerated by the application, not shown anywhere on the UI. Type of this attribute is UUID, Universal Unique Id.
- noteText: text of the note
- noteTimeStamp: an integer value which contains the time stamp of the creation / last change of the note
- noteTitle: title of the note
When creating a new XCode project we can check a checkbox which indicates that the app uses Core Data. If we check it, the app created by the template will contain the implementation to store the items in Core Data. I didn’t check this checkbox in the preparation steps, because I wanted to implement Core Data integration manually to learn it. Although I needed some code from the AppDelegate.swift, which is only generated when I use Core Data when creating the project.
This code looks like the following.
This code is needed in AppDeleage.swift. Here the name
NSPersistentContainer(name: "ReallySimpleNotesData") refers to the name of the
ReallySimpleNotesData.xcdatamodeld file we created.
Storing time stamp in Core Data
Storing time stamp in Core Data is an interesting topic. In Swift, the
Date object has the
timeIntervalSince1970 property, which is of type
TimeInterval, and it contains the interval between the date value and 00:00:00 UTC on 1 January 1970. Type
TimeInterval is an alias of type
Double, and it means the number of seconds.
To get the seconds from this value, round it and convert it to
Int64. The conversion to the other direction is also done this way. I do this by extending the
Date type of Swift. This is done in
The date helper implementation also contains a method to format the date properly. With this method I can show the date on the UI in
Monday, Feb 4, 2019, 11:22:33 format. The implementation of the date helper class is the following.
Note and Note Storage implementation
Note group contains the implementation for the Note. The class
ReallySimpleNote is the container of the data of a note. It can be initialized by using UUID as well as without UUID. In case the instance is created without providing a UUID from outside, the UUID is generated using the UUID which is part of the Foundation.
The instances of
ReallySimpleNote are used throughout the app to transfer note data. The notes are stored in Core Data. For handling the integration with Core Data, we have two classes:
- ReallySimpleNoteStorage: handles the operation of creating, reading, updating and deleting a note. Holds an instance to
NSManagedObjectContext, which is necessary for the integration with Core Data. The operations are forwarded to the Core Data helper class, which communicates with Core Data.
- ReallySimpleNoteCoreDataHelper: manages the creation, reading, update and deletion of notes towards Core Data.
NSManagedContext is provided to
ReallySimpleNoteStorage by the
MasterViewController, in the
The note storage class,
ReallySimpleNoteStorage maintains a dictionary to map note indices to noteId’s. The UI identifies the notes by their index, but in Core Data their identifier is a UUID. The mapping between these two identifiers is stored and maintained in
ReallySimpleNoteStorage. Calls to
ReallySimpleNoteStorage are forwared to
ReallySimpleNoteCoreDataHelper. For example, reading a note by index is implemented the following way in
Core Data helper implementation
ReallySimpleNoteCoreDataHelper class has static methods and handles the reading, modification and saving of notes to Core Data. It needs an instance of
NSManagedObjectContext object, which is provided to it by using a parameter in each and every method.
For example, the creation of a new note in Core Data can be done by calling the
createNoteInCoreData() method. This method is called from
Creating the UI
The template app we used as a starting point creates the storyboard for the app. I extended this storyboard with one more ViewController Scene. For the Master ViewController, Detail ViewController and Create/Change ViewController I have separate implementation classes.
In these ViewController classes I call helper classes to store and retrieve data from the Core Data storage. I also call the Date Helper class shown earlier.
The ViewControllers are connected by Segue’s to navigate between them. Most of these Segues are created by the template app by default, but there are 3 Segue’s, which I needed to add:
- navigation to the create screen by the + button. The template just created a new entry in the list without navigation to another screen.
- navigation from the display screen to the change screen
- navigation from the create / change screen back to the list of notes screen (this segue is called
For these Segue’s I needed to use “Show (e.g. Push)” kind.
The navigation from the Create / Change screen to the main screen is implemented in the ViewController
ReallySimpleNoteCreateChangeViewController by calling
Handling the actions
UI elements are connected to class attributes with
When the view was loaded
When the view was loaded, we need to set some defaults for the UI elements. This is implemented in the
viewDidLoad() method. What is done here is the following:
- set the ViewController as the delegate for the note text view
- prefill contents of the fields when we are editing a note
- set content of time stamp label
- set border width, radius and color of the note text view
- change text of back button in navigation bar
Enabling / disabling the OK button
When a new note is created, the OK button should be enabled only in case there are some text entered in the title and in the text field. For this, the
ReallySimpleNoteCreateChangeViewController class implements the handler for the Editing Changed and Value Changed events.
The class also implements the
UITextViewDelegate protocol, so that we can react to the change of the note text. In change mode (when we edit an already existing note), the OK button is enabled by default.
For example, the handling of enabling / disabling of the OK button when the note title changes, is implemented in the following way.
ReallySimpleNoteCreateChangeViewController is registered as a delegate for the note text view field. This way the app can react on changes to the content of the text view. For this the
textViewDidChange() method was implemented.
Throughout this article and app I didn’t implement proper error handling. The code still contains TODO comment referring to appropriate error handling. This topic I will cover later in a separate article.
Thank you for reading this article. I hope you have learned somethinf new today. The app can be accessed on my Github profile:
Really Simple Note Taking App for iOS. Contribute to nlharri/rsnt-really-simple-note-taking-ios development by creating…