Building an iOS app with coordinators – Swift on Sundays January 13th 2019

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all righty folks welcome back to the next edition of Swift on Sundays he ever met before I am Paul Hudson I run a cycle packing with Swift full of lots of free tutorials about Swift I can go check those out on the site hacking my sitcom clever that as a reminder switch on Sundays is run weekly every Sunday between 10 and 12 a.m. at 12:00 p.m. sorry kind of only time or 6 to 8 p.m. UK time this week 6 p.m. the weeks perhaps 8 p.m. we'll see how it works out but the goal is that I want to make actions that you live in a screencast you can see exactly I'm building stuff as we go and sometimes we'll do fresh apps from scratch sometimes some folks ask me do technique stuff some folks have asked me to do app to span more than one week so you might do say two or three weeks for an app for example to do biggest stuff but as for now we're still doing one app at a time to get the grips with stuff there's a code of conduct I measured it last week and I'll skip over it very quickly again this week it really comes down to no harassment or abuse of other people you will get a permanent ban very quickly if you do that in the chat I haven't the patience for that maybe quite frankly I do insist on three fundamental rules one of which is no feigning surprise so if someone asks a question that seems simple to you don't act shocked because we're all learning things no well actually so don't try and be technically correct even though it's great fun if I try to explain something that's the best that I can give for this audience don't try and say well actually did it today and no backseat driving doesn't ask a question in the chat area I am watching carefully on my screen either help them fully and help their answers or leave them to ask and I'll try to help them don't just show up in the back and hope for the best none of those things work now we are online so I have no way of judging how much is going in how many questions you have and so forth unless you specifically say what your questions are so please ask them very clearly in the chat area otherwise I ain't gonna see them it's not gonna be helpful to me just to find out 20 minutes later you've lost track somewhere so please please please do dive in and tell me when you get stuck straightaway try and correct it so those are the fundamentals if you do find these livestreams useful please subscribe to my channel I have other three videos there including right now my Xcode in twenty second series so have a look at those they're all very awesome anyway today's task let's dive rate and brighten with the actual job today's hand will make it out from scratch again we're gonna make an app to help folks track the times their friends are in around the world so if you have a friend in Tokyo and a friend in Paris and a friend in Los Angeles you can add their names add their time zones and it'll tell you where these people are what their time is all the time so it's very easy to track things but useful people have like an office where you have multiple international employees or colleagues and so forth you have all their times up front in one screen that's what making today if we can get it all done in an hour or an hour and a half maybe we'll see but to make the project more interesting we're going to use the coordinated pattern introduced by soosh conlou and honestly this app is simply enough that I would necessarily choose coordinators it's that simple however as you'll see later on using coordinators here induces an interesting problem so I think it makes an interesting problem for coordinators to solve and how it work around that so not only will you see how to use coordinators but you'll see some of the more challenging aspects of it and how it work around that what we're gonna do is we're gonna implement this thing as a before and after so I'm gonna go ahead and do this code without coordinators to begin with and you'll see how the app builds up and builds up and builds up and then I'll say ok at this point let's introduce coordinators and I'll rip out the old code and put coordinators in which should mean you get really clear before and after how code looked and how it looks after coordinators and I think I'll work better for a lot of folks because most of you have products already that may not have coordinators built into them and you want to migrate to those so to help you can kind of see it and then migrate across to it very quickly by following these instructions again it's a very simple app I would necessarily use coordinators here but at least gives you the idea for the future okay if you have any more questions you can go ahead and add them in otherwise I'm gonna kick off and start by all means I'm gonna share my screen in a moment see the chat log is right there to go ahead and ask me all questions you want what I'm talking I will try and get them if I see them I did try look over there regularly but I never get to them just ask against let you get to it because of some head as your questions and otherwise whole thing's rather pointless okay so let's go ahead and share my screen as we see the fundamentally important step to begin with so I'm going to switch up here and then press share screen button like that excellent okay so I'm gonna go ahead and launch Xcode I'm gonna attend one hopefully you're doing the same otherwise as we were a very confusing tutorial for you what I start off with a new project unsurprisingly so I press command shift and make a new project and choose a single view app template and this thing is gonna track your friends and their time zones so I'm kind of gonna call this thing friend zone so call it friend zone the single view app iOS template press next and then press create on your desktop wherever you like to make your projects so the first stream on your design just to begin with is a list of friends on the screen and each friends gonna have their name Dave and their time zone Los Angeles or PST you and have you want track time zones so you can see a glance your 50 friends or so what the time is what their name is very quickly so in this view controller by default it will be a regular UI view controller we don't want that we want a UI tableview controller so go ahead and change that to be a table view controller and it scores child downslide exist enjoy stuck there we go oh a crashing already hit paul i got a tent app builders April um I don't know I have no idea I'll find out I guess in a few weeks anyway so when I faced me a UI tableview controller and I'm going to the storyboard and in here I'm gonna go ahead and delete this current view control this is a regular big blank empty thing scrap that in its place I'm gonna add a table view controller in the storyboard put a boom badda Bing like that and this thing needs to have the same class that's gonna be class view controller and I nearly always give my view controllers the same storyboard ID as they have for their class so I'll paste that directly into there and the storyboard ID so it's called view controller the class P controller story by DV controller it's a regularly controller like that now this thing needs to be shown on the screen we launch our app so I'll go ahead and choose editor embed in navigation controller and then it's window a little bit bigger there we go then with the map controller selected I'll go to the properties and choose is initial view controller like that so at a glance they can see the view controller and that'll show on the screen begin with on this first screen we're gonna have the friends names on the left and their times on the right 9:00 a.m. 3 p.m. whatever it is right now in the time zone so I'm going to select our current prototype cell as a style custom by default and a change custom to be write detail on the left with one thing on the right another thing in this case lesson the name right by the time and so forth I'm also gonna give this thing an accessory of a disclosure indicator a little right-facing arrow telling folks you could tap on this to see more information we'll see give this out a identifier I'm just call this thing cell because I'm usually quite lazy in that respect and that's pretty much it right that's our our entire initial view controller done we've got our and I screen here with a lesson right thing and cells that's it for this view controllers design so go ahead and start using that a thing so it have you control like I said there's gonna be an array of friends the name and time zone that is a custom type 2 meter struct all by itself which we codable so our in Xcode our press command and make a new file choose Swift file then name this thing friend or Swift so a friend and this is gonna be struck like I said struck friend it's going to be codable so we can read and write it from disk using Jason and it has two properties name of the friend and the time zone the friend is in so I'll say var name it's going to be just you friend and the time zone is going to be time zone current well time zone we are personally in because by default most friends are in the time zone or one vaguely near to it you know Europeans have lot European friends and similar Americans lot American friends across the similar time zones so I'll start in a similar time tone to us that's our entire friend struct done so we can go ahead and make that an array of those things in our main view controller so we can roll it swift I'll say in here our friends is friends is an array of friends structs like that I'm gonna use that read French strokes for all the table of you later source methods in our view controller how many rows there are what each row contains and similar so below viewdidload I'm gonna say number of rows in oops number of rows there we go number of rows there we go in section how many rows are there well how exactly how many friends are I've had lately so I'm gonna say return friends count that friends count yep good and then for self enroll at I'm go ahead and say dick yourself get the right friend and put that information into the cell well this is more working this later on but it's not get started with so we'll have cell for row at explain why I'm using a class Rob there's no reason to use a class here so classes cause all sorts of headaches around dependencies and spaghetti code because they're copied by reference so anyone who uses the class will overwrite other folks who's in the class and this is some instance we're going to pass around this friend struck from place to place to place so it's be a bad idea to mutate backs it will change everywhere all at once whereas a struct has one unique owner at a time and therefore you can't have the spaghetti code problems attached to it it does mean is extra work to do in this case because of passing it to and fro but let's make our code flow clearer it doesn't just change by surprise under our feet so broadly speaking data model stuff should be struct not always just mostly self relaxed we're gonna go ahead and DQ yourself so I'll say let's sell equals table view dot DQ cell with an int afire which is cell I'm being lazy index path is our index path we can then read out the friend at that index path by saying their friend equals I scroll down a little bit there we go their friend equals friends index path dot Rho pull out the friend for that row I'm gonna say cell dot text label dot text equals friend got name and the detail text in this case the right-hand text in the cell dot text is going to just be friend dot times own identify now time zones are weird things that bizarre things and honestly the less you futz with them the happier your life will be so there are a number of ways of storing time zones and we kind of think of them as like you know GNTC ET EST PDT and similar but the standard times are Edifier uses we look at the co completion uses geopolitical region identifiers that's how this thought now if you write at time that out of this it will write at a geopolitical region something like america's slash chicago or asia slash tokyo or something like that and that's a standard way of storing identifies because they're very complicated beasts you know places like Indiana in the US have on a city or state level change the daylight savings time overtime and so we see list of timezone identifiers there's long it's confusing in places but just don't try and make it better you can't make it better it's a mess because it's just historical mess um just do what a Palazzo and give them all to the user let them choose themselves which one makes most sense of them because he doesn't know what they're doing anyway but now I'm sure they'll in defiance it'll say something like America slash what's Angele something like that show the identifiers in the text label and then send back that cell okay brilliant now we do need a little bit of code to load and save users from disk when the app launches and when it's like interesting changes it's not really required this is like a you know tutorial app I'm doing it for a second completeness if someone says this app they can actually use this code and it's not too hard to do it now quickly firstly the method called load data which will yes fair point items I agree with that but it's fine for here no data we're gonna go ahead and use user defaults cuz not storing much data remember user defaults is loaded when your app starts if you're storing lots of late on user defaults enough that takes a while to load it will slow down your app launch which will annoy users if it's really bad watchdog the iOS system actually kill your app so don't do that here though it's fine because we're not storing that much data right here we a few K at most for a lot of friends and a lot of time zones here it's fine them so it use defaults I will go ahead and pull from that whatever store in our friends key which we some data some ingame encoded chastened data so I'll do guard let save data why Oh Lucas I know Santos asks why isn't Xcode showing warnings and errors in real time I've turned off because it annoys me when I'm doing videos I'm explaining to somebody and it'll say errors all over the place they're just it winds me up and it gets confusing on the screen its tracks readers and users so I do try and chill out a little bit on that forum turn that off so life one is turned off just felt like that way but doing videos anyway say data is going to be defaults defaults lowercase how could you disable seven points you go to the xcode menu and choose preferences and then i think is it general they aren't show live issues just uncheck that box there and all those red things go away temporarily so if you're learning don't do it but if you know you're doing put off for now anyway right so we've got our pulse we now read from that some data add a key so I'm gonna say data for key and this key is called friends and if we cannot find that then fine I don't actually care couldn't find the data doesn't matter right if we could find it though it means you've got some saved aims to work with so you want to decode that and from JSON to an array of friends I'm going to say let decoder equals JSON decoder and we're gonna decode that data tuner air friends by saying God let's say friends equals try question mark decoder decode the type is going to be a ray of friend dot self and a date updated date is gonna be save data now if that fails a let's do return we failed to decode it somehow that really shouldn't happen but it it's very feasible to happen so I wouldn't put a fatal error in there you don't wants me I'll saying whoops has a corrupted arrow some like that but anyway so if this point we've got tape data I would decode to save friends now we want to put that into our friends array so you can say friends equals saved friends that so that's our entire load data method ask for save data this is effective the opposite thing so I'll do funk save data defaults equals user defaults standard I'm sizing you line let encoder equals JSON encoder and it's not what encode ups will say guard let's say data equals try question mark encoded or encode friends if that fails I would use fatal error here because this shouldn't ever fail by Frank you shouldn't or bit encode our stuff so I'll say fatal error unable to encode friends data should never happen but there you go and finally we'll do default set save data for key friends okay so we now have an array of friends with our friend struct a low data method and a save data method and when the app launches we want to go ahead and call load data get things moving and then add a little bar button item to folks know how to actually add friends to their screen so I'm gonna scroll up and find viewdidload here we go and here I want to go ahead and call load data get our stuff from user defaults again don't store too much in there but this kind of that level issue is perfectly fine I got a title of my annihilation controller say friend zone and we'll add a button here that will go ahead and add a friend to our friends array so they can go ahead configure stuff so I'll say navigation item oops navigation item dot write bar button item equals UI bar button item and we're going to choose the bar button system item option with the option add a nice sort plus all the word add depending on your language you have target will be self and select or be hash selector add friend and you might have written yet that of course we all write that method otherwise it'll complain when I press command B so I scroll down and I said here a new method a table C funk add friend it's got to be a table C because we're using target action button can only called OC methods we've got to use Apple chief this method here I'll say let friend equal the new friend friends dot append that friend we want to insert that into our table view so a table view remains in sync with the array a question from ver Angela Tia what our hash selectors that is a swift compiler directive saying please find this method and verify exists it's a method pointer effectively saying this method exists somewhere on this type it's a way for the Swift comply to find ahead of time which is quite nice question from Khasra asking web but the key friend yes so yeah in that case if I stand up if at that I would put someone at a classical constant sport class but struct um just somewhere else you know in this case it's a dummy project I mind putting the word friends in there directly but it's it's fine here anyway I've got a friend's array we're gonna insert that into our table view as well so it stays in sync with the array so I'll say table view dot insert rows at it's like an index path array and I get one item which is an index path with the row being friends count minus one so the most recently added item a sexual mu zero zone want X on this thing and the style is automatic water mapped Nick there we go and finally call save data we added a friend so let's try running this soon as nil work let's build the first life yep welcome at what typing all built correctly here are our press command ah and then realize I've used the iPhone 10 are still edible accident which is completely broken in Xcode 10.1 yay if you ever notice that Scrolls really badly an Xcode 10.1 bit of an apple bug there sadly so I'm gonna not launch it in the iPhone 10 huh huh come on your own launch launch launch launch come on all right there we go and then kill it and try again with the 10s instead which is significantly faster the iPhone scrolling bug only affects the 10r sim not a 10s so do you not use the 10 our sim for time being joining Xcode 10.2 war eleven whoever comes in a few months that bug will happen to go away but for now it's broken anyway let's launch of 10s boom there we go what users I didn't even set my sim shouldn't I I set simulator reset try that again come on camera oh it's so slow if it's slow you get terrible terrible dad jokes which trust me you don't want cam on those be a fast Magnus okay it's try again so 10's command are launching friendzone attender if you tweet me out I'll respond to you with an invite for the slack group okay here we are we grab a word friends at the top the plus button or low temp table you cells by press + hopefully you're adding to their boom it's working correctly so seeing new friend each time plus a time zone Europe / London that is the identifier identify as London uniquely amongst all the places in the world at the time zone buttocks applies to us basis in the UK isida folk that's what my fingers configured to so that is what you think anyway when we select one of these rows we really want the whole screen to pan across and show a new view controller where you can change that friend's name and change their time zone so and more interesting and of course what that saying there to happen when we add a friend as well when we press + we just want a new friend to appear we want actual things you know customization options to appear as well otherwise it'd be annoying pressing + then tap again again again so as much nicer to do + creates and configures and tapping a throat configures in one lump so we'll do this by creating a new view controller which lets us configure what a friend looks like what's their name and what is their time zone so I'm gonna kill that I'm just just delete at this time that's how it gets clear I had quite a few Baxton I think come on delete this thing please okay don't delete it house to erase while I'm talking another race anyway so I go ahead and make a new view controller press command and choose cocoa touch class choose UI view controller and this thing is called a friend view controller press next and create and once again this is going to be a table view controller I'll change a class to be table view controller now I don't make these things in that previous screen as a UI table view controller subclass because it makes extra methods I never actually want and always always delete I pro using UI view controller that way you only get one method I delete which is thing down here so it's much cleaner to do that that way anyway there's our a friend view controller class this thing has to have a couple of properties to work with one of which is our reference back to the previous view controller who can post changes back as a delegate the second is the friend that was selected that's being edited so I'm gonna say that two properties in here one is weak far delegates which is a view controller optional cuz it might be there might not and a friend so I'll say a VAR friend is a friend force unwrapped and visiting our app sorry it must be there that one it can't survivor that's it anyway that's enough for now and I'll go ahead and design this thing in the storyboard so I'll choose main dot storyboard and I'm gonna add another table view control him there it is yeah beautiful nicely cuz I'm a bit pedantic like that boom as before I'm gonna select table your controller and change its class to the correct class which is friend view controller and again I always use the same thing as my storyboard ID so I can get to it easily that way it's easy to remember we're gonna fill out this thing with more shortly but for now that's more enough we don't need any else than that for now I want to write the code to at least show that thing so back in new controller Swift we have add friend adding friends we're gonna add a new method to configure a friend this will Creighton's of our friend viewcontroller assign ourselves as delegate assign a selected friend i his friend property and then push onto the view controller stack so and here we're gonna say func configure friend some sort of friend and I'm also gonna pass in where this came from what the position was this will make more sense later on Clem we've got a pass data back somehow here is the new modified friend and we'll replace the previous friend with the modified friend and we'll know where that is with this position value here so it will integer somewhere some sort position in our friends array we pass into the configure method like this it's like I said the first step is create a friend view controller so I'll say guard let VC equals storyboard question mark dot instantiate if you control it with identify pass in friend be controller typecast that as friend view controller if that fails bailout with a fatal error unable to create frame view controller that should never ever ever ever happen because it must be there there's a storyboard but isn't in there it's broken bailout and die goodbye anyway we can now say I'll delegate for that VC is our self as predicted and the friend is editing is the position I started a friend so a question from veranke I would use in out no no I would very very rarely use in out and as I particularly wanted to cause problems for myself ideally you want to pass in data and receive back data as opposed to modifying it freely that's why I'm using structs again you want to have a unique copies your legs being passed around rather having things being mutated in out it is effectively so make ourselves you dead like on the view controller give it a friend edit and then finally neighbors controller mark push me controller that view controller animated true so push on to the finished you control a stack so can be seen on the screen so now we can call that when we add a friend so we had a friend in app in the table view it'll immediately start editing that friend so save the user click there right or a tap on the screen so I'll say configure a friend when we just made our friend and the position is going to be again friends count - 1 that's the one that was chosen in our oh right it's just added we can also now add in the did select row up method for our table view because we can be up here somewhere we have self a right and so forth we can now say when they selected a cell short in a screen so I'll say did select row at index path that again when it's called straightaway configure friend friends index path row whatever friend it chose and for position will just be index path top row now in theory I can press command ah it'll build and run and deploy to my 10s and see if was slightly further along I'm at a friend boot which slides in with my editing screen and there is my friend are the Christ plus now adds a friend and immediate let's you start editing the friend now there let's see friend screens blank fine but the concept is sound you add a friend you meekly start editing that friend okay so let's pause view controller for now we'll come back to later on and voice fast as I can but already halfway through our time sadly um I was not looking at friend view controller what that has to do let's configure the friends nicely so again this lets us enter the name of the friend my friends called Laura and she lives in a New York Times own or my friends called Dave he lives in a Pakistani timezone whatever is a name for a friend plus their time zone that's the point of this new view controller so I'm gonna head back to main dot storybook or I have my friend you controller hit this thing is going to be a grouped tableview with two prototype cells one will be a text entry field and one whether it be elisa time zones like that so a text entry field there are a few ways of doing this there is one nice way of doing this and we're gonna follow that a nice way now i don't really want to teach too many bad habits what i'm doing live streams the nice way of doing this as Josh said earlier is have custom UI tableview cell classes where you have your own things in the side there so I'm gonna have two pair of type cells in here like that and again I'm gonna make this thing grouped style but I want that first cell to have a custom class I've defined so our press command end choose cocoa touch class I change the subclass to be UI tableview cell so there we go I'm press named it supposed to be text hey with yourself some sort of text handling table yourself and next and create that and back in minute storyboard we can connect that class to this first cell I have to prototype cells here this first one is going to be an instance of text table view cell so it will have access to anything inside that class the other one is going to be not a custom style but I think probably a subtitle yeah like that that way we can show certain like America slashed a cargo and then title GMT - Oh crikey six six I guess probably six or five it's a six anyway I'll edit this later a live stream so we have a custom off the top with our text in a second at explore a second and a subtitle one in the bottom for all the time zones I had a group style thing so we can so a nice separation between the entry of names and a tight the time zone selection beneath so we're gonna make some changes to the way our textview self thing works it needs quite a customisation here because by default by select it as our text here we sell here you'll see things like it can be selected which makes no sense we don't we'll be able to select this cell then want to select the thing inside the cell not the cell itself so it had to be none so you don't get a great thing when you tap on that cell similarly we want to have something outside that you can select which will be a text field so whether you just can enter the name of their friend so I'll go to library look for text drag out a text field into the box and then I'm gonna control drag from this text field up to its content view hold down shift to get multiple constraints at same time and choose leading top trailing and bottom at the same time so we have four constraints pinning it to all four edges of its content view Andy Warwick saying pros or cons of segways versus manually printing VCS giving them using storyboards I almost never use segways back I never use segways like never use segways I can't think of the last time I actually used them when I wasn't just teaching segways I I find them so very annoying as a way of hard-coding application flow directly into your storyboard and I can't think of a wild ever want that to happen I'd rather decide my flow dynamically in my coordinate as we'll see if we're lucky we get to it as fast I can go in this talk this one's likely to run more an hour I feel because I'm really 20 minutes to go in the hour this could be like ninety minutes easily I think anyway onwards we got text field pinned or wedges I'm gonna modify this so it's constraints are exactly 16 points on every side 16 left 16 right 16 bottom 16 top like that so it's it's a shrunk little bit but in when it runs it will get bigger and then I'm going to ask this text you to turn off its border style so that we the leftmost one wears non border style so it becomes invisible the whole looks like an editable area that's what we want to get here for a placeholder you know a default name I'm gonna enter in John Appleseed curious fact things you learn this pod is a live stream Johnny Appleseed's a real historical figure in the u.s. he planted apples around I think Pennsylvania anyway so I thought placeholder text right there John Appleseed I'm gonna add this clear button appears while editing so I can clear names very quickly if they want to like that and now we want to connect that text field to the class we just made the custom table view cell class text table you sell so I go to this narrator and by default it's chosen friend viewcontroller.swift which is a bad idea but here you'll see number two there's something else it could show me we press left Chevron there get the alternative and now it's showing us correctly text pay with you cell like an control drag from that thing down into my cell class to make an outlet for this thing I'll call it text field boom connect boom so now that text field is able to talk to its class we can reference it from that class when we have it which is very nice the second thing I want to do is when this text field changes I want to notify our view controller so in the other assistant area friend you control our Swift I'm going to right click on text authority control drag on text field and pull it out into my view controller make an action and I'll call this thing name changed how much I want to look for here a particular thing no editing did end I want editing changed so as they're typing I'm reading that every single time as it's happening and for type make our lives easier only you'd UI text field maybe the actual text bill that set this message every time and press connect boom I will type in that text field it will all the viewcontroller name change every single time type of letter that's really convened to do and the second cell is just for handling the time zones it'll have you know Los Angeles US America Los Angeles GMT - a song like that right so that's what's going to do that's all that was fine for that there's no quick running yet because let's actually change I've got a code to show this yet so the next step is to make this view controller actually show some time zones so I'll switch back to the standard answer choose friend you can talk to Swift and then here we're going to add two properties one is an array of time zones all carefully organized rows of work on the thing because you have to get least one system carefully the second thing is the index of the time zone that's currently selected so first I say var time zones equals an array of time zone like that and secondly bar selected time zone here zero just start like at the first one we don't care 20s do you miss it and now inside viewdidload we've got to get all the system's time zones and there are many of these things can again time zones are complicated don't try and outsmart time zones especially Apple they know time zones so let them do their magic we're gonna go ahead and ask system for all its times identifies and then show them in our array so start with let identifiers equals time zone dot known time zone identifiers these are all the ones the system understands already I'm gonna say four words fire in identifiers and now we're gonna create a time zone instance from these identifiers it'll have a string America / Los Angeles we're gonna make an actual time zone instance from that we can then display and work with because time zones the actual time zone object have useful things like for example how far away from GMT are you which want to show it will I say GMT - 9 GMT plus 3 and similar so I'm gonna say if let timezone equals oops here a time zone with the identifier we are passed in so if this was successfully made into a time zone we're gonna pend that - I'll write that oops time zones time zones there we go append that to our array and once that's done time zones the array will have every time zone the system knows that every single one but we want to sort it so they come in a sensible order and we're gonna apply a double sort firstly get these things organized by westernmost through to easternmost so I'll start like you know GMT - something crazy like I think thirteen or fourteen is the most Western or way through - like plus 13 or 14 years side and also by name because some places back many places have multiple time zones with the same offset for example GMT is used in I think Portugal or parts of Africa for example use the same time zone GMT but they don't call it GMT necessarily they're called something else maybe but we'd have it's multiple places organized by time zone first offset from GMT and then region name so we'll sort Africa before Europe and similar so so double sort here we can call time zones dot sort with a custom closure first we'll get the difference between the first time zone and GMT so we'll say let our difference equals dollar zero the first time zone dot seconds from GMT for some date I had to save a bit of time here I'm making a new day ahead of time I'm saying that now it goes to date will reuse that date again again again and again rather making new date a thousand times and I sort so I'll have it here able to do now and in space let other difference equals dollar 1 dot seconds from GMT for now so half hours the first one from GMT half price second one from GMT if our difference is identical to the other difference so it's the same timezone we want to sort it by name to put say London before Portugal so if it is the same we're going to do return dollar 0.8 enter fire which we Europe slash London is less than dollar one but in the fire which would be Europe slash Portugal who knows what Lisbon I know otherwise if they're different fine we can just do return our difference is less than other difference there's two a straight integer comparing that one so that all the times up those earlier time zones appear first and once the salt completes we're gonna go ahead and update the selected time zone property to be whatever the friends time zone was where to find that in the array and then attack back through them set a time zone so I'll say set a time zone equals time zones got index of friend dot time zone if that fails for some reason they've got bizarre time zone nil coalescing zero so it has a default value of zero if they couldn't find their time zone so now we have this array of time zones all beautifully organized at what bubble sort them swift actually uses two different kinds of sorts in order to get the most efficient kind of sorting to answer varieties questioned but yes it will do it everything on this table view so you could if you wanted to put that somewhere else and hive it away to reusable time zone manager destructor class that's fine Andy Warwick and is asking wouldn't we lazy be better well not really no because it's got to happen to show us new controller so making it lazy wouldn't save us any time this new controller has shot every time zone inside it so has to have have them up front lazy or otherwise it has to be their variety selection session of putting it well pastor to put it somewhere else is accurate you could hide this off do it once and make a reusable array of time zones will be quite nice actually but you know what you'll find is this is lightning fast I wouldn't worry too much at this point you know premature optimization all that kind of thing anyway we now have no rare time zone you want to use that for our datasource methods so I'm go ahead and make some cut out here first up a number of sections this defaults to one in table controllers we want to because the first one is going to be named your person and your friend and the second one is going to be all the time zones so there are two sections here the second one is number of rows and section and here if we're in section 0 the top one there'll be one row mean your friend otherwise there will be time zones count rows so I'll say if section is 0 return 1 else return time zones count we got the right number of rows depending on our section now for the important part identify these clearly to users so we're going to use the title for header in section method remember I've chosen this nice grouped style so get a nice little break bit of gray space title saying name your person bit more space title saying choose our time zone and a list of time zones all done by sort of table views and their headers so I'll do title for header in section boom if section is 0 this is the bit worst a text field that supposed to name their friend we're going to return name your friend else section one will do return select their time zone that so identify those two sections really clearly to users and now our first bit of serious code first section so Chris Ops is asking should the first should be two rows name and time zone yeah that's possible two steps the way I'm going to do it is slightly different as you'll see I'll show timers one big long list and one of those will be theirs you're right we could pre select one and put at the top that also works well but you know at end of this it's your project you can optimize it all you wants to customize it it's down to you anyway now for the the big one in this is a class sell for at we're gonna load one of our two classes and show on the screen correctly as we go so let's go around a little bit we'll do cell for row at and if index path thoughts section is zero if we're in the name your friend bit we've got a DQ a tableview cell and typecast it correctly to be our text table you cell plus so I'll say guard let's sell equals table view dot DQ reusable cell with identifier name and it's gonna be called index path and well I've typecast this thing to be text table view cell if that fails fine fatal error couldn't get a text table view cell again it shouldn't happen I think I named these things I'm a bit lazy in that front let's just check never know I named them I did not name them see that first ones called name sake ones called time zone there we go don't be lazy don't be like me anyway first was called name second was called time zone so back in the code again we're gonna DQ that cell named typecast are custom types you can start modifying it and then send it back so if you have a cell which we should of course we're gonna say cell dot your text field it's going to be a friend dot name give it the text field in there as I should do and send that back else if we're in section number one the second section well the time zones all are how will I find known time data fires it's actually just built into the the class jemand it's you can be the docs everyone asked about that look at over there I'll have to meet up documentation anyway second section we got to pull out the correct time zone for our cell and show it in there nicely I'm gonna say let's sell equals table view dot DQ reusable cell with identify densifier now is called time zone index Partho just index path this does not have to be typecast as perfectly fine as is we do have to pull out the matching time zone so I'll select time zone equals time zones index path row I'm going to put the time zone identifier into the main text label of our cell so I'll say cell dot text label text equals time zone dot identifier then into the detail text label I'm sure to take the time difference how much that varies from GMT and put that in there so it'll say in seconds like - 3600 seconds song like that right some difference between GMT and it so let time difference equals time zone dot seconds from GMT for the current date and put that into the detail text label I'll text the string difference I've obviously made a cunning typo somewhere I'm not a press Bill just yet nice surprise Annette piays I'm sure put that into there like that we also want to make sure users can see the glance which is the currently selected time zone now before we added this property called set the time zone as an integer we can compare that against our index path and say is this the current is a cell actually selected if so give it a check mark so if index path doc row is selected time zone then cell dot accessory type equals dot check mark else sailboat history type equals dot none and finally return so alright let's press command B and see what mistake I've made what fundamental error I have to hate here it is whinging I wrote time zones that it my entire mistake yeah that's my time mistake not bad not bad I pressed command R see if it actually works of course before I get too happy of myself here we go there is friend tap on them oh yeah look at that okay now we're seeing time zones you can see there are stacks of these things and there are stacks of them because they're very complicated again you know you can see there's multiple in Australia mostly an Asia and similar that may look similar like the same sort of number offset but how they vary there summer time when they varied it and similar all is different there's a lot of history here and you all look at the real the real painful area you won't go up to say America and Indiana okay Indiana is a real ball of pain so yeah you can see down a city level here Kentucky Louisville Kentucky Monticello and so forth so you can see lots going here Indiana Annapolis Marengo Petersburg and similar all these towns Indiana have their own unique time zone identifiers too varied historically how they handle times and may still do today so it's a eventually problem the today question from Robert did I mean to use now insert a date in time difference did I make mistake somewhere obvious I think it looks correct to me but you might be right it looks fine the numbers are correct these are time differences in seconds from g8 GMT so you can see there's a lot you know half a day here almost that's messy almost a full half day there but it looks correct to me Robert anyway if isn't correct we'll know shortly because the Apple go hideously wrong um so what come back and correct it at some point anyway well we've got this point is things are kind of working but there are a number of problems and at least I I know four or five problems Odin six first up if I try and select this step I click here to select this text for you doesn't actually work I've got a click in the texture itself all this area here I'm tapping away and that they actually happens because X view has spacing inside it I worked it exactly in this tiny box text for you to activate it which is rubbish right we don't want that won't click anywhere in that cell to activate the text view secondly as we scroll around that keyboards saying which is really annoying I don't like you want to be there it's gonna go away through them where do you get rid of it you know if I select time zone it should do something not just make the thing gray and when I show a checkmark there these numbers here like - 36,000 that's meaningless that's nothing at all useful for users to look at so where I make that much nicer as well look around this one here we have a specific one here has underscores rather than spaces that's just the way Apple stores these things as underscores so here's Los Angeles Los underscore Angeles I suppose lost space Angeles so formatting kind of sucks as well and probably critically most important of all any changes we make here when we go back or ignored so the screen looks kind of vaguely okay but it wasn't returning back so it sucks this is a pretty user screen right now but we're gonna go ahead and fix all of those errors however now just enter to you there's quite a few right where are you little niggles we can look at and get fixed quickly so well pick up for the first one which was that I'll right-click anywhere in this cell like here clicking here really hard nothing happens I work like exactly in a text field like that to get it active I wanna make it so that my click anywhere in that cell will activate the text field that's much easier the users to use and the smartest way to do this is to add a computed property that gets that cell as the right type and sends it back so we can activate and deactivate that filled as needed so in a friendly controller I'm going to add a compute property here thank you very much Josh that is there that's exactly correct they are as GMT but it varies on DST anyway Andy yes the system update regularly with changes I think I saw the legendary they've long tweet just this week there'll be no leak second this year this summer update these things all the time leave Apple to do all the date handling for you do not do your own date handling it's a disaster it's a brain vortex don't do it anyway I'm going out of computer property in here that will get us that top cell to commit later so I'm gonna say var name editing cell is going to be a text may of you cell optional it's a computer property so it's coding here I'll say let index path equals index path row will be 0 section will be 0 like the first row in the first section and return table view dot self row at that index path typecast as text table view itself that means from now anywhere in our code we can read that name anything cell and activate it freely as needed and we'll do that in two very small new methods we're gonna add func start editing name this will be just name editing cell question mark dot text field dot become first responder to activate the text field please and secondly when they select any time zone they're finished with the text field will call resign first responder so I'll say func select row whatever are they chose have some sort of index path they selected in the table view I'll do name editing cell question mark text field dot resign first responder like that boom so in a tap on the thing it select it activates it when I set anything else it will deactivate it they can see the whole screen freely so we can now call one of those two inside our cell for wrote up I did select row at index path method so let's go ahead an implement here did select row at that should be over right if our index path section is 0 we tapped on the first cell in the first section then we can say start editing the name otherwise what is called select row at index path and pass in the index path they chose and that should be the first problem solved I'll press command R build and run there's my thing I'm too bright the corner here boom it activates straight away so now fat-fingered folks like me who aren't too precise can tap anywhere in that cell to activate the text feel it's much much nicer way of working take a second problem is that as we're here editing stuff with our keyboard showing like this as I am scrolling around I want this thing to go away it makes no sense for when I've scrolled off down here to hide a third or more of a screen with the keyboard this is a a 8ns simulator it's quite a full screen on an S II and iPhone se this will take up most of the screen it'll look pretty ugly so we can fix that very easily to go to main dot storyboard and choose our table view there are options down here on what look at down here is keyboard do not dismiss change that to be dismiss on drag so soon as you scroll that table view in any direction it will dismiss the keyboard straight away which is much much finer way of working best command our again let's make sure it all works nicely so I'll choose this friend here let's choose a thing there's a keyboard I'll scroll slightly and bang it's gone so it means as we scroll the whole thing clears up to make more space which is much much nicer way of working third problem when you select a timezone it should be selected you want to see it checked on the screens you can see what actually happened now we have this very helpful select row method which is triggered whenever a row is selected in the second section that's from one I'm going to use this to check at a check mark to one cell but of course we must also uncheck any previous cell because it's changing we don't want you know multiple times isolated that'd be a disaster so we're gonna do is gonna say for cell in table view look table view dot visible cells show me all the cells are currently visible on the screen we're gonna say cell dot accessory type equals dot none uncheck it now update our selected time zone property to be whatever one they just chose so we track it more easily and update our friends timezone the one our struck that was passed in to be whatever time zones matches that in our array will do index path row inside the time zones array and now we want to check the one they chose so I'll say let's select it equals table view dot self row at that index path that undo selected dot accessory type equals dot checkmark give a check mark and finally I'm gonna deselect the rope so little flash and gray check the thing and then fade away again they've made their selection so we'll do table view dot deselect row at the index path animated true come out ah let's build and run that to see how it looks I'll choose new friend I'll choose America there we go look at that you got a little gray flash a nice blue checkmark that moves around correctly as it's being shown much much nicer our fourth problem was we're seeing numbers here like minus thirty six thousand which is a useless number that means nothing to anybody we don't want that on the screen we want nice for third number this thing's seven hours behind this is five and a half hours ahead or whatever but nice for the number so it's clear at a glance which time zone this person actually belongs to to do that we're gonna modify we could do it a number of ways but one nice way of doing is to modify int with an extension to say that we're extend integer to have a time string method now we could add it as a method in this view controller that is great because in this particular app having it bills to convert from seconds to a timezone format would look nice in a number of places so using that and globally forges is a good idea and II work assume used to it real cells there is one cell screen and flushed is a checkmark yes correct and it's correct yes Zann yes bill says wouldn't catch it we wouldn't need to accept we scrolled back onto the screen and would have its own when you come onto the screen it checks here my currently set time zone or not dates it but you could put this in will display cell at index path this would be absolutely sure if you worried about the problems cuz it's it's feasible it could can go slightly off screen and not have to be reused and no no but yeah you put in will displayed you absolutely sure a pretty good idea anyway we're extend integer to have a time string method they'll take an integer and convert to do an hours and minutes structure so I press command and choose Swift file and I'ma call this thing int - time formatting Swift there we go and we're gonna make an extension integer to add a time string method that returns a string formatted nicely so I'll do extension int funk time string returns a string now there are a number of ways of getting hours and minutes and seconds or similar from an integer there's the Duke yourself way there's the slight smarter way unsurprising I would do it the slightly smarter way cuz I'm lazy but also apples pretty good at this and let Apple do it for you it's great I'm gonna say let formatter equals a date formatter formatter dot allowed oops allowed units why you complaining me you horrible think I'm sorry take components weather so date components for my thing there we go allowed units equals dot our and dot minute I don't think he says hopefully I don't think there are any time zones at you seconds there's our minutes only so get five hours behind or okay so india five-and-a-half hours ahead we also want to give us a style for the units now there are a number of stars you can give for matters and or explained nicely the way what here is called positional and we look at the help for this a quick help it does say explicitly most commonly used for time areas where our military used separate by colons if you want things like you know just the hours like this it's a really nice way of doing that is it positional like that so we've configured our formatter now we're gonna give it a tie mental to work with and return that back so I'll say let formatted string equals formatter dot dot string from this takes a time interval which is actually a double behind the scenes we will convert that to be at our cell to meet time interval otherwise it will complain and if that fails because it can Theory fail we'll pass back just zero there was no time difference whatever I never turn that back for my third string there we go so I'll pass back and nicely formatted string from an integer back in friend new controller we have this code here on line 88 we just take a string form of our current integer time difference and put that directly in there that's gonna go away instead were to say time difference dot time string press command on now we should get some nice for my thinking nicer if I see anyway how choose the first one there we go so minus 11 minus 10 minus nine and a half to do there we get through to Africa here we're hitting 0 0 0 to 0 this is all on GMT or similar and then one and two and so forth this is better it's better but it still kind of sucks you know the the positive ones like Berlin we usually write plus rather than is having one we want GMT plus 1 or GMT minus whatever and just having 0 quite rightly looks weird however that was up here somewhere down here Danny there we go these are just look weird right and should you say GMT or similar so we're gonna modify this method a little bit our time string to be slightly better we're gonna say in here rather train it directly we'll say if the four third string is exactly equal to zero so is just GMT we will return GMT else if this thing is negative for third string dot has prefix - will return GMT - what it's drink and else we're gonna say return GM teeps GMT plus formatted string question for Manuel we will Alec a date yes we exactly we will you're absolutely right there's another instance of sorry except the question was will we Alec a new date components flight of each cell yes we will yes we absolutely will this is another instance of premature optimization this is likely to not be a good thing there were more fact this out more neatly later on but again ways until it proves to be a problem I wouldn't worry too much about it you know there are some things aren't great particularly date for matters they have to handle calendars and it's possible they could pop mutters the same thing I Chris can the behind-the-scenes I'm not sure but I suspect it doesn't anyway there are some things we're making them regularly is is very very bad we don't want to at all yes we don't want you to march 1 simply thank you very much Andy wired for the question okay so this I think will make the whole thing look better let's find out again press command RT built and run how to use top one there we go gypsy - Levin let's go down yep just GM's he and plus one so that's looking much nicer already okay the next problem we want v now I think v problem was that we use underscores rather than spaces is trivial to solve in friend view controller we had its fire here what us do replacing occurrences off underscore with space that's it I solve problem weekly super fast choose that and boom that's what's gone looks nice too already great the last problem is that no changes are being safe and open do you want call us thing pause at a time when you want to it won't be safe when we push back to the first view controller so that's actually happening here which kind of sucks we want to do better than that past days actually back and forward now we do have in friend new controller when we have select row which was down here somewhere there we go we are modifying our friends time zone whoever was chosen in the table view controller which is fine we also want to add the same sort of thing up to the method we made earlier from IB name changed to ascend that then the name of the friend back as well so I'll say friend dot name equals extend lock text otherwise empty because it might be Nilson reason but that doesn't mean any bits posted back still we're modifying our local struct we aren't sending it back now as well asked earlier we could have used classes here in which case this would have modified the original friend in the original array but it means that they just change it underneath your feet by surprise using structs here stop that from happening we're going to post our change back to original view controller when we're ready and not before so to do that when were in viewcontroller.swift we want to track which friend was selected so we have this method called configure friend down here it has his whole position insta coming in this friend friend number five was chosen friend number zero is chosen and so forth we want to track which one was chosen so when we're ready the friends who control can say okay here's the new friend object at position whatever and it'll know which one to change so when I add in here var selected friend it gave me some sort of optional integer like that no nil by default right it's just if you have a value a citron but South it'll be nil like that and when we call configure friend down here at this point we can update selected friend to match that position so it now has a value so we're now able to find which friend was changed later on and now the next step is to write a method the friend view controller can call on its delegate on it so you controller here to update a friend what it's changed so I'm gonna say func update friend some sort of friend and first we're gonna make sure we have a value a selected friend otherwise it'll be a bit of a disaster we'll say god let's select a friend equals selected friend else return just bailout some reason we got here somehow without a valid value in there if possible but you never know we're gonna say immediately friends selected friend equals friend take that item in the array they were editing and replace it with the new version of the item whatever happens to be and save the data and more importantly reload of the table view dot reload the data because it's changed somehow the names change something like that right whatever's changed some sort of thing has changed in the table the name all the times up whatever and now in our friend new controller we can call up method when we're ready so as we are ready man well possibly it's live streaming all sorts of things happen during live streaming in here I'm gonna rely on view will disappear so when our friend view controller is gonna go away at that point we should update the parent and say here's the latest data you could add a Save button iOS doesn't really go in for save buttons with a first or immediate automatic sort of save much nicer so our first say super dot view will disappear animated and then delegate update friend-friend pass back the friend we had before and now I'm gonna press command R see what comedy mistakes I made if any questions Nico why don't we load a single cell we could do we absolutely could do as you'll see there isn't time for it when we're out of time imminently if you take this project further you'll realize updating single cells you've got to do very very carefully what we're going to have a difficult time for was showing times and here as well as the clock ticks all the cells should change as well and have you happen to be in the wrong view controller when you change those cells but you can get a mismatch between your data and your table view you really read careful so the simplest way in this approach is just to be like the whole thing but yes I would agree doing one single set of thymus is ideal anyway I have a new friend here I'm gonna name my friend I'm getting the keyboard and use my heart real keyboard in sick it's much easier I'm gonna use the name muck just entirely random honest I've got no idea what time zone max in I'm gonna say he's actually in one of these hideous indiana places you're in this city here one of those six different indiana time zones now mark you buddy eight bags packed anyway he's in that time zone there I've told the time zone I have given the friend of name when I go back boom America mark America Indiana buffet or Vivi and I pronounced it anyway so has worked correctly it's now posting things back to the main screen which is really really nice did I oh I did you're right good catch Andy well done and view will disappear not to disappear I'm stay thank you right Andy anyway so this actually works now posting there's our back and forward correctly it's not ideal yet you know the point of the app is that on this screamer looking at wherever it was here you would see the time zone for mark what is the time where he lives as opposed to just where he lives but who kind of know I could fix that really easily now it's all working correctly back in there you can't all it's Swift we have the dirt in cell for row at here we are just printing out the identifiers directly we want to do is format that somehow so we're gonna make a new date formatter and before Manuel says yes this doesn't mean I'll make a new bait from adder for every cell you want to reuse that somehow that's fine but from now it's perfectly fine let date formatter equals a new date formatter date formatter time zone equals our friends time zone so you use whatever their time zone is rather than our own time zone and for a time style there are a number of options here the one that works best is short let's give me the absolute minimum required information just hours and minutes effectively and that with all that we can now say give our detail text level text the text date formatter dot string from date and that should let's find out work boom okay so mark is not shown there's 220 and my new friend is my turn time zone at 720 I'm gonna go here and add a friend I'm going to add my friend flora who lives in France not Florentine yes and he ought to correct it is in France so I was down to Europe slash Paris and go back and boom yes everybody for me a twenty five Florin so it all works very very nicely ok Wow take an hour and 20 minutes almost subtracting a bit of time for explanations beginning to get to this point of an app that kind of works this is an app that's feasible there's so much more we could do with this like I say you want about a set I know a reference time in here saying instead of showing the current time say set 10:00 a.m. you know what is what is what time is it for mark when it's turning out for me so you can plan meetings more easily and similar but that's for other day perhaps at this point finally we haven't at the kind of works we can look at how could convert this thing over to use coordinators and it's actually surprisingly easy process to do and it's a wonderfully clean pattern if you look at the previous one Sunday's like last week's we went through and slimmed down our view controllers so that a lot of the work was done elsewhere I personally believe you control should be you short under a hundred lines ideally under fifty was perfect but short view controllers which means getting things like cable you sauce out of there mostly that got checked last weeks I'm not gonna do that here instead all of the coordinators and coordinates are another brilliant thing for slimming down view controllers they were introduced by soosh conlou one of my all-time favorite iOS speakers I've got some great blog post about it as blog conlou commonly he tweets also I think it's at Connolly and the idea is you get a navigation out of your view controls and put somewhere else and we look at our code in our view controller we have the Select row at course configure here which goes down to do here this thing is whole guard let VC make a view controller configure the view controller present the view controller what's happening is our view controller class here do you know what Swift has to know about create configure and display the friend view controller which it couldn't care less about it's not really attached to vend view controller it's not the same you control a lot relate to view controller it's a different view controller and we want real isolation and that's where coordinators come in they let you pull apart your project so your view controller stand alone independently without talking to other view controllers and even better this line here comes out the view controller what's happening here in the words of a Suroosh have this child to controller RB controller right here is reaching up to its parent and telling it what to do hey parent please push this and that's rude it's not a good way of handling dependencies multi-directional penalties happening here which isn't ideal with coordinators we can yank most of that code out into a coordinator so a separate object handles the flow between our view controllers and it means you can change your mind in one central place I want to do a/b testing I want to handle iPhones or iPads whatever you want to separately it own coordinator class rather than your view controllers you can mix around your view controllers freely they're beautifully encapsulated there's no more mingling and mixing and matching and so forth it's all very flexible and of course benefit you get much shorter you control it again see last week four hold the real tricks this one's about coordinators okay so it's ready 25 past seven here I'll get through it as fast I possibly can press command n to make a new Swift file called coordinator coordinate or dot Swift this is what I find a protocol for coordinators what should a coordinator look like in order to work in our app so we're going to say delete foundation and you like it instead we'll do protocol coordinator you have to have and a rate of child coordinators trout coordinators which itself is just an array of coordinator like that just get set and a navigation controller the UI every controller gets set and we need that one there because this thing has to show and hide view controllers freely as it wants to and that's what it'll use does it mean I have a bar at the top there could be no bar at the top for all we care but it's there so we can show and hide you control us freely all how to be a coordinator you've got to implement one method called the start and the reason it's there is because you might have multiple coordinators one for your whole app and oneness to do the login flow one for the purchasing flow one for the first-run flow and so forth and they all going to say okay first one flow create yourself and now start you have controlled the app and when start is called a to present its first week chocolate and get things moving it's now control of the application so that's the minimum required to be a coordinator in our app I press command and again make another Swift file and call this main coordinator there's an actual concrete implementation of the coordinator protocol I press create and I'll say class main coordinator is a coordinator now it needs to be a class here rather than a struct because multiple instances are view controllers will all point to the same coordinator using a weak reference but you can't do with structs Andy question I would end game is to pull co2 choose time zone into embedded view controller and better view controller not sure necessarily that no but anyway yeah it's your application Philippos however you want to and you do it works best for you anyway make coordinate this thing has to have its child coordinators so I'm gonna make simply an empty array like that it needs to have its navigation controller like that and he's in it clear to class so I'll do in it with a navigation controller some sort of you I know whose controller that and self dot nap controller equals no drama what type of did I make I guess important you I keep the hell wouldn't it mmm there we go boom after start method I'm not gonna write anything just yet we'll come on to that in a second so that hopefully now we'll build thinking there we go we're gonna get good so when this start method is called it has to instantiate our main view controller class called view controller and show it in its nav controller but it will also need to show other view controllers along the way in this case you only have one which is a friend view controller but it'll have to show others along the way now when I use coordinates I need always add a protocol to make my life significantly easier let me make new controllers from storyboards easily in one central place so press command n choose Swiss file call this thing storyboarded swift and this needs to have input uikit again and let's gonna say your conform to the storyboarded protocol protocol storyboard it all you have to do is input the method called instantiate returning at instance of self so it's static meaning exists on the class now turn self mean it exists whatever type of call it conforms to man well why not create a friend you can't order to enforce the function invitations so we could on that if I wasn't use coordinators here that's what I would recommend using a dedicated protocol instead to have that instead but one of the things in this particular live stream instead of setting how to use coordinators hence why I'm using them here but yes protocols are generally a good idea you want each protocol here at least now we don't want classes to input this method itself we want me to do it by ourselves most of the time so I'm gonna say extension I'm sorry that begging out here extension storyboarded where self is some kind of uiviewcontroller we're gonna implement static Frankenstein shape turning self and because I have named my storyboard classes the same identifier as their class we can use that to find view controls in the storyboard trivially so I can say let class name equals string describing self which we view control of the string or friend view controller and string then let's storyboard equals UI storyboard the name is going to be main and the bundle is bundled up me load my main storyboard and finally return storyboard dot instantiate you can follow up with entice fire our class name and do a forced typecast as self now this force typecast is perfectly safe here this thing must be itself that's the point of it and you haven't have used a class name a identifier be just causing problems for yourself as a bad idea please don't do that if you look at my main storyboard I believe I have named these things correctly so it's much should be a friendly controller here per view controller here and you controller to control it here you control it here it's all work correctly for these places anyway so now we have this protocol we can apply that to our view controllers we can say hey do the polar swift you conform to storyboard not empty of store action storyboard it there we go and do the same for friendly controller up here they both now conform to these storyboarded protocol that means is our coordinate can create instance of these things easily so in main coordinator in this start method we can now make a view controller instance by saying just let VC equals view controller got instantiate and now have controller dot push me controller DC animated true falsely it's the first one don't have make it okay Sal compiles cleanly so that's the code required to make our coordinators work but they aren't being used by the app yet the app still bootstraps to the storyboard this movies back in what is five or so storyboards instantiate your initial window automatically for you question Andy as you don't use segues could you use instantiate initial view controller not identifiers at all and put one so I will profile yeah sure yeah I guess I have tried it by let's see a reason why not yeah sounds good well what's that good but that's possible at least anyway we have to rip out uikit bootstrapping and do ourselves using coordinators and that takes a few steps first up in Maine dot storyboard question from a swiftly tilting planet if using cornets your app flow would use zip files I know some folks do use zips I don't um you know the storyboards annoyingly thanks Apple have some features you only get in storyboards they don't back port them to other things like zips for example things like static table view cells with Apple aren't possible after story what they believe still now it's very annoying thanks apple anyway so the first step into fixing up this thing for coordinators is to go to our storyboard and select this thing here and that controller and scrap it we're doing that by hand instead now the second thing I want to do is go to our project settings friend zone and see down here main interface is set to mink which means when the app wants to boot up itself it will look inside may not storyboard before initial view controller and use that I'm gonna delete main do not use the storyboard to make the do controllers I'm gonna do it all by hand instead we now want to go to app delegate got swift and do that work ourselves create your own coordinator create the initial navigation controller create initial window and show it all these are things to do by hand always before iOS 5 or 6 or so but now it's done for us by storyboards that's removed do it gonna do it by hand again so in here and I don't need property my coordinator is a main coordinator that I should say if using quadrants at a large scale you'll often use protocols and staged bites better ellipses protocols I'm using here it's one concrete class that's class because it's just easier for simple things in did finished rods with options we have to bootstrap our ourselves which means a few things firstly we've got make our first UI navigation controller ourselves secondly we're gonna make our coordinator I'll do coordinate or coordinate or equals our main coordinator with nav controller set to now control it like that and call start on it so it'll create own view controller and get things moving by itself however because we remove the storyboard we now have no window as a type you don't see very often anymore called UI window which returns a window on the thing I suspect iOS 13 or where Apple announced shortly in that four months five months so it's gonna have more UI windows but for now we haven't got one so we have to make that by hand they get fill the screen and use that with our nav controller so I'm gonna say window equals a UI window it takes a frame but is going to be UI screen dot main dot bounce so basically fill the screen it needs a root view controller what to show a fill the screen with of course that is our nav controller we just made previously and finally call Mickey and visible show this thing in there across the board Nicole could be lazy sure I mean you're not saving really anything at this point it's everywhere else it's no optional here it's only it's not me a problem mixing I'm saying it's not real issue this is just in this one place that's being used it's not to worsen anyway at this point I believe that I've screwed something up if I press command R it should now build and run and show the same app and it should look the same ok look a tentacle but it's now being run through the coordinator the court is in control it made that window in May that nav control it made up your controller for us however the navigation tapping from mark into the detail screen this is still being done by the view controller of course this is where Cortez become useful you want let us say head coordinator you figure out the right thing to do now that's the magic of it so in the Kannada Swift we have did select row app course configure and this configure method pretty much shouldn't be there we just want to say hey coordinator please configure this friend somehow we don't care this view controller doesn't care what that actually means it might mean oh I'm on iPad show popover or show in the right hand time a split view controller or I'm in a be test showing alert or whatever we don't really care what it means it's down to the coordinator decide what that thing means and so we want to make sure that all the classes all have you controllers that refer to the coordinator have a property they can say hey coordinator this has happened well hey coordinator I finished and it will do the right thing so in our view controller I'm gonna say week far coordinator is a main coordinator optional now it's always going to be there realistically it has to be there for the thing to work but opticals nice and safe and that thing in here could also go into other view controller friendly controller boom like that they both have a way to talk to their coordinator now in main coordinators start method we make our first view controller at this point we also want to say VC coordinator equals self tell this view controller how can talk back to us when something interesting has happened past that reference back in there so back to leave it work swift this configure friend method this thing here this whole thing really ought not to be in the few controller this is handling configuration and navigation of a different screen entirely I don't want that code in there I'm gonna command X that code cut it to my clipboard get rid of the little space it made and then I'm gonna go to my main coordinator and paste it in here instead an equation from Neil is a good case for a single than that quartets property no it's not really good no singleton having a cords property like this means you can change it on the fly trivially have sub coordinators have you want to very very cleanly or on having ones of singleton coordinator remember there could be a network of coordinators child coordinate is spreading out across the app to handle individual parts of the app if you want to it's not that common but it's at least possible so no it's not really a great case for single on that one anyway I've pasted the configure method taken out of the new controller paste it into the main coordinator instead it isn't quite right though okay there's some bugs in this code because I put it in a different place now first up this nav controller is no longer optional it was optional before because in a view controller it might be there might not been there it is always there in our coordinator to the optionality can go Ruth's question mark second up we have our fancy-pants storyboard protocol now as a result we can ditch nearly all this code we can say just let these C equals select select select delete dot instantiate and delete all that way nicer and this delegate line here pacinator back that's gonna be coordinator so make this friend to controller know who can talk to when something interesting happened so you just self up there now there's a property of a problem here which is this line here line 27 selected friend that is storing the index into an array from the view controller of which friend was chosen when we post dated back saying hey this just friends changed name or change timezone whenever it knows which array element to replace and that there are a few options here we could keep it in the new controller we've put into the detail view controller instead we put into the coordinator a number of ways during this real Stickley the simplest solution in the time we have is to get rid of it out of here and leave that in the main view controller instead so don't even pass in a position property here just call configure for a friend and leave the main view control to handle its own data in a nice clean I excited way I've taken out the division parameter entirely I'm no longer storing that property anywhere in the coordinator isn't needed there at all so now I'm new controller swift ryan is calling configure instead we say hey coordinator you can figure this friend but we shouldn't pass in a position anymore well I'll take that out I'll cut that my clipboard delete position and say selected friend equals paste do it before we put it into the coordinator and it was at one more place did select row to do here we go I hit this one here again cut the clipboard scrap my vision parameter and do select the friend equals that thing instead so now I'm making a coordinator instead it's corporate here what's coordinator or question mark dot should work hopefully boom so now we can hopefully navigate from A to B smoothly using a coordinator yeah there we go so the same result that's happening it's working correctly but now it's going through the coordinator question from Andy Warrick you said earlier about reaching back out from a view controller it kind of is so he's asking is the we're just reaching out to a coordinator rather than reach out to our neighbors controller yes the difference is here there's like a almost like a hierarchy of data we have enough control that sits above a view controller it owns a view controller that is inside it now kind of reaching up into it the coordinator is effectively a delegate we could call it delegate we could have said delegate riling coordinator and the same thing hey lookit something's happened like on table views did select row at act on my Baja please that's more unequal than an owner of that makes sense the relationship is different that's all it is so now we're going from A to B using coordinators which means that we're taking a lot of code out of our viewcontroller and again watch last week to how to get way way more code out of last week and if I could you could apply this call its pattern to last week's project very nicely to make that you can follow even shorter please do love it but now we hit an interesting problem a challenging problem which is how do we get data from here back to here I'm a detail screen back to the main screen so the four would just say hey delegate update friend please now we can't do that because this these view controllers shouldn't have any knowledge of other view controllers as far as they're concerned there are no other view controllers they have no idea there's a sequence of things being displayed in the screen we could change our sequence dynamically later on by let's changing the coordinator that's the point of it it's really really flexible and dynamic and changeable we cannot just say hey pass it back to here anymore at least not cleanly so instead that I've chosen this particularly because I think it shows an interesting problem in coordinators when you have to communicate an A to B but you don't do it directly but a bounce it through the coordinator and I'll show you how that works here so in our friend your controller we still have this delegate property which was our do you control it what you're calling before saying hey then again update this thing when it was chosen and so forth we no longer want that we want to talk to the coordinator and say hey update this please and it'll do the right thing whatever that means in this case it means find the review controller and call update friend on there but elsewhere it might be different it might say oh it's the split view controller that the left-hand one or something else we don't really know it depends on how the correlator wants to behave and that's the magic of these things friend view controller doesn't have to know about all possible layouts of our view controllers that's handled by whatever call as active right now it's much much cleaner way of working anyway I'll go ahead and remove the lid from there then let's look for the update friend which was where's that here yeah so we're calling delegate update friend were instead gonna call coordinator update friend do the right thing into the coordinator and the coordinator at this point knows in this layout the root view controller was our friends who control our original you are sorry and the new view controller with a a friendly controller I said again the coordinator knows the review controller was out you can fold up Smith file and this current one was a friendly controller but of course again iPad might be left and right or page you control or who knows what depends on the cordon is active so we're gonna call update friend on our coordinator in main coordinator here I'll say funk update friend friend and all that do is find our root view controller make sure it's the right type and call the method on there instead basically relaying the message indirectly because again it might vary in different layouts so I'll say guard let VC equals nav controller got the controllers dot first our top view controller as our view controller class else return so this happened now in theory this shouldn't happen but as I'm being safe here if that works we now say ABC to update update with friend to pass things back and forward correctly that should work so it's relaying the message now again the point of this is we can change coordinators on the fly there's a property in our view controller here we could say this is now an iPad coordinator or an a/b test group to coordinator it'll behave differently and friend view controller doesn't have to know anything about that it says hey other a friend please all that has happened or whatever I finished my work you figure out and the coordinator owned all the navigation flow so in theory press command aa that made some common mistakes I can go to mark here and I changed mark and I say it's now kristaps and then press back boom it goes back cleanly and smoothly and again we've got this wonderful isolation no viewcontroller knows about any other view controller again for more advanced projects you're unlikely to use a concrete type here like main coordinator and have something like login coordinator as a protocol they can talk things no matter what the coordinator is so you can change coordinator freely other kinds coordinator on the fly I actually have an arc like this talking about using protocol composition to say escapable and result of all and scorable whatever you want to as a multiple protocols in one is very very nice way of doing it in this particular case the quartet and methods are so simple you could also use closures and that's covered in the same article on the happiness if comm slash articles okay we've gone way over time that's like an hour and 48 minutes plus the intro I would love to show you more there's so much more I could do with this you know really you want to have a button up here showing the current time I will choose that you can choose the reference time it shows a custom time in there right showing the current time and and similar but it's your project now go ahead and customize it all you want to if you have questions about the project or what other things now is your chance we have gone way over I apologize my goal is ninety minutes of the maximum so we've gone a bit over that hopefully be faster next time I'd try and go as fast I possibly could by the way but even then it was too fast though anyway if questioners would go ahead and ask I will happily answer Josh yeah you are most welcome I enjoy doing these things they were they're real exciting time life codings fun right who knows what comedy mistakes you will see live on YouTube I think I made nuns I make no bad mistakes I think this time like a few typos here and there but no actual fundamental screw-ups which I'm quite pleased about and well well you know your mission now Manuel right you can go ahead and edit your project to reuse those you know date format isn't similar because you know you don't want out getting those again and again and again you want to reuse them if you can particularly the sales you know fast scrolling stuff you run that through instruments you might find all sorts of I see use are being made handle dates the real real problem areas performance that one Robert by rehearsing yes I absolutely do rehearse me at a time I go through it once beforehand just to make sure it's all sensible in my head otherwise it'd be a disaster it would be a real problem only because you know I know I get to the point when I've typed at me and I'm like ah that was a bad idea and then we factory factory factory factory factor I'd rather show vaguely sensibly correct where I've reacted ahead of time otherwise I'll just confuse you folks even more which of course you wouldn't want Lord Waterwalker anyone know how long the video this live stream is up I guess in immediately when I press stop I think in about 20 seconds it'll be up on the stream very quickly so yes you will see it shortly on the site but they subscribe you know I publish Xcode tips right now they're very nice I publish my Swift videos on here which a bit longer more in-depth tutorials on there check it out so you think any questions or am I done I can go and relax roll off time though you are most welcome I enjoy it it is fun it keeps you on my toes talking quickly for almost two hours it really makes my brain buzz Richard low where is the it been calling the VCS so the the Dean it will not be called on the group you control ever it's there as a review of your controller even when it's hidden it's still there does not get destroyed the child one will get called well its fleet that disappeared it where it's actually gone to screen completely it'll be the answer at that point Roberts there isn't really anything offered in the slack Channel it's just a chance to ask folks questions if you have any I hang around there hair tutorial problem or your questions by all means ping me there I thought it's for I'll tweet the link if you follow me on Twitter I am two straws on Twitter I was happy to Here I am two straws what calm / two straws there you go I'll tweet it there and that way you can follow me and I'll to be the link of the stack channel again if you want to see it Mitch yes it is now something I use all the time this is a toy project like this card there's just a small project I would not have used cortex here personally there's too small to work with but if you look at my unwrapped project github.com / - straw ash unwrapped that uses called ethical law all over there you'll see that it's really really nice and it's interesting because a year ago I wouldn't said that it took me a while eating - I was more into sort of childhood controllers which is a very nice approach - I like using childhood controllers I like it a lot but I found that coordinate has helped me contract my flow more clearly and then nice - because there's no more you could fall a mess everywhere because that's because a problematic as you know how surely utmost welcome glad you liked it well yes please these quarters I do love using the man check out Suroosh conlou he's the person who pioneered the one iOS and lovely he writes a great blog - it's interesting watching blog posts being written around the internet then a very interesting very useful a very cool but are effectively the same thing sue said two three four years ago on his home clock but folks don't read it for some reason no we're not enough folks read his blog you've gotta go to the source of read his stuff first cuz he published his stuff often years ahead of the pack he's a really brilliant thought leader and actually I'm seeing him next weeks and he's in Singapore with me next week so I'll see him then and hopefully hang out he's a very nice guy how well question Miko how to handle the case will login cornet as a logging in state I wouldn't call no your call start exactly once so with a lot in coordinates you can have a main coordinator like your route coordinator which says okay I launch the app I've checked my stapes you as user is not logged in create a child coordinator call start on that it takes over from that point there's a login state it's all inside the login coordinator and when it finishes when it's finished doing its work I'm you know I have now authenticated or given up or guest whatever the options you might have are it calls per corner saying I finished now what's next because and that gets destroyed it goes away you don't have to have that one address the app it just handles that one thing there Thank You mr. bomb head your time zones GMT 14400 which code my math is due by uh spoiler he taught me earlier Andy Warrick testing office pretty good I do like testing Swift I do like it's a good book yes go and read that and processed good too well they're all good you know actually I think Pro Swift's my favorite I think personally then Swift design patterns and then testing Swift in that order his eye patterns I rank highly for that's quite personal book I actually include that anecdotes of jobs I was doing in there which I don't normally do my books try and keep me quite white box quite abstract in that respect I've mentioned me personally too much but I give examples and they're saying I hit this problem and I did this with the solution so you can see this is a real thing people do use and real-world situations do you now did not get notifications oh sorry I don't not to do if you subscribe and your Bell thing is turned on and you follow me on Twitter that's the most I can possibly do to warn you oh come on the slack as well no tweet the slack thing shortly I mention the slack st. psychic now hopefully between those multiple messaging things you will get a notification or I'm sure that's a way you can say something like an Twitter app notify me when Paul tweets I have to meet a lot mind you so be not that how do you test coordinators so it's problematic and I do actually put that interesting Swift kristaps hangers call engines because it is problematic and the nice thing about them is when you have protocols of course you can do dependency injection we replaced that with some test struct whether you want to that is in there instead they're capturing messages so you could say have a mock or spy in there instead saying yes I attempt a trigger showing this thing as unit test as an integration test make you always use UI testing if you wanted to use a UI test saying was this thing fully shown was the screen at the end of it as an integration test but I'd rather not I'd rather replace the coordinator in my test with a mock just to check it was being triggered correctly that's how I'd personally do it Pablo our core data suitable for any app no they're not they're really not and it's interesting that I don't think enough folks talk about this it's like mvvm mvvm you know the crater mvvm said it's a great way of making apps it is overkill the simple apps and it's identical for coordinators I'm making this app here I would have been a simple delegate protocol and coordinate back that way rather than having a coordinator like this I only do exercise I do on Twitter right so I would recommend this first small project like this but for larger ones yeah absolutely I use them immediately I've even thinking about it what I recommend for mid slash seniors with legacy a bit of C code why don't know from your message Lord Waterwalker is whether you are currently proficient in objective-c if you are not I have a book called Objective C for Swift developers which is kind of what hasn't the title did you let me see in a quick and easy way relating it back to Swift so here's thing and Swift here is great to see again again again so you can map your learning across quickly the bigger problem they're gonna face is that if you have literacy and Swift side by side is be able to be good at both it's very very hard because you want to be able to write great code of it at sea and then write great new code in Swift and that's challenging a lot of folks will write swift code as if it were objective-c code and that's the worst kind of Swift and I was absolutely guilty of that when I first started being Swift I just said you know we you know this array definitely contains strings cuz it has to because it did it just does I know it does the compliant at the time wasn't enforcing it but we knew it did so is safe I do the same thing all time Swift I would happily force unwrap everything and after a year or so I became sort of like ultimately swifty unwrapped nothing force unwrap nothing's around I'm not think carefully and now a more nuanced I know this one is safety force unwrap it does not make sense not to force unwrap it and similar so it's an evolution for that particular case though lord Waterwalker you are looking for pro swift it's booked with like six hours of videos attached to it that walks you through real idiomatic ie swifty swift how to write a natural swift language code next question harshly upper tail am I plan to hold enemies in New York no yeah me V get me Yuki you give me yeah sounds sounds like a yo-yo anyway plus ultra I'm guessing anyway you now that if you want to if you clone it you can continue changes back to me which is probably very very welcome I love having countries into my projects please please do by the way I do have a translations project so if you want to help translate happiness rift into other languages you can do that all on github that github.com slash two straws lash hws translation you're gonna so hi um do you have any books would also teach iOS in a more theoretical way what really cuz you have to I mean you can't teach theory for practical things I mean you could teach theory of Swift like no projects like you know Pro Swift has no project right it's all about just swift code what it's like nav controllers or buttons or page view controllers whatever you want to stack views it's a little bit tedious it's the basically comes in manual doesn't a documentation you actually want to say let's use this thing in practice because it helps you remember exactly what it's trying to do yet in mangani have you worked in a company as I have I wouldn't come pannier work for a number of companies we had clients all over the world and it was fun I enjoyed what good clients I work with with UBS I've worked with Apple I've worked with Verizon I've worked with Autodesk I work with fender with Tesco my favorite one my favorites too fair was Peppa Pig a UK cartoon which my littlest child loves so anyway I got to make help them make iPad Peppa Pig which was great fun anyway oh yes sorry she gets to 88 you're plus ultra nevermind which other gnome identifiers are there so we mean from time zones that's all of them I think we literally use the system's big dump of them all as opposed to just like plucking out careful ones we use them all so I should be all of them right there that she go to 88 plus ultra yes please this project is now yours upload to github whoever you want if you would be so kind as link back to my site I'd be helpful the right kind of view it's not required it's your code now but it'd be very nice of you so the reference manual things still going on it is basically developer.apple.com that's what it's there for it's a it serve as a reference guide to uikit and if you want to have a cookbook style of stuff how do I do this how do I do that with stack views or nav control and so forth that is what my knowledge base is for so do you go to hacking rusev calm slash example - code you'll come to the Swift knowledge base you can choose to think UIKit there and you will see lots of UI kit code snippets like hundreds of them all there to weed through Benjamin I try using Cornett as an app with Knapp controllers and what a power controller I see so I haven't done that I have had an app with tab bars and I have one coordinates at per tablet as a main coordinator which create a power controller but on the screen and so forth and there is a individual coordinators for each tab bar controller each tab bar item sorry they pushed some pop inside it's personal nav controller but I've never actually done it I think what you're saying is you have a UI that starts as a nav controller and then becomes a tab bar controller I haven't done that before I even coded that before nevermind use according to that before nicely done that full stop or afraid I can't really help you too much there any more questions or are we done I can see your Twitter with a slight lag with a chat but it looks pretty quiet we'll assume that all happy more or less anyway you know where to find me I'm on Twitter I'm on the slack I will tweet the slack link shortly on as a reminder by all means ask questions on the slack email me i'm paul at hacking reserve calm you can tweet me at two straws I don't really mind I talk to me I am open the question is freely tell you about coordinators who is my favorite developer I've got favorite developers be happy taking sides but a number of people developers I think underappreciated favorite developer is Erica sidin Erica would never say us herself she would never ever say this herself but she's the closest we have to a thought leader in Swift and that's not an insult I'm in a nice way you know she has written more Swift evolution proposals than anybody else including all of a swift core team who work at Apple she is responsible for really driving the language forward some of her books have changed our industry her classic iOS cookbook things you'll still see code from there in apps today some of our blog posts or remarkably topical and interesting and useful but she's really humble about it you really wrote herself as remarked it herself but she's absolutely wonderful and it's a goal for me one day to at least meet her and shake her hand as a great inspiring developer for me okay brilliant thank you very much by all means follow me on Twitter tweet my Twitter took me on slack email me I'd love to hear from you subscribe to the channel of course thank you very much coming thank you for all the questions have been lovely happening having you all here take care and I'll see you in two weeks because next week I'm in Singapore at iOS conf SG and in two weeks we'll make a another project from scratch take care
Info
Channel: Paul Hudson
Views: 20,055
Rating: undefined out of 5
Keywords: xcode, swift, coordinators, coordinator, design, pattern, navigation
Id: p9fSsoHcLTg
Channel Id: undefined
Length: 127min 14sec (7634 seconds)
Published: Sun Jan 13 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.