To use sqlite.swift with Swift 2, see the Create a Data Access Layer with SQLite.Swift and Swift 2 post.
A couple of weeks back I wrote a blog post on how to create a data access layer using SQLite.swift. You can see the post here. In one of the projects that I am currently working on, I wanted to create the data access layer as I described in that post because I know how well it worked from previous projects. For this particular project however there are several tables that only have a couple of columns which means I needed to create a number of classes in the data model layer that contained only a few of properties.
A couple of weeks back I wrote a blog post on how to create a data access layer using SQLite.swift. You can see the post here. In one of the projects that I am currently working on, I wanted to create the data access layer as I described in that post because I know how well it worked from previous projects. For this particular project however there are several tables that only have a couple of columns which means I needed to create a number of classes in the data model layer that contained only a few of properties.
It seemed like a waste to create all those classes which only
had a couple of properties so I started wondering if I could use tuples instead
of classes to model my data. I was
unsure how modeling data with tuples would work but I decided to give it a try.
I found out that they really worked well.
In this post I will explain how we could use tuples to model
our data and then I will show how I would replace the data model classes from
my previous post with tuples. If you have
not read my previous post about creating a data access layer with SQLite.swift,
you can read it here.
What are tuple types
A Tuple type groups zero or more values into a single
compound type. Tuples can contain values
of different types which allows us to group related data of different types
together. There are many uses for tuples
and one of the most common is to use them as a return type from a function when
we need to return multiple values. The Void
return type is actually a typealias for a tuple with no values.
Using tuple types to
model our data
When I say that I want to model our data what I am referring
to is grouping related data together is a single structure. As an example if I want to create a class
name PersonClass to model the
information for a person the class may look like this:
class PersonClass {
var
firstName: String
var
lastName: String
var
age: Int
init(firstName: String, lastName: String, age: Int) {
self.firstName = firstName
self.lastName = lastName
self.age = age
}
}
In this class we define three properties for our person and
we also create an initializer that will set these properties. This is quite a bit of code to simply store
data. If we wanted to create a typealias
for a tuple named PersonTuple which
models the same data, it would look like this:
typealias PersonTuple =
(firstName: String, lastName: String, age: Int)
As we can see it takes a lot less code to create our PersonTuple tuple as compared to the PersonClass class. Creating an instance of the PersonClass class is very similar to
creating a PersonTuple
variable. The following code
demonstrates this:
var pClass = PersonClass(firstName:
"Jon", lastName: "Hoffman", age: 46)
var pTuple: PersonTuple =
(firstName:"Jon", lastName:"Hoffman", age: 46)
We could actually shorten the tuple definition as shown in
the following code but I prefer naming the parameters to show what they mean
(really personal preference).
var pTuple: PersonTuple = ("Jon", "Hoffman",
46)
We can pass tuple types within our code just like we would
pass an instance of a class or structure.
In the following code we show how to write a function that accepts an
instance of the PersonClass as the
only parameter and a function that accepts a PersonTuple as the only parameter.
func acceptPersonClass(person: PersonClass) {
println("\(person.firstName) \(person.lastName)")
}
func acceptPersonTuple(person: PersonTuple) {
println("\(person.firstName) \(person.lastName)")
}
When we replace data modeling classes or structures with
tuples our code can become much more compact and in some ways easier to
understand however we do lose the ability to add functionality to our data
model types. Some, including myself,
would argue that losing the ability to add functions to our data model types is
a good thing because if we truly want to separate our data model from our
business logic we should not be embedding business logic in our data model
classes.
Replacing data
modeling classes with tuples
Tuples weren’t meant to be used as replacements for classes
or structures however if we create a typealias of a tuple type it can very
easily be used to model our data. In the Create a Data Access Layer using SQLite.swift
post we had two classes in our data model layer: Team.swift and Player.swift. The code for these two classes is shown below:
Team.swift
import Foundation
class Team {
var
teamId: Int64?
var
city: String?
var
nickName: String?
var
abbreviation: String?
init(teamId: Int64, city: String, nickName: String, abbreviation:
String) {
self.teamId = teamId
self.city = city
self.nickName = nickName
self.abbreviation = abbreviation
}
}
Player.swift
import Foundation
class Player {
var
playerId: Int64?
var
firstName: String?
var
lastName: String?
var
number: Int?
var
teamId: Int64?
var
position: Positions?
init (playerId: Int64, firstName: String, lastName: String, number: Int,
teamId: Int64, position: Positions?) {
self.playerId = playerId
self.firstName = firstName
self.lastName = lastName
self.number = number
self.teamId = teamId
self.position = position
}
}
Now to replace these to classes with tuples, all I really
need to do is to create typealiases instead.
For this I crate a DataModel.swift class that contains the following
code:
typealias Team = (teamId: Int64?, city:
String?, nickName: String?, abbreviation: String?)
typealias Player = (playerId: Int64?, firstName:
String?, lastName: String?, number: Int?, teamId: Int64?, position: Positions?)
I then deleted the Team and Player classes and was able to
build/run the project as it was before. We
could additionally remove the typealias names from the find() and findAll()
methods of the data helper classes. As
an example, the findAll() method from
the PlayerDataHelper class looks like
this:
static func findAll() ->
[T]? {
var retArray = [T]()
for item in table {
retArray.append(Player(playerId: item[playerId], firstName:
item[firstName], lastName: item[lastName], number: item[number], teamId:
item[teamId], position: Positions(rawValue: item[position])))
}
return retArray
}
We could change this function to this:
static func findAll() ->
[T]? {
var retArray = [T]()
for item in table {
retArray.append((playerId: item[playerId], firstName:
item[firstName], lastName: item[lastName], number: item[number], teamId:
item[teamId], position: Positions(rawValue: item[position])))
}
return retArray
}
However I think the code reads better if we keep the
typealias name in the code.
I created a github site which contains the sample project for
the “Create a data access layer using SQLite.swift with the changes made in
this post. The repository is located
here (https://github.com/hoffmanjon/SQLiteDataAccessLayer). I would like to know what others think of
using tuples to model data. Please leave
comments below.
If you would like to learn more about Swift, you can check
out my book on amazon.com or on packtpub.com.