What's new in SwiftUI for iOS 15?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey folks uh my name is paul and i'm keen to talk to you about what's changing ios 15 for swift ui uh i'm sorry i'm a bit late i had to reboot my machine because xcode and the simulator is continually having problems with sound on my mac uh and it now happens also in uh the canvas window which is brilliant so um hopefully you're seeing this and hearing this with no actual problems um because honestly this could sound could go wrong at any point because that's just how xcode rolls apparently if you do hear sound problems let me know and i'll do my best to correct it otherwise we can just kind of fly on and start investigating all things that have changed along the way uh i am reading the comments on my screen so if you do hit uh sound problems let me know and i can try and we start the stream i guess and hope for the best otherwise that's kinda see how we get on um and uh yeah it's it's potluck it's gonna catch fire at some point we'll see that's just because it's all xcode uh beta1 uh i'm gonna get the bad luck out of the way now by asking my mac to build and launch the simulator with just hello world and if it's gonna go wrong this is where it's gonna go wrong so i'll press command r and let it do its thing launching simulator and if it's gonna catch fire it'll be when it's doing this so hopefully uh we'll see uh i had to restart xcode and restart my entire mac to clear the sound problems and i don't know why and it seems to have the the plague seems to have spread it used to be a simulator only and now it seems like a plus xcode canvas um which is great yeah thanks for that apple anyway uh it's beta one it's gonna get better i'm sure um i should say uh while it's catching fire on my screen right now uh apple have launched a huge amount of stuff today massive new apis ios 15 mac os 12 and similar there's stacks of music you guys have to try out out there and uh i hope you're all feeling excited you're all feeling good you're all feeling great this has been a very positive update for apple so hopefully you are grateful to the uh apple teams who worked so very very hard over the last year mostly from home to build this stuff for us so uh actually last year sms 50y team came to this live stream last year uh sort of slightly lurking in the corner and uh if that's you if you are here right now 50y team much love you worked so hard thank you so much uh you've done a great job anyway no one is screaming about bad audio in the chat window so i'm going to assume the audio is still okay but i can plow onwards and kind of hope for the best um so anyway oh oscar asked am i on monterey no i am not a monterey i i don't want things to catch fire that badly okay so a number of things have changed after ui this year i want to try and fly through as many as i can in this stream if you have questions or discoveries of your own want to write corrections what i'm doing as i go let me know i'm figuring things out too like you so let's explore together um there's a number of small things are enabled by swift 5.5 which is a huge huge huge release go and check out uh swift 5.5 what's new on my site because there's stacks of example code there um but it's a lot of little things for example um if you're sick of typing very very long names to get your styles of stuff that's been really shortened down thanks to the way so 5.5 works for example if i had a list of stuff let's say a list of the numbers uh 1 251 coming number coming in let's just do that and do text uh let's do zero like that if this is a sidebar list style you might have said previously uh list style here is going to be this style sidebar list style or rounded button this style and similar and now actually you can just say list style dot sidebar and save yourself so much typing similarly you know inset insect groot plain and similar they're all there waiting for us in a much much shorter way and this applies anywhere where you would have used those very long old style titles for example uh if you wanted to say uh make a a text field with a rounded border effect you might have said something like um at state private var name is tim obviously tim's great name i had something like a v stack alignment of leading then text field enter your name with text bound to dollar text again before you've had text field style rounded border text field style like that and it was all very repetitive uh swift 5.5 was away with that you can just how to say round border which is so much nicer and it was like that in the original swift ui beta for like 2019 and it was removed swiftly sorry removed quickly because it took a lot of hack to make it happen and now it's built into swift directly to work correctly which is great actually in this case you can see i've got text field rounded border which is great we can also now say i want to have a submit label as well and that's to control the way the done button looks because before it's always you know return i think it was and now you can say submit label something else join next return so continue done go or root or send and it just changes the way the button looks and that's you know ui kit 2 i want to say um but it's now in 50y3 that's the main thing we can now use it everywhere and have let's do uh let's do join like that and it works much much nicer okay that's little api sorry dogs have come in um that's little api cleanup which is great there's other things for example you can now have um a hash if a post fixed expressions remember expressions even sorry um you could say something like you know i want to have yes i do see you dog it's it's like what is it in the uk 3 45 in the morning in the uk you should be in bed um so you can do things for example like come on quick shot there you go i've got off to bed you could say things you know with a hash if os is ios then do something otherwise don't and that's again a swift 5.5 feature uh it was matt rickettson and someone else put that through episode 5.5 and it's just a nicer way of customizing the way your code works different os and and other platform operations like that right clear off go on the text should be named yes sorry there you go um there's a nicer way of doing platform customizations and other similar kinds of thing with a compiler which is great okay that's the easy stuff let's look at some more interesting stuff for example uh let's say we want to have a list of content doing stuff and this is a standard thing you want to have a list of information and you want to pull to refresh and see more information again it's been built into uak for a long time but now it's available in swift ui as well with the refreshable modifier so you can now say this list here is refreshable and swift ui will automatically take care of pull to refresh call a function of your choosing waiting for that function to complete and then hiding the refresh indicator it works really really nicely and so in a really trivial example you might say there's a navigation view here and i'll do a list of you know one to a hundred with a row coming in and then text uh row is row like that and then attach the new refreshable modifier here and say this thing should be refreshed and when it is refreshed hello other dog um sorry two dogs two treats two straws come on quick come on no you had a treat already clear off you had one already hungry dogs um when this refreshed now let's just do print uh do your refresh work here like that and now when you pull down to refresh it will correctly show a spinner and then hide it away again i'll try and run it back on the simulator let's press my audio chances slightly higher and i put refresh there we go there's a spinner and there's my thing being triggered and it only triggers when you do pull far enough like that now obviously in practice you're going to want to do actual work here this is a great place to do networking for example to fetch information and helpfully refreshable uses another new swift 5.5 feature which is async await you can go ahead and call asynchronous functions here or wait for them to return and then use that value somehow so for example we might say i want to go and fetch information from the web some json from a server somewhere parse it and put it onto the screen and we can walk through a working example of that here we can say something like um let's say there's a news item which is decodable so it can come from json and identifiable so we can loop over into the ui land this thing has an id integer and a title string upstairs string and a strap string some description below it and then we could say inside our content view there is one built-in news item i'll say at state private var news is an array of news items with uh let's do id 0 title uh want the latest news want the latest news question mark and then strap pull to refresh so one sort of built-in uh news item want to work with like that and then what we want to say really is inside our list go over and show all those news items one by one in the rows of data so i might say uh go over our news here list of news bring one item in each time and lay that out somehow on the screen for example i might say that is item in i might say there's a v stack with alignment of leading let's show the items title using font headline then we'll do below that text item.strap with foreground color secondary like that so we're showing the news information that was loaded from the web somehow now obviously we want to do is aside this refreshable modifier do the actual work of fetching json from the web decoding it somehow and showing it in our news array and async await makes this beautiful because of course it's here and refreshable it's also in foundation which means url session supports already so we can actually say something like this a do block to catch any kind of error uh first things let's make our url we're going to fetch now i've got one of these already i'll do let url is a url with a string let's get this right https colon samples slash news dash one dot jason i'll happily force unwrap that that's my uh little uh example jason euro i think that should be some valid json all being well isn't this is not going to work very well uh that's my data my url there i can then load that into some data and optionally a response as well but i don't care the response here so i'll ditch your response so i'll say let data underscore don't care at response equals this is the new syntax here try a wait try waiting for some work to happen what work well urlsession.shared.datatask and we want the new option here data task from a url and just pass that in with no delegate it'll go off fetch it back for you and say here's your data here's the response if it throws any errors then you can catch it down here uh whoops something went wrong what do you want to do in our case we might just say you know make news and empty array for example so at this point it has asynchronously gone ahead and fetched the data for us and downloaded it and we can now go ahead and decode it we could say uh news is try json decoder decode dot decode an array of news item dot self uh from that data like that oh kirk clifton's here kurt was i think i don't hurt anybody's feelings here my favorite speaker from wwdc20 um he was he was so happy to be there and he was great on the screen and i'm really great to see him work so well um so yes kurt is saying that i may need to decorate items in my list with id something rather down the way and i'm getting suggesting something like dot id here with item.id like that i'm guessing that's what he means if not cut by all means please correct me and let's see that's gonna work let's find out um i'll go ahead and uh give that a try it seems to build let's find out it works correctly have i muffed up the uh uh jason decoding it along the way pulls refresh it's thinking oh worked first time brilliant so we can get pull to refresh fetching things by a url session bang out of the box it works brilliantly uh so it's just it's so so nice we're going to worry about you know hide the spinner show the spinner that's all handled for us it'll go away automatically where we have our weight call here when this work here finishes fine it'll then go ahead and hide the spinner force automatically it's really really nice okay so we get pull to refresh but we also get another really highly requested feature which is an equivalent to ui search bar this works really nicely because there's another new simple modifier to work with let me go ahead and uh clear up our code here a little bit i want to end up with a lot of mess in our code um let's get rid of all this guff boom okay uh there's a new modifier called searchable and this lets us place a search bar directly into a navigation view somehow and watch its text or provide suggestions and more it's really really nice and super simple in its easiest form actually in its simplest form you can just go ahead and say search for some kind of text and there's no there's no list required here nothing else just show me a search bar and i'll do the rest whatever happens to be so you might say uh there is an at state private var search text is an empty string then in our navigation view we'll do uh text let's do searching for search text oops crazy that back there we go search text and then we'll do searchable and this thing wants to know what to bind its text string to we'll use dollar search text which means as they type into the search bar equivalent what they call it and nowadays update that search text property without value now let's have our navigation title below navigation title below saying searchable example like that and we're going to get a ui search bar equivalent out of the box it works really really nicely for these simple use cases so hopefully see here boom there's search box good type of stuff hello world great so it works brilliantly for simple examples but there's actually obviously lots more you know if you want to have a list of stuff happening here for example you might say i want to have a list of names let's do let names is an array of who spoke today holly spoke today and uh rondo she was great doing xcode uh xcode in the cloud let's go cloud let's go plus where they call these days and uh ted was there of course ted was good too he didn't get teleport mind you it's a real shame um so we have a list of names to work through and we can now say i want to show those names in a list somehow and i may have to actually just fire up uh the uh the uh studio for youtube and watch out people being idiots on the thing actually the button right you can press bam brilliant there's a brand button right there in this button on my screen you can't see which i can see in ecam live cool even better tarab spencer mckee anyway um where i was like oh yes lists of stuff we make lists of stuff we could say i want to have a list of stuff let's do uh a list and inside our list i want to have the names we're showing on the screen filtered somehow so i might say something like um give me the search results as an array of strings and if our search text is empty we haven't searched anything in our text will return names and then upstream if it's not empty we'll return names dot filter where each item contains their search text so we can filter that names array somehow by just typing you know h o n to get ronda for example does it contain the search text case intensity could do of course but you get the idea you can do a search however you want to now inside our list we want to go over those values somehow and say something like for each of those search results identifying by self give me a name coming in and i'll say that the navigation link with destination of text that name oops crazy there we go and text name so it should in theory show us holly ronda ted and tapping one of those will show a detailed screen with holly or ronda or ted pranav what's your typing speed i've got no idea uh bad i'm trying to talk and stream at the same time sorry i apologize for the hilarious typos i'm trying to think and talk uh and stuff anyways there you go ronda and ted and similar are all there which is great but of course what we really want to do is have a way to search through these things to find examples of information so we might say that our list has a searchable binding the text bound to search text like last time and a navigation title of contacts so now we're going to search on that search text field and as that changes it will refresh search results automatically and match the ones we care about if i just pull down a little bit there we go boom so i can now search for h o oh our capital h will have thanks for that let's sift ui so h o l h o l there we go so it doesn't work correctly so you get filtering really nice and quickly which is fantastic uh and i saw by default you get that sort of ios default behavior of the search thing scrolling around with the uh bar automatically so it'll go away and the lib sort of pull down a little bit from the top it behaves just like a natural ios ui search bar presumably is not message ui i haven't checked but it probably is kurt is it one find out later on anyway um for more advanced uses you can actually ask this thing to provide suggestions as well you could say here are things i think should match somehow and if you want to provide completions for those search things as well um to save them typing the rest of holly's name for example even though it's only um five letters in this case um and this is done by passing a function into searchable as other parameter that will return some kind of view full of your suggestions whatever you want to do and then if you want to you can then say each one of these things has a search completion so tapping on it will complete the search automatically and so we already have our names hollywood ted we already have our list i'm going to modify our searchable text modifier here so that we loop over our search results and for each one of these things we'll say are you looking for holly are you looking for rondo looking for ted as they type and we'll make a complete that name so i can just press from one to see holly immediately that's a slightly faster way of working obviously the names are quite short here but obviously for longer stuff with more complex matching then you get the idea so i'll say for each search results again with id of backslash dot self i'll do result in we'll do text are you looking for and then that search result so i'm looking for holly i'm looking for ted i look for ronda and similar but i'm also going to add to this the search completion of the name i want to complete when it's tapped i want to complete this thing with uh their name so i'll just do result uh kurt's saying there's been a great talk on this tomorrow by harry lane who's harry lane i've met harry lane before anyway i've met everybody of course um it works on all platforms yes love it in fact there's more of that later on the way action sheets and alerts been redesigned work much nicer now other platforms and stuff anyway i'll press command r let's find out and let's see if we can do a little a little completion of stuff here so i'll just sort of pull down and type uh there we go my conditions are there i'll do h and now it's just holly there press on that one and it completes holly for me so it's completing the search thing automatically and giving the results i had before so it's a really nice really simple way to do a searching system it's a ui search controller just dramatically simplified with all the same power too so it's great i'm actually looking forward to this if this works well on mac os i haven't tried it yet but this was really really hard to do on mac os before apple's sample code for this was nightmarishly complex so uh yeah i'm looking forward to seeing if that works beautifully in mac os there are more changes to the list lots of good new things with list for example you can now say oh i've got two dislikes i'm doing my best folks i'm trying my best it's like two minutes past eight on on keynote day thanks for the dislikes anyway um there's a new way where you can finally add swipe actions to your distros to control which buttons appear on those rows you can have more than one if you want to color them uh put them left and right if you want to it's really really flexible for example let's do a simple one first i'll say that we have uh a list again let's get researchable entirely let's give all this chunk up here goodbye and let's do hey thanks for the bonus likes folks can offset the dislikes a little bit thank you so much best pals anyway there's title let's do swipe actions and then kill all the stuff three dislikes yeah that's all right some folks do find me annoying and that's just life and i had someone at ios deaf happy hour last time say to my face i find your voice annoying like cool cool dude i don't come around to your house and have a go at you at your workplace do i anyway um let's focus on the job at hand here search results how do let's get rid of the stuff here it's all junk let's put in some static examples here of uh rose in our list i might say there's a pepperoni pizza and then below it i will do pizza with pineapple like that now i want to have a swipe action for this row here so i'll just do the new swipe actions modifier like this and i'll say there's a button called order and when that's done i'm going to print awesome and i'll tint this thing in green so it's nice and obvious it's a good thing to want to have piece with pineapple i'm going to say it has swipe actions and this time my button's going to be burn and then print right on and then did that in red no one wants that anyway we have now added two swipe actions to these static uh list things here so i'll press command r to build and run my code and see how this looks so i can swipe here and there's order and swipe here to get burn and it works brilliantly i mean it's really really raised to do and in fact you'll see uh you can even go away across the trigger the whole action immediately by sort of a long swipe but that's a default behavior um i would say um these things use the built-in buttons now from swifty y and that occurs in other places too and so in the case of burn the pizza with pineapple for example um i should say that's my eldest daughter's favorite pizza so i can't complain too much um in the case of that one while i'm just doing a tint in red what you can do instead is uh say button burn and then do the role is destructive and give swifty why the extra context here of what your button's trying to do and let it take care of it appropriately i'll press command r under that i selected a destroying kind of button and we still get it in red because it knows what that means so we're giving it the extra context you'll see this in other places too as we progress through the api changes it's a good way to tell 50 why what this button is trying to do and you can also say there's a role for cancel as well for example do you want that kind of thing anyway as you've seen you can swipe all the way across to trigger the action immediately you won't always want that because sometimes it's dangerous right for example the messages app for your device you can't just delete people by accident you've got to sort of swipe across then tap the button and you can also have of course more than one button in there potentially on either side so you can really stack it up as much as you want to so let's work through an example of this i will say that i have a array of friends and i'll say that is antoine there's baz there's kurt there is dave and there's erica and uh in our list down here uh we're gonna go ahead and loop over all these friends and we'll say there's a for each friends using id of backslash dot self with a friend coming in inside here i'll just show the friend's name text friend then attach swipe action to this i'm gonna say allows a full swipe is false do not trigger this with the swiping all the way across otherwise i can do things by accident and inside here i might say i want a button which is going to print muting this conversation and the label for that's going to be a label with mute and system image uh let's write bell dot slash dot fill i think and then i'll tip that in indigo beautiful new color and then we'll have another button inside the same swipe action this time with the role of destructive so it's quite clear it's a bad thing and i will say deleting this conversation label will be delete this time and we'll do trash.fill so i've got two things here and it's complaining as it allows for swine sorry planing tiny typo so easily fixed i'll press command r and build and run it see how it looks we should now get all our friends here i'm going to swipe across and see both our controls let's make one of these have a different color because it is destructive don't be indigo destructive please it's a bad idea let's try again see if it's better there we go and i can no longer swipe all the way across and get uh delete or accidental action it's a bad idea having that so that works better so you can see swipe actions work brilliantly and you'd also see that swifty y is being clever here it understands the context of this button it's a bad idea to have delete or mute right there in the ui and so basically switched across an icon only label style showing just bell slash fill and trash fill automatically so it's reading the context for us which is really really nice i believe it will still use the labels uh text for voiceover so it will say mute and delete correctly which is what we want really uh if you want to of course you can uh uh have swipe action on both sides you know go one way for one thing otherwise the other thing for example and so we could make like a little numpty calculator we could say something like private var total is zero and then in our code down here will go away i'm going to say there's a four h here counting over uh 1 to 100 with a number coming in and inside here i'll place a text of that number with a swipe action and this one's going to have an edge of dot leading so left edge and left right language like english or right age and right left languages so for leading one i'll say button total plus equals i add that to our total with the label of label add i and the system image of plus.circle you want to say i think it is and then i want to have on the trading side as well so just do another swipe action same modifier have two back to back one leading one trailing i will subtract that time around i'll have uh subtract i and i'll do not plus the circle but minus dot circle and theory i can add that to our title somewhere let's do total is total and we've got ourselves not quite james thompson threatening but a calculator nonetheless let's find out so here's one i can swipe that way at four subtract six at eight i had ten subtract whatever that was seven um so yeah there you go an instant calculator in a really really simple way next stop add you know exploding bananas just like uh james would do okay so lists had a lovely upgrade lists are much much more nice on uh ios now i'm sure also on mac os and other platforms too sorely missed feature that has come now to swifty y is an equivalent for ui visual effect view and this is just brilliant it's just brilliant i mean there's so many brilliant things this year around i get that this is particularly good because uh ui visual effect view took a bit of futzing around get right make it exactly right so if the ui carriage goes nope let's make this much much simpler and it raises nearly all the api you use z-stack or z-stack if you happen to be cut um backed up by the background modifier we all know and love and it'll do most of the work for us because there's a new set of materials we can apply to control the way our background and our overlay stuff interact it's really really nice anyway let's go and give it a try let's say i want to have get rid of all this junk goodbye goodbye i already have a picture by the way in my asset catalogue of singapore this is taken in changi airport up here it is um of their amazing monorail indoor rain system thing anyway um we can say there's a zed stack with that image of singapore in there singapore even hudson come on uh and inside there will be the text of visit singapore and i'll put some padding around that now i really want this thing to appear against the zed stack in a nice clear way uh so i'll press play on this and we'll see how it looks and right now it'll be pretty hard to read because that's just my life boom you can barely see that it's useless um fortunately we can now say after applying padding i want to add a background background using the regular material look at that let's uh example this here that's somewhat translucent love it death pubs have worked really really hard this year i am so happy for them they've worked really really hard it's great anyway boom we now get uh the natural dimming of our content it's overlaying correctly a little bit of glass effect behind it you can now say i want to have maybe um thin material or ultra thin material to adjust the way the amount of effect it goes on there how much you can see through it so it's like even more visible now more of a green color coming through you could do let's do ultra thin material so it's even thinner material so get much more content coming through there we go so get a lovely glass effect going there um hey someone here from singapore um singapore's lovely it's this place this place is like standing for a star trek it's just amazing this whole airport is astonishing anyway um there's there's a whole set five to choose from ultra thin thin regular thick and ultra thick depending uh how much you want to shine through i think by default that's black basically black text i think if you were to say um i want to have a foreground color around color even of secondary you get some translucent scenes and vibrancy coming through as well um so the text kind of pops out a little bit like that so the text also has a bit of the color coming through it looks really really nice and so it's it's super simple if you use visual effect view and you like it it's much much harder um than this so you know again round of applause shift uit you did an amazing chef's kiss job well done okay but you ain't seen nothing yet because uh like almost day one of stuffed ui i said why can't it do this thing and now it can and it's brilliant because in ios 15 50 y now has a dedicated async image which will load an image from a url on a server somewhere and display it you know when it loads and its simplest form you would just say async image with a url i'll just do daisy url of string i hope you won't get this wrong too much https card slash slash demo dub or hacking with swift.com slash img slash pull.ping of me let's find out if that works let's find out did i screw it up already no boom there we go um why using ipod touch i don't know it's it's just a default option in xcode and it doesn't really matter that it works in all these devices okay there's some things you have to know about using async image because first up i'm really glad they did this um it takes an optional url so you haven't got to put you know force unwrap your url here that would have been so ugly to have if you have a bad url it'll just show a placeholder for you automatically you probably saw it as loading it's really quite brief you see this sort of gray box appear it's very light it is there and that loads in and how well that appears in the stream um but you see a gray box while it's loading that's what you'd see if you have a bad url that grey box wouldn't go away to say that entire time similarly for a good url but you know user is offline or the image doesn't exist or you know errors that gray box will also stay that's the placeholder for your image appearing and so that's what's gonna appear now um if you think about it it makes sense that swift ui has no idea how big that pitch is going to be it doesn't know happens to be that sort of square picture of me in uh it's paris speaking on stage check me out um it's me speaking on stage in paris and uh it doesn't know it's that big and so what happens is it allocates all the space it's got this flexible uh width and height it'll grow to fill all available space which is not ideal and so uh it'll jump around as it loads and you can cast this in action if you said something like um i want a v-stack with my async image and then text hello world below that um you'll see it jump around a little bit now so hello world it loads and boom hello world moves up to the middle because it now knows the correct size of the picture uh brett asks can you have a custom placeholder yes you can right i'll show you in a second give me a chance anyway so you can see it's jumping around because it doesn't understand how big the picture is going to be now you might think oh that's all right that's easy i will just attach a frame to my ac image i'll say this thing has a frame width of i know 128 height 128 and i mean it kind of works it might be vaguely what you want but it's probably not really what you want um and so you can see it works correctly there because the size is about what i expect to be but if i'd forced a size of 64 for example so let's say the exact size is smaller than the image is going to be it'll look fine when it's loading and jump in too big because we've set the frame for the acing image not for the resulting image it's going to load and so uh you really want to control that and you can do this by passing extra functions in you can say actually when the image is loaded here's what you should do with it and also here's my custom placeholder whatever you want that to be for example we might say that our async image here loads my url like last time but when the image comes in here's what i want to do and this thing here this is the real swifty y image not async image the actual original image loaded ready for us to work with i could say use image dot resizable make it scale up and down correctly for display there is no resizable uh modifier on async image only on images directly i could then say i want a placeholder and this whatever you want to be i could say you know color.red just show the color red and then make that whole thing now fit a frame of my choosing i'll do with 128 height 128 and then you know uh clip it somehow clip shape with rounded rectangle corner radius 25 so we're now having a custom placeholder of red which is there boom and making our image and size resize correctly as much as we want to it'll adapt because it's resizable so what matters now is we're giving instructions to the async image here's how to display your frame and your clip shape but also the resulting swift ui image gets loaded as well that should be resizable to fit inside the async image as well so now i'll say be smaller actually also work just as well like that which didn't work before you see because you couldn't do that by default it'll just occupy its natural space now if you want to know this if you have happen to have extra information um by default ac image assumes your images are 1x scale so you know iphone from a decade ago quite frankly um if you happen to know i've got 1x 2x 3x assets and you're loading the 3x to your device whatever you want to you can pass that in you could say load this url at a scale of three for example for your retina hd displays okay ac image works and it's a lovely lovely improvement for swift ui what's out of the box it's brilliant but there's another helpful i mean this people are going to cry when they see this there's another helpful change that was really really hard to do before you probably couldn't do it to you i had to dig down to uak it before and now it's native inside swift ui which is and i sound bad i say bad saying this because it sounds obvious it's dismissing the keyboard folks and also controlling the way you move around the focus of text fields because this used to be possible in in uh swifty ui for 14 and 13 only by calling down to uh ui kit and saying you know force resign the first responder for the whole application and now it's so much nicer i mean it's beautiful the change they've made it's bringing across the tvos stuff and this works really well if you're having you know number pad with no obvious dismiss button to get rid of the keyboard now you can it works really well and so this is done by firstly saying here's my focus state this might be simple as a boolean we can do customs if you want to and when it's true focus my thing but it's not unfocus it and of course unfocused will also hide the keyboard because there's no requirement for any more and so uh you can let's start something real simple i'm going to say we have uh some text private private come on hudson you can do it there we go name is an empty string and focus state private var name is focused and i'll say is to be false by default so there's no uh focus for our text field and then oh sorry in this room bull sorry like that there we go now in our body i'm going to say we have a v stack of stuff and then text field let's do sorry text field not textual style there we go uh enter your name and this will be bound to uh bound to dollar name like that uh says it should be focused when name is focused is true so when this is true focus is text field when it's false unfocused text field you know also hiding and and resigning the keyboard at the same time but we can now also add a button below saying you know submit login or something and force us to say name is focused equals false stop focusing our text field which of course is basically resign first responder in ui kit so i'll press command upstream command r to build around my code now being well i can type into my text field i might have to show the keyboard first let's press show keyboard and there we go uh enter your name b o b and then submit boom and it hides a keyboard automatically now obviously that's a very simple example but for more advanced examples you can actually make whole forms to track an optional enum work your way through the fields now focus this one now focus this one now we're done login and so we might say we have enab up here called field which of our form field is currently selected i'll do first name uh oops ready that one first name i'll do last name come on xcode and email address like that so the three form fields we're going to have and i'll have various fields for this so let's just copy and paste this a few times let's say first name isn't empty string last name empty string and email address empty string now this time it's not a boolean i don't have boolean true false true false that'd be a mess to handle instead i want to say what is the focused field an optional one of our enum cases it's optional of course because nothing can be focused when you first land on the screen there's nothing focused so what is our focused field so we can now say down here enter your first name this is bound to i'll do uh first name here this thing should be focused based on the value of focused field look for that field watch it and the value of this one is equals first name so when focused field is equal to first name this text field here is focused that's what we're saying now if you want to be particularly nice you should now say something like you know uh text content type is given name let's do a submit label of next go to the next field i'll copy and paste a few times um enter your first name enter your last name last name last name uh family name like that then we'll do enter your email address let's do uh email address here and here and here and if the last one it's not next anymore we're ready to join our chat channel we'll say it's join so go ahead and join and now for the interesting stuff well you don't want to have a submit button anymore that's too simple one replaces with a new way of tracking values changing over time and that is called on onsubmit when a value's been submitted what do you want to do in our case we want to figure out where we are currently and move to the next form field so i might say switch on focused fields if we are currently the first name now please focus last name if we are in last name currently now please focus email address and if we are currently email address then we'll do print joining chat room or something like that so we can work our way through a form and then submit the end result to go and do something now apple makes something really really clear to our people to hear do not use the same focused binding email address or last name or first name for two things don't do that that's a bad idea let's press command r to build and run our code and see how it looks oops i've got an error here i'm not missing a case really pitch focused field oh yeah none we need none let's do none here actually default is of course everything else at this point let's do that okay so is it going to build it's thinking about it no it's not building it's airing down here i'm missing a brace there my switch okay let's find out how this works so i'll do first name uh b-o-b sorry short names uh next bob lee another nice surname there and then next and it goes great blue for join now email address ah i can't type here where's my email address an email address you should show me the email address entry thing at uh j dot good grief is slow type com okay join and boom we get joining chat room down here brilliant so we can work our way through a series of form fields focusing focusing focusing as much as we want to and then do something more finished which is great so it's getting better and better and better and now it's simple change but it's done in such an elegant way and that's why i'm glad they waited they're going to put in you know just resign as a quick hack call an id they didn't they thought about it and planned it and made something really really beautiful which is fantastic anyway moving on moving on there's more things you can do um there's a new way now a nice easy way to handle badges now badges appear in traditionally tab views we just clips with junk go away go away go away they appear especially in tab views so you might say something like um a tab here says to tab view i'll have a simple tab saying text your home screen goes here that with a tab item using a label label of home and then system image is house that's going to show a tab view at the bottom of the screen with home and a house and we press that it'll show a home screen like that now a badge is traditionally used to put something over this to highlight users that this is something interesting happening here for example number of unread messages and this is really really simple in ios 15 you just now just say my type item is that thing i have a badge with five on it that's it that's really that's it so honestly it's so simple you'll now see a little sort of like a measles style effect a little thing hover over it's saying five it works brilliantly and you can do it you like i said there are options here to do you know text and similar it's optional down to you and it's localized as well it's even better um this thing also works with lists um you can actually recreate a sort of like um uh setting style screen where you know thing appears in the left and then detail appears in the right a badge on the right because that's something like um let's do a list and if you're doing settings you'll notice things like text is wi-fi and then text is bluetooth and in uh settings they have wi-fi and bluetooth on the left on the right you can say something like your wi-fi name which one you made to right now so i might say i'm on lan solo and badge on and that's it you get this great layout completely for almost no code it's just absolutely wonderful boom just just like in the settings app so badges are brilliant and they're really simple to use and they just help again make your ui fit in the rest of apple's designs there's some chains for sheets you can now say when you're showing a sheet actually this thing shouldn't be swipe to dismiss now we had full screen cover last year to show a whole screen covering the main view but that's this is different this is a screen that is obviously an overlapping screen but can't be swiped away and you can control it by saying what is the interactive dismiss disabled setting for this sheet uh and this is important for places like you know show some information don't let them go away till they've made a choice whatever that might be make sure they've made that choice and then they can swipe to dismiss so please accept our copious amounts of terms and conditions for example that kind of thing is a great way to dismiss only when you're absolutely ready for example you might say i have a sheet i'll call it example sheet example sheet which is a view this thing has to have an environment property of presentation mode so we can dismiss ourselves when we're ready like this and i might say there's a body in here and a v-stack with text saying this is my sheet view and the button will be dismissed and action will be closed and that will be a method down here called close to presentation mode rap value dot dismiss and we're going to make this thing not swipe to dismiss so i'll say actually interactive dismiss is disabled do not let them swipe away to get rid of this thing and when it comes to showing that in our content view down here i might say at state private var showing sheet equals false in our body i might say the button saying show sheet with toggle sheet showing sheet dot toggle even spinnerisms uh i'll do a sheet with is presented presented is come on keyboard you can do it presented uh showing sheet and the content will be examplesheet.init so when you press the button show the sheet but don't get rid of the sheet by swiping down they've got to press the button to dismiss let's try and run that back i press show sheet and now i cannot pull down dismiss this thing i've got to press dismiss jeff asks are there any size or presentation options for sheets beyond this i haven't seen any i i really want to see form sheet um from you know ui kit because that's really really nice on ipad i haven't seen that yet uh if someone with citywide is watching and they know of a former equivalent now is a good time to say so i'd love to know now actually this thing takes a binding to a boolean if you want to customize it on the fly uh so you might have said something like um in our example sheet have they accepted our terms it's false by default right and so in our restart i can now say uh there's text with you know terms and conditions in a font of title and text uh lots of legalese here like that and then a toggle uh i'll just do accept like that and find the is on state of that to be terms accepted i'll ditch my dismiss button because now uh add a bit of padding around this and we'll say uh dismiss disabled with not terms accepted like that oops i knew that let's press command r to build and run and show sheet so i can't type dismiss i accept the conditions and now i can swipe to dismiss so you can bind to that if you want to it's down to you it's really flexible and it works brilliantly ah mark moykins hey mark how are you doing um is there a way of making uh the background semi-transparent i haven't seen that i that used to i remember ios 3.2 like a long time ago i mean is4 maybe you could do translucent uh form sheet modals and uh it then spontaneously broke in a future version i'm not sure it was intentional but you could do it uh so anyway i don't think you can ask the answer i think something i know of um okay let's do something real easy because i've done a few harder things right now something real simple uh this one is just wonderful absolutely wild um brace yourself for this one folks um swift ui now has built-in support for markdown in ios 15 and you get bold italics links strikethrough you name it it just it just works um so i i it feels almost stupid saying it because it's basically free it just works out of the box you just say text then it's a markdown and it just works so i could say i want to have a v stack here with text uh this is regular text then text i'm going to do this is star star bold text because that's that's a bold and markdown or text this is uh star italic star text i mean it's just basically pure markdown this is start asar bold italics our star text uh text what is it's like tilde tilde uh strikethrough example tilde tilde or text uh mono spaced works too and even i mean this is wonderful even uh links are gonna visit apple uh click here https.comapple.com like that um in theory all three of those just work out of the box let's find out boom look at that everything just works like regular markdown i can just click on you know visit apple and uh it will launch apple.com in safari it's absolutely brilliant so i don't i don't know honestly i can make that any easier because it honestly works out of the box which is great um one thing i would say and uh this might change in the future perhaps uh images don't work um which is a shame because that'd be great to pull things into your asset catalog directly um so yeah it doesn't work just yet which is a real shame also it's a bit of an annoyance um they can obviously do links inside text these days but i don't think still today you can put a link like a link struct inside text you can string interpolation that's really missing um anyway boom markdown just works which is great next up i already showed you um button rolls because button rolls you know destructive or cancel they matter and it's as important because a it makes our other apis simpler you see how they work otherwise but but they've also uh refactored the way or rewritten the way alert and action sheets works and um kirchhoff's saying dev pubs crush it this year and they did death pub did a really great job this year well done you know comprehensive documentation for swift ui uh you know dark mode now worked out of the box there's screenshots galore they've done a really really good job thank you so much dev pubs well done anyway buttons and rolls this match because they've changed the way alerts work because these better say as an alert struct and action sheets struck and similar to handle alerts and action sheets and that's all going away now they've simplified it dramatically and made it much more standard they're using regular buttons everywhere and as you'll see the new way of doing action sheets also now supports mac os because they have different ways of handling action sheets and the non-correction sheets there are confirmation dialogues as you'll see anyway let's look at a new style alert uh let's say something like uh at state private var showing alert is false and then our body we're going to say button show alert i'll do showing alert equals true attach our alert modifier now there are quite a few of these things now and they're all quite hard to read in places but uh yeah trust me get worse than that um you can now say directly in here what are you trying to do you can see title is there a localized string key a binding for boolean if it's prevented or not plus our actions what actions do you want to have in there and these are regular buttons that's the power of this new way of doing stuff there's no more alert button an action sheet button just regular 60y buttons everywhere with that roll so it knows how to color them successfully and handle them on the screen anyway button the other alert with important message binding that is presented of showing alert and then for my actions go ahead and make all the buttons you want to so you might say there's an ok button with a roll of cancel with no action code inside because by default all buttons dismiss the alert and so that makes a standard tool cancellation button so i'll go ahead and press command b let's find out how it looks we should see boom okay great and just like the old api for alerts when it goes away showing alert becomes false again so it's a two-way binding right there now you can provide as many buttons as you want to and if you don't have any with the cancel roll then an extra won't be added for you automatically which is great for example we might say i want to have multiple buttons here i want to have you know uh let's do first doing that and then second and third for example boom and that's it i've added a cancel button there so we'll add one form of mattely uh geraldine does alert support text fields now no it don't doesn't as far as i can see there's no sport of text fields still which is a real shame because this new api is so close to handling text fields and yet no it doesn't appear to work with it just yet which is a real shame um maybe next year anyway um so these are native buttons which means you can now say this first one here is important you might say it has a role of destructive and again 51 stands for context it'll say this thing's a bad thing make this red make it obviously stand out on the screen somehow bang don't press first it's bad the same kind of api rewrite has also come to action sheets where they're now called confirmation dialogues and this is great because of course mac os doesn't have action sheets it has dialogues and so we no longer say action sheet we still can if you want to have ios 14 support of course but if you want uh 15 support then you want to use the new confirmation dialogues so let's say i want to have uh showing options is false and at state private var what i have selected and i'll just do none by default now in our body well let's say there's a v stack of stuff like this i'm going to show their selection in there right now so it'll be none by default and then uh in this button i'm going to say you know please confirm the paint color you want to choose and i'll do showing options is true now to handle the action sheet is we don't want to use action sheet anymore because that's the old api you've got to use their fancy pants buttons you've got a not support mac os um we're going to use the new confirmation dialog option here and there's there's quite a few of these they've really gone to town with options here um which is yeah yeah i'm not going to go there oh it's not ideal to put it that way um dialogue uh select the color is it presented or not well by now they're showing options and then just like showing alerts there's no more fancy pants custom api just swift ui buttons now so we'll just do button is red i'll do selection uh is red and then paste it a few times red green green and blue blue like that make them however you want to you can if you want to actually ask it to always show a title i could say you know always show the word select color for example it's down to you uh i might say that you know maybe uh red is bad so again roll destructive because it's a standard swift ui button there's no more custom api anymore it's all the stuff we get to reuse again again again which is great hopefully now i can press confirm page color there's my options i'll press blue and it pops blue that's a really nice uh cleaner way of handling action sheets it also works well on other platforms cool what else you already seen on submit ultimate's really nice because obviously you can navigate through form fields um it might get better in the future but right now it basically it'll effectively what we had before was i'll show you example we had the ability to say you know username is an empty string and a password is an empty string and we might have said something like um in my form there's a text field uh called username bound to username with oncommit being some kind of function you know username was set for example uh and you do the same thing then for uh password perhaps you know secure field rather than text field password bound to password and again have an oncommit function attached to that so when you submitted one of those things it would run your custom code and you can still do that but what on submit let you do is take that one level higher take out oncommit here entirely like this goodbye and instead attach that to the form so when either one of these two things are submitted run some code of my choosing so you might say now well let's make sure that username is empty it's not false and password is empty else return and then print authenticating so make sure they pass in both values before we submit the whole thing somehow so on submits really really helpful for this kind of thing but grouping multiple submissions together we used earlier navigating through form fields as well so it's a really nice clean addition uh menu men's had a lovely upgrade in 915 because this is available now it's 14 for ui kit um you can now have primary action for your menus and so you can distinguish between press and hold to show a list of options to work with or a quick tap do one exact thing right now so for example we might say let's get rid of some code we might say there is a menu with the title of options uh button order now action i'll do uh place order then button adjust order action adjust order then button cancel action cancel order and then pass this thing a primary action what to do when it's tapped quickly like transient press in this case we'll just you know just do the thing whatever happens to b right and now we can add our functions we'll say i just do it down here prince button was tapped so quick tap transient tap then of course place order crazy empty function and then adjust order empty and then cancel order door like that boom so this prime reaction distinguishes it from pressing and holding so i run this code back we're going to see options as a button on the screen and if i hold down i'm going to see cancel adjust order and order now pop up as menu if i press it quickly we'll see down here it was tapped so you can distinguish between this this transient tap and a press and hold just now the prime reaction um cunningly i know devpub's crushed this year don't follow their example code their example code's been deprecated already they move really fast right um there is like two more things i want to show you perhaps and we're done i know i know right quite a lot already sorry i know it's late for a lot of folks out here anyway um there is a new way of handling uh foreground stuff because uh here there's some code what time is it quarter nine or nine pacific it's late um we can now say that our our layouts have a color but also have styles attached to them i could say there's a h stack here with an image and let's do system name of clock dot phil text set the time uh and i'll put this thing into a font of large title dot bold boom and i'll give this thing a foreground style not color style of quaternary now these are what were available to us as ui colors in uaket land you could say primary secondary tertiary quaternary to get different levels of opacity the levels of emphasis on the screen uh quaternary is one of the most faded and so when you play this back you're going to see a very faded h stack you know a lot of transparency whatever's showing through in our case it'll be white showing through so it'll be quite a light gray all this tertiary secondary and primary as well which is neat so you can now make the whole thing fade in and out matching the ui kit sort of emphasis colors but super clever is there a whole bunch of other foreground styles to do more advanced thing for example you might say actually um primary secondary quaternary at all well and good what i want is a linear gradient and then you grade it you can now pass in gradient pass in all the values you want to work with so i might say we have let's do colors of uh red and black because i've been watching the miserable let's do a start point of top and an end point of dot bottom and now we get linear gradient as a foreground style and it's really really flexible stuff boom beautiful super easy to do too honestly it couldn't get much easier quite frankly um to do these kind of complex effects now but before you have to you know do a background of your uh or a mask sorry with your gradient and mask text over it it was more complex which is great uh cut same swifty white colors on all platforms now that's interesting is that correct really background color dot i'm loving mint by the way mint's a lovely color um really i i really want to do is colored up background you know system background and second background and tertiary background that's what i want to do because i want the background color sometimes you know and um anyway it's late we'll do one last thing i know i've ranted a lot so far and i'll i'll stop imminently folks you can get on with the rest of your lives um something which will make people very very happy and i mean over the moon happy and yet it's so simple is that you now have limited control over the way your list separators look you can hide them and you can colorize them and that's it um this is of course a huge improvement um which is which is great ah could foreground only that's a real shame i want to see background stuff too because system background's missing and it really wind me up i'm gonna do the binding to ui colors behind the scenes anyway um list stuff yes let's do a list of one two a hundred with the index coming in index in text row index i'm gonna say this thing has uh list row separator hidden do not show the separators like that uh and it'll hide it for that row and you can also say actually i want to have a tint color let's do a list for a separator tint of red also works um there is no way i believe at this point to say actually adjust the inset because clearly that's very hard to do but uh we can at least hide them and we can at least colorize them okay we have just gone through stacks and stacks and stacks of changes for software i15 um i didn't make too many mistakes which is great um hopefully you have learned a few things along the way hopefully you're feeling super psyched about if15 because 50y has seen some significant steps forward i'm really really grateful for the team for all their hard work and also for deaf pubs and documenting it all sufficiently um and hopefully you're looking forward to trying out and there are some great talks coming up this week on safety why and more i'm not sure i haven't seen the full schedule yet but i hope there's another luca talk about data um we'll see but hopefully that was on for i think friday last year anyway if you enjoyed the video please hit like please subscribe to the channel leave a comment saying something nice about me and my dogs i read them all it doesn't matter to me um so please go ahead and uh give it a try um any questions i can answer while i say did i see matt's name go by matt matt is so helpful matt honestly he's been wonderful answering questions from a lot of folks including me so thank you so much matt um you're a real pal ah so that's interesting so i might say you can now just do background mint which of course is brilliant by itself because mint's great you can that's great so that's at it being very clever because before it it was obviously complex to figure out what was going on uh which is which is really really cool so that's xcode getting smart all sorts of swift games smarter sorry which is really cool anyway if you have any questions i can have a go answering them but we actually have the swift ui team in the audience and maybe they can try answer the questions while they're here they probably can't because of you know these reasons and stuff but if i can it'd be great because that helped me out too jesse my dogs are gorgeous yes they are and they they know they are and they abuse it by coming in and getting treats and doing stuff um donut asks is it backwards compatible i do not believe so i've seen the evidence here there is any of this backwards compatible it's all ios 15 or later um in fact i'm still waiting to see what the swift 5 5 compatibility story is async await it looks like they're maybe trying to back deploy that using xcode somehow using some sort of shim library um for ios 14 or 13 i don't know i don't know i have to wait and see um because a lot of folks would really miss that it wasn't available jeff asks is there a preferred status bar style no i look for that i haven't seen that anywhere sadly which is a real shame um i look for that straight away because one i thought my list of things i really want to see at ui that and text fields and alerts and background colors and similar got a little nag list of things i really really want to see in 50y and i believe that's currently not available which is a shame shame um dano why import qualification you want because i was noodling around it's a new as a new location button in um caution ui i was noodling around exploring it to get a one-off where am i right now you actually say you know what should it look like um that it's like you could say share my location or send location and it basically makes a system button the user understands it'll ask them correctly do you want a location once if it does you get location or you can ask for it sorry and then it will work afterwards and they press it again again and again um that's why it's important and it's not required i'm just noodling around ignore it julian refreshable is not working on scroll but you're correct it's not working on scroll view maybe it should i don't know why i mean i don't know why it isn't sadly so uh yeah we'll see is there anything else collection views uh so i think you're thinking about the tab view with uh the paging style um there is i haven't seen sorry i haven't seen any uh support for the fancy pants orthogonal scrolling where you can have like little bits hanging off the end uh they can in ui compositional collection view um but naturally swiftly composes so you could have a scroll view then a tab view then something else below it's not quite as powerful as um uh compositional collection view but it's still rather nice might hello mica how are you doing um can use custom colors on alert buttons good question should we find out well although it's like a billion years ago wasn't it h stack set the time whereas alerts menus let's do it here let's try and tint this i think i think indigo um is brilliant by the way i love this color and mint okay whoops kind of doesn't look can we action is meh meh let's find out let's find out uh press and hold no it's the answer you go okay uh so um that was a long rant from me but hopefully you are excited i certainly am as you can tell from my general well-being i am loving it uh there's so much going on and there's a whole week ahead this is just like scratching the surface of what's happening right now there's so much happening right now i'm keen to explore some more tomorrow and the next day and the next day the next day um see what other goodies are waiting for us um i have seen by the way in ui kit you can now do bottom sheets correctly you know there's all pull up sheets you'll see in maps i have not seen that in swifty y which honestly i cry if that isn't there because that's a wonderful feature when you like it's finally arrived and it isn't there fty wait another whole year no anyway um my bits there haven't seen it yet after explore some more i've poking around i'm harassing swifty white team there are lounges there are labs so i'm not gonna laugh tomorrow sadly um but i'll be in the lounge and chat folks then we'll see how it goes um yes it's all cool oh good question there from who is that ali makongo uh will it change the hundred days of ui much yes it will i'm going to absolutely be recording the whole 100 days from scratch to integrate all these new changes because so much has changed i want to really get the whole thing bang up to date so every video every article will change to reflect that in fact in about half an hour i'm gonna push a big update so if you why by example covering most of what was talked about obviously transcribe this video and then put it online as fast as i can and so that's gonna happen tomorrow probably or tonight and a half now we'll see how i get on this it's already nine o'clock so we'll see how i tried the news of playgrounds now i haven't i can tell it's not actually available yet which is a real shame i did ask one of the engineers on twitter um a bunch of questions and um they didn't answer sadly i said he can't tell me so it was things like can you pull in spn packages can you use git does the mac os version have these new features um and uh i don't know i want to know as well trust me i'd love to know because that seems like a really powerful way i talked about last year actually with erica when they uh launched the mac os playgrounds it's a lovely middle ground between full fat heavyweight xcode and sort of playgrounds are sort of cartoony move forward collect gem kind of thing and i i'd love to see more of that you have to really lower the barrier to entry to help more folks ship apps so yeah we'll we'll see doesn't your search only work on lists so as i showed you actually it requires nothing at all we attach it to a text field um you can do you like and we did a list you do filtering and suggestions and stuff but you can do text field i'm sure you do if you like doesn't really matter um let's say on a couple more because it is getting quite late folks don't hang out too much here um i saw one go by from eugene hey eugene um what my thoughts and combine uh hasn't gone up this year that's fine i mean combined it's great mine's already great i wouldn't change too much about it as it is and i think what's gonna happen now is focusing on a pause and think what the heck just happened to swift you know with async await async let's 408 actors and more there's a lot of change in swift this year the swift language even things like at main actor for example there's lots of things have changed uh and you know things about benefit why things like you saw how we can do um dot sidebar around sidebar list style and the hash if for uh postfix member expressions all there and so forth um and also actually swift ui particularly uh the silent bridging of cg float and double oh yes last cd float be gone quite frankly anyway um there's a lot of swift churn this year so if 5.5 is massive and i'll do a stream tomorrow i expect just on swift 5.5 because it's so huge and um as a result i think we'll take some time to see what's happened to let folks actually try these apis out and see what we think of them see how we work with task and task group and similar get a feel for them what works and then how that plays well with combine because they're not they're different problems but same kind of problem space at least and so how our code can result in change i don't know i think letting it bend a little bit before trying to monkey around with combined too much is a good idea so just sit and wait see how you know your weight foundation changes work we go ahead and try and change too much of them combine anyway okay enough for me thank you so much coming along folks it's been a pleasure having you here please hit like in the video please subscribe to the channel leave a nice comment i do read every one of them and if you could if you could really help share the video and i'm here chatting away at 9pm uh pacific time on on keynote day tell your friends you enjoyed the video tell them to check it out and that would mean a lot to me and i'll see you on twitter i am two straws you'll see a little euro in the bottom left corner there uh hacking with swift.com offers that's there because i have a 50 off sale right now on all my books and bundles so you can go and learn swift uh for less quite frankly go check it out i'll see you all on twitter hopefully uh imminently have a good night and enjoy ii15 have a great dub dub dc
Info
Channel: Paul Hudson
Views: 40,552
Rating: undefined out of 5
Keywords:
Id: SQE5DZDqASA
Channel Id: undefined
Length: 83min 18sec (4998 seconds)
Published: Mon Jun 07 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.