The Hitchhiker’s Guide to SwiftUI - iOS Conf SG 2021

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi everyone my name is marlin and i'm originally from sweden but i lived in australia a bit and now i'm in vancouver canada and so i'm running a software studio together with my partner kai and with our studio we are both building projects for others as well as working on our own app so the latest thing we've been working on is an app called orbit which is a time tracking and invoicing app both for mac os ipad os and ios and this is an app that's mostly written in swift ui and i think there are many different resources available on how you can get started using swift ui which is awesome and it's great to see so much enthusiasm about swift ui but when i was using swift ui i noticed that there were some things that would have been helpful if i was aware of beforehand and there were also some things that i felt were missing or things that i had to had to work around and things that i had to figure out along the way and so i figured i wanted to just talk a bit about that today and a bit about my experience using swift ui to make an app both for mac os ipad os and ios as well as sharing some of my tips and tricks that i found along the way when i was working on the app and hopefully that will help help everyone when they are making their apps as well so to get started i just want to talk about the general state of swift ui and i think overall i i'm really excited using swift ui i've had a lot of fun learning it and building my apps with it but it's still noticeable that swift ui is new and that swift ui is in an in an early stage so there are still a lot of things that are uh being added to swift ui so lately at wwdc 2020 we saw for example that a lot more things became available that were platform specifics so it's awesome to see that apple is continuously con adding improvements and adding things for the specific platforms um but i think it's important to be aware of that there are still some things missing and some things that you might have to add your own workarounds for or your own implementation in order to get the behavior you want but i think overall uh swift ui is um in the stage where i think you should get started using it so um even though there are some things that are still being that are still missing there's many things that we get and many benefits of using swift ui so of course you can just write it once and run it anywhere no i really don't think that's how we should look at swift ui and that's something i want to emphasize here that it's not about writing at once and running it anywhere it's more about learning at once and then applying that anywhere and this is something that i think is important to keep in your mind when you are deciding to use swift ui and you should use it rather as a tool that you're learning that you can use across the different platforms but think about each platform as individual platforms and consider what is best for the platform so if you're making an app that you want to be both a mac app and a knife and an ios app you should still think about the platform specific behaviors for mac os and for ios but you can still use swift ui as one tool for that and there are some parts that you might be able to reuse but it shouldn't be the core reason why i use swift ui so one reason i think for users with dry is just the fact that you can learn it and then use it across all the platforms which is really appealing but then another thing is custom ui so there was one view that i will show you later in our app that we thought would take about two weeks and then it ended up taking two days for us to get that get that working so making a custom ui is really easy with swift ui so that is awesome um so when should we use withdraw i think uh an obvious place to start with swift ui um is in a widget so i think a widget is a really good place if you already have an existing app for you to get familiar and start using swift ui so you can start adding a widget and then you have your sort of concise space where you're making your swift ui view but then if you feel if you feel like you really like that and you feel comfortable using swift dry i think you can go as far as you want so you can use it on watch os ios mac os of course tvos as well if you have a tvos app um so i think let's say that we so with that that said we would just want to go ahead and make an app for ios and for mac os as well we just want to go full in and that's something we can do with swift ui and i think that is really exciting that we can actually now make an entire app using swift ui um but for that i think it's important to talk a bit about the structure of swift ui and how you can structure your ui and structure your views in order for you to be able to create those custom uis that you want to create and in order for you to potentially be able to reuse some things as well um so as we all know um views in swift ui are made up of out of different type of views so we tend to stack diff we tend to combine different v-stacks and h-stacks and views in order to make up an entire interface for our users and so that is sort of swift your eye as uh at the base level on how you make your views but i think then it's up to you to sort of decide how you want to structure your code and an obvious place where those v stacks come into place is in this view in in orbit so this is our dashboard it is a very custom custom interface and here we have built a whole view based out of different components so this part again as this row these different rows of the projects we decided to separate out into its own component um and this is where i think it's uh it comes in handy that you decide to actually really try to move things out so if you make this into a separate component this is a view that you can reuse across and a view that you can very easily just have in one control place and you get this one component that you can use within your app and then this can be put into the overall component and the overall view that the user ends up seeing but this view itself is actually made up of out of a lot of smaller components so it's made up out of the v-stack and out of the rows that i showed you as well as out of this chart which then make up this view and the benefit of componentizing this and separating things up into smaller pieces is that you can reuse this so if you have this layout on an ipad for example you will be able to um reuse that on a smaller screen so maybe you want to use the same ui or the same components on ios but you want that in a smaller sort of form factor because the iphone is smaller then you can actually because you have componentized things out and have separated your um your rows from your chart uh you can easily put this in a v stack rather than our previous h stack in order to have the same components and reuse those components into a different type of layout and so that's where i think the way that you use decide to structure your code and the way that you componentize things in your code is important for you to be able to get that reusability and get that flexibility that swift ui has given you and then you can make quite complex um custom uis yourself and i'm talked a bit i mentioned a bit that this is something that's helpful for different platforms so when it comes to structuring your um your app for different uh four different platforms or your project for different platforms uh there are many ways of going about it and i think if we want to have an app that looks very different on mac os and ios you might actually want to decide to separate out your um your code at an early stage so you might share the code base and have everything in one project so that you can reuse your network logic and reuse all your models and reuse some of your files that make sense but you can actually at a very early stage decide to keep everything in the same code base but customize things and make sure that everything looks and feels right at the different platforms so an early place you can do that is in your content view itself so here we can decide to separate out a logic for ios so we can have this if ios if os ios and then we can decide to display a tab bar for example so on ios it's very common to have a tab bar in the bottom whereas on mac os we might want to display a sidebar which again is very common of a pattern on on mac os to have it in a sidebar so this is already one place where we can start separate our code base and you can see there that you actually end up having very different navigation flows because you separate them at an early stage here but let's say that you also want to separate your ui to look different on ios and on ipad os you can use the same structure there and you can actually reuse some things across ipad os and mac os if you want to so let's say that you want to have a a sidebar list again on the ipad and on the mac but on ios you want to have the tab bar and then you can use this horizontal size class and check whether or not you're running on a compact device and if you do you will display the ios display the ios ui and if you're not running on a compact phone or on a compact device you will be running on the ipad and then you can display it in the you can use the sidebar navigation instead in the here we can actually see an example of where we can potentially reuse this so if this looks very similar on ipad os and on mac os you can use the app sidebar navigation view both in the ipad app as well as in the mac app so that is just one place where you can start separating things out already so let's say that you might have your sidebar that looks very similar on the on the mac and on the ipad but you might want to have a different modification on it so on i on the ipad you might want your fonts to be rounded for example you want to have a bit more of a playful feeling on the ipad um so let's say that you do end up reusing some parts or the the main like some views across those platforms but you want to add some modification there you can actually do it quite easily so this is an example where i have added this this modifier to to the view so if you look at this and this is an extension of view which is a function called ios which takes a modifier and if you are running the app on ios we apply that modifier to self so in this scenario we have a text saying hello world very simple um and if you are running on i if you are running on ios we will apply this modifier which is to apply a font that is rounded uh to that text and that is only going to be executed then on ios so if you're reusing something on ios which includes ipad os so if you're reusing something across that and mac os then you will apply you will be able to use those sort of mechanism to customize certain things um so yeah those are some few different ways that you can both structure your app in order to make it readable in order to uh and in order to add those custom ui components that you want to have but also the ways that you can reuse those components and ways that you can customize your ui and make sure that you have a nice ui across different platforms and make sure that you're really um adding adding behavior and adding um adding the flows that you want on the different platforms um so that's that's great that's how you can get started using swift ui in a more complex scenario across both ios and the mac um but i still want to talk about some shortcomings that i have seen um that you should be aware of when starting to use swift ui and that is a that swift ui has quite a high level of abstraction so since it is still early you sort of rely on things you you do rely since it has a high level of abstraction you do rely on things working as expected out of the box but if things are not working it might be hard to actually debug things and troubleshoot things that aren't working as you expect them to and that's because you have that higher level of abstraction you don't have that much insight into what's actually happening you're sort of just saying declaring your view and saying what it should look like and then hoping that it will look like that and most times it does but times it does sometimes when it's not doing that or times when you might want to have your own behavior and add your own custom functionality that can be hard to do because of that um and because there are still some things that are missing in swift ui that high level of abstraction can make it harder to customize those things so that's something to be aware of and of course it's a yearly release cadence so even if we are seeing more and more things coming and being available from apple we have to keep in mind that things are going to change on a yearly basis so if there's something that you're missing it might not be introduced until a year later and so i think it's important to try to think about how you can sort of find workarounds and find your own ways of adding that functionality that might not be there at the moment um so in terms of things that might not be there um there are obviously things that are a bit more fundamental or higher level we're still missing things like some advanced navigation and another thing i really missed i would love to see in 2021 is pull to refresh which is not there at the moment um which is a bit of a shortcoming but uh when you're aware of it you can structure your way your app or decide how you want to handle that behavior yourself in your app um but with that there are some things that i have noticed that i personally was missing with swift ui that i end up working around and end up adding my own implementation with so i wanted to share a few of those so one thing i want to point out is that one really great benefit with swift ui is that even though it's since it is i guess one benefit is that if you want to use swift ui you don't have to go full in so if there is a behavior that you're missing and you have experience with ui kit or app kit or there is a way of doing that in your ikit you can always move back to that as well you can always combine swift ui and ui kit so i think that's one way one thing that makes it very friendly to start using swift ui because if there's something you're missing and in general i think you should try to go as much swift ui as you can because it's a good learning experience and it will make you faster at using swift ui and that will help you understand swift ui more if you continue using it of course but if there is something that you want to have that is specific for ui kit or app kit you can easily bridge over to that so one example for that that we had in orbit was an image view that displays a vector and we noticed that this image in swift ui didn't preserve the vector data so if you're looking at this in swift ui this view is this this image is really blurry so it's it's not at all what we want we want it to be a lot crisper so that's something we had to find a workaround for so we ended up using a ui view representable so this is where we're bridging over to ui kit rather than using swift ui out of the box so the way we did this was to add our own image view which is an uiview representable so i will show you a bit what this is doing but in general i do have all of the code that i'm showing you available in my github repo so don't worry about paying too much attention to all of the code i will highlight i will talk about the high level things um so the first thing is that this is a image view that is a ui view representable and what this does is that it has a function called make ui view and this is where we are interfacing with ui kit instead so here we're creating our ui image view and since we passed in um but we have been able to pass in from our swift drive view what content mode we want to do what content mode we want to use for the image so once we created our image view we can just apply our own content mode that we decide from from from there when we're calling this when we're creating this view so we can set our own content mode and we can also use the image that we passed in when we created this uh when we created this custom view so if we are so here we're trying to fetch a ui image with the name that we were provided with from swift ui and then we are setting that image to our imageviews image um and in this ui view representable as well i just want to highlight that there is also a function called update ui update ui view and this is where you would do things like update the view when things are changing in your swift ui view so if you for example let's say you have the user enters a name of an image that they want to display and you want to change that as soon as they have entered a name then you could have a binding variable which is the name and then you could update the image here but i'm not gonna do that now because that's not uh that's not necessary in this use case but you can customize this um and bind to variables as well um and then you will end up having something that looks like this so the next thing i want to talk about is our text editor and i think in general it's great to see that apple added a text editor but one thing i was missing was a placeholder text in the text editor so if you look at this top view this is the default text editor that you get from swift ui but if you want to have something like a like a hint or a placeholder that just lets the user know what they should enter in this field you might want to have you want to have like a grayer text here um but since that's not available i decided to add my own text editor with a placeholder text so the way i did that was to add my instead of using a text editor i used this text editor with placeholder text function or struct that i've been creating it's not very great naming but it's hard to name things so here we go and so what this one does is that it's just a struct it's just a view and that uses the text editor that we already have with swift ui and to that text editor we apply an overview or an overlay and that overlay is our placeholder view and that placeholder is an h stack with a v stack inside of it and what we do here is that we check if the user has entered information or check if the text field is empty basically and if it is empty then we add our placeholder text so that means that next time when the user starts typing text we will not display we will not display the placeholder anymore it would just be there but while the user is still while the user hasn't entered any information um and then the last thing we do here is to turn off hit testing because we want to we don't want this one to pick up on any touch input and yeah that is just used here as an overlay on our text editor so we can still use the swift ui component we don't even have to move over to ui kit in this scenario um and then we get something like this and this is what it looks like in action and we can just go to the notes field and then start typing and the place all the text is being removed as soon as you start adding your own text um so that's one thing that i found to be really handy and something we use used throughout our apps um another thing that i felt was missing as well was a customization of a um picker view so there are many ways of there are some ways of customizing your detail in the picker view so if you're not familiar with the picker a picker is basically something that you if you have a picker in swift ui and you have multiple options that you want to display that will automatically segue you into a separate table where you have multiple options that you can pick from which are all the pickable options for the picker and in the default behavior we get this extra space at the top and we don't we're not able to add we don't have a title by default um but what i wanted to do was to add remove that space and add a title to this view that sort of just says says what the picker options are for um and there are different ways of adding titles like this but all of them had different limitations when i tried using them so i ended up using we ended up adding our own view and our own behavior for this and so for this we're using this enum helper which is just our different options for the for the beverages for the different options that we will display in the picker um and then we can this is our customized picker so what we do here is that rather than using a picker we are using a navigation link so this is the navigation link it has our destination and it has our label so let's get started with the label so what the label does is that it displays an h stack with our text which is a select beverage then it has a spacer and then it just shows the picked option um and that will look that will end up building up this view that looks very similar to the default or it looks exactly the same as the default picker picker view when when you're looking at it um but that's that's what that label is creating so go to go back to the navigation link the next thing we have is our destination and our destiny destination here is our own view so this is a custom picker view that we created and what does what that does is that it's a it's a view as well it's a swift ui view so again we can stay with swift ui which is great um and this one has a body which is just a list of the different beverages that we want to display so we are displaying all of the different options that we want to display in the picker and then instead of having it just as a text label we actually have a button which makes up the row in that list so the button has a behavior that sets the selection so as soon as you tap the button we set the selection to the beverage that was selected and we dismissed the view so that we get that automatic automatic fallbacks that we actually go back when once you select a new option in the picker we go back to the previous view and to mimic that behavior that we get with the default picker and the next thing this has is a label again so we have a label with an h stack which is just displaying the name of the option that we have available in the picker and a spacer and if this is the selected option we also add a check mark to make sure that we show to the user which one is being selected or has been selected and that makes up the list overall and the benefit of this is that now when we have this list we can add some customization to it so we can add our own title and we can also make sure that we don't have that additional space by making the display mode an inline mode and then we'll get something that looks like this so the next thing i want to show you is a scenario where that i was using quite a lot and that is the presentation of different sheets from one view so that means that you might have a view for example a login view where you have two different buttons uh or actually i guess it's an authentication view or welcome screen and you might want to have two different buttons one is the create account button and the other one is the sign in button um and then you want to have two different sheets that are being displayed um and that is something that is i i think is quite a common behavior um but the way to structure that is not as obvious that i uh obvious as at first seem because if you do end up adding multiple sheets to within the same view they will end up overwriting each other so if you want to have two sheets there are some ways that you can add that so i want to go through that and this is the behavior that we're looking for um if we type sheet one we display sheet one and if you tap for g2 we display sheet two pretty pretty nice pretty uh common behavior and the way that we do this uh is that we have this sheath type which is an enum and this one has different cases for the different sheets that we want to display so depending on the button that you're tapping in this view we are setting the sheet type that we want to display so if you tap button one we said sheet type to sheet one and if you type button two oh it's at the to sheet two um and then we can have our v stack here which has a sheet attached to it and that one checks for the item sheet type and when the sheet type is being set then we switching on that sheet tab to determine which sheet we want to display um so in here we can see that if we are presenting if if the case is sheet one we will display sheet number one and otherwise we will display display sheet number two and this is something that i also found to be quite useful for alerts too because the same thing applied applies there so if you want to have multiple alerts that you want to display from the same view um you can use a similar way that you displaying them based on an item and displaying them based on an enum and determine which alerts you want to display all right the last thing i want to go through um is something that is a bit more uh structurally structurally related it's not view specific but it was something i felt was missing um and that is the behavior that we get in ui kit that is called um is modal in presentation so for those who aren't familiar with is modal and presentation what this does is that it if you set its mode in presentation to true in ui kit you will not um any uh any interactive dismissal of a sheet or of a model will be ignored so you won't be able to dismiss something by pulling it down and this is something that i found to be very valuable if you have something where the user is entering information then you might not wanna you wanna prevent them from accidentally dismissing that view if they have entered a lot of details so i'll show you what i mean so by default in swift ui um you get this behavior so if you are presenting a sheet you can of course dismiss it and then if you present a sheet and the user is typing something it's still possible to dismiss it so maybe if that was important information that would be lost at that point before because the user didn't tap the save button they just decided to go ahead and dismiss it um and that's something i would like to prevent so the way we i will show you how we did that um and just as an example i just want to show you what what the behavior is that we're looking for so we can still dismiss it but if you start typing something and you try to dismiss this sheet we're going to block that so you could you could wait for them to actually tap save or tap cancel in order to get out of that or maybe you want to present an alert or let them know why they can't dismiss it but the important thing here is that i wanted to add that behavior to be able to like actually stop the user from accidentally dismissing the sheet in case they will because otherwise they might lose valuable information of course the name of the coffee that's your pro that's your favorite coffee might not be essential information but there are more scenarios like if you create a new account where you wouldn't want to use it to accidentally dismiss it so i'll show you how we add this custom behavior for the moto presentation uh so to sort of add this functionality ourself we're going to add a state variable which is called is sheet modal and this is going to be used to enforce that behavior ourselves so we're still going to use our swift ui sheet and we're going to present a view here but the view that we're presenting is going to take a binding variable which is called is modal um and what we do in here is that we have our view and our view is just presenting a text field a regular swift ui text field which is getting the text that the user is entering and then we have a unchanged modification so what we do in the on change is that we are calculating the modal state and depending on that state we set is modal to true or false so i'll show you what the calculate modal state does and so what this does is that it checks whether or not the user has entered text so if the user has started writing something in the text field this will return true and otherwise it will return false so that means that if the user has entered information um we will set is modal to true here which means that that's an indication that we wanna we don't wanna allow that interactive dismissal we wanna force them to use the cancel button because we don't want them to miss their important information about what their favorite copy is um so if we go out one level where we add this sheet we're gonna use that ismodo variable um in this presentation modification and that is something that we built which is an extension on view and this is where we are moving over to ui kit in order to get this behavior so here we are present we are creating a modal view and we we're passing it the view that we want to display so the swift ui view is being passed here to the modal view and the modal view is our own custom implementation of a ui view controller representable so what this does is that it uses app kit to set up a and create a ui hosting controller and it uses the view that we passed in which is the swift ui view as the root view and then we create a demo create our own coordinator there and what we do here is that we add a um we add our coordinator which is a ui adaptable presentation controller delegate so what this does is that it gives us two hook two hooking functions that we can use to provide a behavior that uh that stops the user from dismissing the sheet so we have two functions here which is a presentation controller should be should dismiss so what this does is that um it checks our modal view and it checks the ismodo variable that we already passed into this view and it checks whether or not that one is modal so if we tell if we are from the outside if the swift ui file the swift ui view is setting is modal to true that means that we don't want to allow presentations so presentation control should be dismissed is using this variable directly um another thing we have in here is the presentation controller did attempt to dismiss so i'm not using that at this in this example but if you for example would want to display an alert letting the user know why they can't do the interactive dismissal for example you want to say make sure you save your coffee before you dismiss then that is something that you can do here so you can interact with this and you can get information you can get you can know whether or not the user tried to dismiss the view and if so you can use a variable that you have passed in from swift ui already um or a function that you might pass in from your swift drive view um to determine whether or not you want to you want to present something to the users you you might have some behavior you want to present there or an alert you want to present and you can do that as well and this is what it ends up looking like now we have our custom presentation and if you're trying to type something and you add your coffee and then you can't interact with it this you can't dismiss it interactively um so that's exactly the behavior we want and it's something that is it's a bit it's a bit of work to add at but i think it can be really valuable if you want to provide that functionality and you want to prevent the user from accidentally just dismissing everything while they're in the middle of adding information because i think that can unfortunately easily happen and it can be quite frustrating um so last thing i just want to wrap up and talk about some takeaways and i think overall swift ui has been a really exciting framework for us to use and we end up using it for all of our apps so i think overall we have um i think swift gi is a good tool tool that you can start using now but you have to keep in mind that it is still early and you have to remember that there might be things that you want to add yourself so it can be useful if you know your eye kit or you might want to be prepared to learn some jar kit or app kit if you want to add certain functionality um but again there's a lot of things that you can do just with swift ui on its own um but if you if there is functionality you're missing you can always bridge over which i think is is great and that's actually really can be really helpful um and that's everything from me uh thank you so much for watching my talk and i hope you have a great conference and if you want to talk to me and just either if you have any questions about the talk or if you want to chat you can reach me on twitter i'm at marlinsonburg and you can also check out the giptabripo or you can send an email um and if you are just interested in orbit and want to check out a an app that's using swift ui or if you are looking for a time tracking and invoicing app you can check that out as well and i'm also sort of sharing my journey in building orbit and in in bootstrapping a project on developercommentary.com so you should check that out as well if you want to hear more from me thank you so much and yeah enjoy the rest of the conference
Info
Channel: iOS Conf SG
Views: 3,031
Rating: undefined out of 5
Keywords: ios, singapore, apple, iphone, ipad, iosconfsg
Id: 0MAc-hjvKqw
Channel Id: undefined
Length: 33min 21sec (2001 seconds)
Published: Wed Jan 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.