Now, we want to create a repository that provides us with entities so that we can apply the functional programming features included in Swift to retrieve and process data from these entities. First, we will create an Identifiable
protocol that defines the requirements for an identifiable entity. We want any class that conforms to this protocol to have a read-only id
property of the Int
type to provide a unique identifier for the entity. The code file for the sample is included in the swift_3_oop_chapter_07_11
folder:
import Foundation public protocol Identifiable { var id: Int { get } }
The next lines create a Repository<Element>
generic class, which specifies that Element
must conform to the recently created Identifiable
protocol in the generic type constraint. The class declares a getAll
method that we will override in the subclasses. The code file for the sample is included in the swift_3_oop_chapter_07_11
folder:
open class Repository<Element: Identifiable> {
open func getAll() -> [Element] {
return [Element]()
}
}
The next lines create the Entity
class, which is the base class for all the entities. The class conforms to the Identifiable
protocol and defines a read-only id
property of the Int
type. The code file for the sample is included in the swift_3_oop_chapter_07_11
folder:
open class Entity: Identifiable {
open let id: Int
init(id: Int) {
self.id = id
}
}
The next lines create the Game
class, which is a subclass of Entity
, which conforms to the CustomStringConvertible
protocol. The class adds the following stored properties: name
, highestScore
, and playedCount
. The CustomStringConvertible
protocol requires the class to implement a description
calculated property that Swift uses whenever we write values to the output string. This way, whenever we use print
and specify an instance of the Game
class, Swift will print the value for the description calculated property. The code file for the sample is included in the swift_3_oop_chapter_07_11
folder:
open class Game: Entity, CustomStringConvertible { open var name: String open var highestScore: Int open var playedCount: Int open var description: String { get { return "id: (id), name: "(name)", highestScore: (highestScore), playedCount: (playedCount)" } } init(id: Int, name: String, highestScore: Int, playedCount: Int) { self.name = name self.highestScore = highestScore self.playedCount = playedCount super.init(id: id) } }
The following lines create the GameRepository
class, a subclass of Repository<Game>
. The class overrides the getAll
method declared in the generic superclass, that is, in the Repository<T>
class. In this case, the method returns an array of Game
, Array<Game>
, specified with the [Game]
shortcut. The overridden method creates ten Game
instances and appends them to an array of Game
that the method returns as a result. Note that we use underscores as separators to make it easier to read integer numbers. For example, instead of writing 3050
, we write 3_050
, and it is equivalent to 3050
. This way, we can easily realize that it is three thousand and fifty. The code file for the sample is included in the swift_3_oop_chapter_07_11
folder:
open class GameRepository: Repository<Game> { open override func getAll() -> [Game] { var gamesList = [Game]() gamesList.append(Game(id: 1, name: "Invaders 2017", highestScore: 1050, playedCount: 3_050)) gamesList.append(Game(id: 2, name: "Minecraft", highestScore: 3741050, playedCount: 780_009_992)) gamesList.append(Game(id: 3, name: "Minecraft Story Mode", highestScore: 67881050, playedCount: 304_506_506)) gamesList.append(Game(id: 4, name: "Soccer Warriors", highestScore: 10_025, playedCount: 320_450)) gamesList.append(Game(id: 5, name: "The Walking Dead Stories", highestScore: 1_450_708, playedCount: 75_405_350)) gamesList.append(Game(id: 6, name: "Once Upon a Time in Wonderland", highestScore: 1_050_320, playedCount: 7_052)) gamesList.append(Game(id: 7, name: "Cars Forever", highestScore: 6_705_203, playedCount: 850_021)) gamesList.append(Game(id: 8, name: "Jake & Peter Pan", highestScore: 4_023_134, playedCount: 350_230)) gamesList.append(Game(id: 9, name: "Kong Strikes Back", highestScore: 1_050_230, playedCount: 450_050)) gamesList.append(Game(id: 10, name: "Mario Kart 2017", highestScore: 10_572_340, playedCount: 3_760_879)) return gamesList } }
The following lines create an instance of GameRepository
and call the forEach
method for the array of Game
returned by the getAll
method. The forEach
method calls a body on each element in the array, as is done in a for in
loop. The closure specified as an argument for the forEach
method calls the print
method with the Game
instance as an argument. This way, Swift uses the description
computed property to generate a String
representation for each Game
instance. The code file for the sample is included in the swift_3_oop_chapter_07_11
folder:
var gameRepository = GameRepository() gameRepository.getAll().forEach({ (game) in print(game) })
The following lines show the output generated by the preceding code:
id: 1, name: "Invaders 2017", highestScore: 1050, playedCount: 3050 id: 2, name: "Minecraft", highestScore: 3741050, playedCount: 780009992 id: 3, name: "Minecraft Story Mode", highestScore: 67881050, playedCount: 304506506 id: 4, name: "Soccer Warriors", highestScore: 10025, playedCount: 320450 id: 5, name: "The Walking Dead Stories", highestScore: 1450708, playedCount: 75405350 id: 6, name: "Once Upon a Time in Wonderland", highestScore: 1050320, playedCount: 7052 id: 7, name: "Cars Forever", highestScore: 6705203, playedCount: 850021 id: 8, name: "Jake & Peter Pan", highestScore: 4023134, playedCount: 350230 id: 9, name: "Kong Strikes Back", highestScore: 1050230, playedCount: 450050 id: 10, name: "Mario Kart 2017", highestScore: 10572340, playedCount: 3760879
The following screenshot shows the result of executing the previous lines in the Playground:
The following line uses the argument shorthand notation, which is equivalent to the last line, and produces the same result. The code file for the sample is included in the swift_3_oop_chapter_07_12
folder:
gameRepository.getAll().forEach({ print($0) })
3.139.107.210