This workshop will be retired on May 31, 2020.
Managing Gates8:45 with Pasan Premaratne
Since enums cannot contain stored properties, we need to define an entirely new type to manage the gates for each terminal
For the gate logic, we're going to create a separate type entirely 0:01 as a nested object in control tower just like runway and terminal. 0:04 Here's what our code needs to do. 0:09 We have a set of gates for 0:11 each terminal that we need to query every time a plane requests a space. 0:12 The information about terminals is encoded in the terminal type. 0:17 So we could associate the terminal's gates with each enum member. 0:21 Now one way we can do this is to use computed properties, so for 0:26 example, we could have a computed property that returns the list of gates for 0:30 terminal A, B, C, and so on. 0:34 But unfortunately, that has its limits. 0:37 A computed property has no storage in memory and either returns a static value 0:41 every time or one that is computed from stored properties. 0:46 We cannot use a computed property because we can't return the same gates every time. 0:51 Let's say Terminal A had three gates, 1 through 3. 0:57 An airline requests to park, and so we say go ahead and park at A1. 1:02 If we use a computed property for the gates, 1:07 we're going to return the gates 1 through 3 every time. 1:09 Enums can't contain stored properties either. 1:14 So, to get around this, 1:17 we're going to encode the gate information in a different type altogether. 1:18 There are other ways to do this, but because I want to show you certain 1:23 things about protocols and enums, we'll go down this round. 1:27 The nice thing though is the way we're about to implement gate logic, 1:31 we're going to learn a few more things about Swift in the process. 1:34 So, right after the terminal enum, let's add a new type, 1:39 and we'll name this GateManager. 1:43 And this is going to be a class. 1:46 We're going to add four stored properties to this class to keep track of the status 1:51 of various gates in the terminal. 1:56 I'm going to copy paste this in, and 1:59 as always, you can grab the code from the link in the teacher's notes as well. 2:01 For these properties, we're using good old dictionaries and 2:06 arrays to keep track of what gates are available. 2:09 The first property, for example, gates for 2:13 terminal A keeps track of the gates for terminal A obviously. 2:15 The property contains a dictionary on the outside with two keys, occupied and empty. 2:21 Using each key gets you an array of integers 2:30 pertaining to the different gates available. 2:33 Now there are ways we can improve this rather than using nested collection types, 2:36 but I'm going to set that as an exercise for you. 2:41 Get that brain of yours thinking. 2:44 So the logic here is pretty simple. 2:47 When Delta Airlines requests landing, 2:49 we know it's Terminal A based on the logic we wrote earlier. 2:52 So we queried the gatesForTerminalA property. 2:56 Using the key empty, that's this one here, we check if there are any empty gates. 3:00 If yes, we return the value. 3:06 Otherwise, we return nil. 3:08 When an empty gate is assigned to a flight, 3:10 we need to update the stored property. 3:12 So let's say we assign gate 9 for the flight to land at or park at. 3:14 Well, now 9 isn't empty anymore, so 3:19 we need to move 9 over into the occupied list. 3:21 So to start, in this class, let's write two methods to get this work done. 3:24 So first, we'll write a method to update the gate. 3:29 So we'll say func update. 3:34 This method is going to take a property that lists the gates. 3:38 So now this type is this thing here, string, 3:43 a dictionary with strings as keys and then array of integers as a value. 3:47 And then it will also take a gate as an integer. 3:54 Given a particular date, we want to switch it from the empty to the occupied array. 3:59 So let's say we call this method update. 4:05 And for gates, we pass in gates for terminal A, and 4:07 the gate number as number 9. 4:11 We want to remove the gate 9. 4:14 We want to remove the value 9 from the empty array and 4:17 add it to the occupied array. 4:20 So the first thing we'll do in our method is get the list of occupied gates for 4:23 a particular terminal. 4:27 So we'll say if var occupiedGates = gates, 4:29 and we'll use the key occupied. 4:35 The gate's dictionary here represents the collection of gates for a terminal. 4:44 And using the occupied key, we can get all the occupied gates. 4:50 You'll notice that we're doing something we've never done before, and 4:54 that's specifying if var instead of if let. 4:57 if var creates a variable that can be modified, 5:01 whereas let creates a constant value. 5:04 The reason we want a variable is now that we have an array, 5:07 we're going to append the gate value. 5:11 So this occupied gates is now this list or this array of gates, 5:13 and to that, we're going to append the new gate. 5:19 That's this thing right here, saying append(gate). 5:24 Now we've taken the gate and assigned it to the occupied list. 5:28 You'll notice we didn't modify the array contained within the dictionary directly. 5:32 We created a copy by assigning it to a local constant or 5:37 local variable when we modify that variable. 5:41 So now, now that we've modified it, we're going to use updateValue forKey 5:44 on the gate's dictionary and reassign this array as a value. 5:50 So we'll say gates.updateValue forKey. 5:54 And for the value, we are going to pass in the occupiedGates, and for the key, 6:00 we'll say occupied. 6:04 This does not work however, and the reason for that is the gate's value. 6:09 This right here is a function argument as you can see here. 6:14 And function arguments are immutable within the body of a function. 6:18 We can work around this by specifying var in front of the parameter, 6:23 but this is a temporary solution. 6:27 If you click on this, it says that var parameters are deprecated and 6:30 will be removed in Swift three. 6:34 So let's delete that. 6:36 To future proof our code, what we can do is pass by reference. 6:40 And we do this using the inout keyword in front of the parameter. 6:45 Now, previously, before we added this, if we call this method, update, and 6:51 passed in gatesForTerminalA, what we actually pass in is a copy of this value. 6:56 Remember that Swift dictionaries are value types. 7:02 By adding the inout keyword in front of our parameter, 7:06 now when we call the method, we are actually passing by reference. 7:09 So again, if we call this method and pass in gatesForTerminalA as the argument, 7:14 by modifying gates inside the body of the method, we're modifying gates for 7:19 Terminal A directly. 7:23 Okay, so now this works. 7:26 Now on the flip side, now that we've added the gate to the occupied list, 7:28 we also need to remove it from the empty list. 7:31 Now this code is pretty straightforward. 7:34 First we get the list of empty gates using the empty key. 7:36 Then we get the index of the value we're trying to remove. 7:45 So we'll chain this and say, 7:49 let index = emptyGates.indexOf and we'll pass in the gate. 7:51 Now once we have these two values, we can easily remove the gate by saying, 7:59 emptyGates.removeAtIndex, and pass in the index that we just obtained. 8:04 Now our emptyGates actually reflects the updated status of the gates. 8:12 So we can assign this back to the gates property by saying 8:16 updateValue forKey and using the relevant key value pair. 8:21 So far so good. 8:30 While this method doesn't actually determine if a gate is empty, 8:32 it ensures we're not assigning the same gate to two flights. 8:35 In the next video, let's implement the actual gate sorting logic and 8:39 finish off the gate manager. 8:43
You need to sign up for Treehouse in order to download course files.Sign up