More Videos

  • SwiftUI On All Devices

    Once you've learned the basics of SwiftUI, you've learned what you need to know to use SwiftUI anywhere. You can use the same SwiftUI skills for making an iOS app as you would for making an app on watchOS, tvOS or macOS. We'll cover the basics, and then dig into more detail about how SwiftUI can help you make changes to your app on every Apple device. Hear about design principles for each platform and learn about how much code you can share across platforms. See how to incorporate device-specific features and how to make changes in SwiftUI by following along with a starter project, available for download.

    Resources

    Related Videos

    WWDC20

    WWDC19

  • All right, thankyou.Welcome. It's so great to seeyou all here and it's great tosee so many people excited aboutSwiftUI.My name is Jeff Nadeau.I work on macOS frameworks andI'll be joined in a little bitby my colleagues Ada Turner andMeghna Sapre .Now we hope you've had the chance to learn about SwiftUIall throughout the week but ifyou need a summary, here it is.SwiftUI is the shortest path tobuilding great apps on everydevice.And what we're here to focus ontoday is the 'every' in everydevice.

    Now when we think about buildingapplications for all of ourApple devices, these are thetechnologies that we thinkabout.We use AppKit on the Mac.UIKit on iPhone and iPad,TVUIKit which is built on UIKitfor Apple TV, and then on thewatch we use WatchKit.These UI frameworks weredesigned around the strengthsand capabilities of therespective devices.And so naturally there are somedifferences between them.And historically we haven't beenable to take code written forone and move it over to anotherdevice without modification.But for the first time ever,we're introducing a UI frameworkthat you can use on any of thesedevices.That's unprecedented and it's abig opportunity for you as appdevelopers.But these devices are sodifferent so how is it thatwe've built one UI frameworkthat works on all of them?Well, SwiftUI was built from theground up to accommodate manydifferent UI paradigms.So whether you're using akeyboard and mouse, or a multitouch display, or the Siriremote, or even the digitalcrown on your Apple Watch, orassistive technologies likevoiceover and switch control,SwiftUI was designed toaccommodate all of these.And it has great support for ourplatform design conventions outof the box.We've brought together expertsfrom every platform to make surethat when you use an element inSwiftUI on a given device thatit looks and feels right athome.The result is a system whereyour knowledge is transferrableacross devices.Everything fits together in thesame way.So even when you're workingwith-- you're building supportfor some specific piece ofhardware, say the Touch Bar on aMacBook Pro or the digital crownon an Apple Watch, or the Siriremote, the tools for doing thishave a kind of consistency andfamiliarity that makes themreally easy to pick up.Now, on top of just generaldesign philosophy we also have anumber of elements that are incommon across-- SwiftUI acrossall devices.So for example, every platformhas the idea of a togglecontrol.You've got some kind of piece ofBoolean state that you want tobe able to toggle and you have alabel describing what you'retoggling.And so even though ourexpression of this control couldbe very different on eachdevice-- it might be a switch ora check box or a toggle button--we can offer a single API thatdescribes this on any device.

    SwiftUI also has a common layoutsystem.So when you're using a stack ora spacer or a padding, thesetools work the same on everydevice. And what that means is that onceyou've learned to lay out anapplication on one device,you've learned how to lay out anapplication on any.We also have some more advancedcontrols like picker forexample.Picker picks one element from alist of many and this controlexpresses itself in a variety ofways. So on MacOS it might be a pop-upbutton.On iOS or WatchOS it might bethis wheel style picker.And given how different theyare, you might not use themcompletely interchangeably fromdevice to device.But the one thing that'sconstant is the relationship toyour data.When you've adapted your modelto work with one of these controls, you can easilytransplant that from device todevice.Now we don't have time to goover all of the differentelements available in SwiftUI soyou should check out the SwiftUIessentials talk for moreinformation about that.Now, does that mean that I canreally use SwiftUI to design asingle app that's going to workgreat across all these devices?Is it going to let me write codeto adapt seamlessly from a 4ktelevision all the way down to a44 millimeter watch face?Well of course not.

    You know, there's no such thingas a one size fits all app.If we decided to just stick tothe common denominator betweenall these devices, we'd bemissing out on the things thatmake each device great.And there's no magic abstractionthat can do that for you.You have to decide what theright design is for your app oneach device.Now what SwiftUI can help youwith is you can share your skillset and toolset that you'velearned building from one deviceacross many others.

    And there are definitely goingto be opportunities to sharecode along the way, just whereit makes sense.And so we think it's kind ofimportant to think about thisless as write once and runanywhere and more like learnonce and apply anywhere.Now to put these principles intopractice, we need to build anapp.

    But really it's more like we'vebuilt four apps, one for each ofour platforms.

    And the app that we've built iscalled Landmarks.The purpose of Landmarks is toresearch and visit landmarksthroughout the country.We definitely want to look atphotos and get visitorinformation about these places.I think it would be great to getmaps and directions to adestination.

    And if we're planning a trip,marking favorites is a greatidea. And when we think about bringingthis app to all of our devices,we can tell ourselves a storyabout how we think the appbelongs and fits on each one.

    So for example, on AppleTV it'sa natural place to couch surffor places to go.And because it's a big screenexperience, that might besomething that you do withfamily or friends or roommates.And we definitely want to markfavorites to research later.And the Mac would be a greatplace to do that research.It's a good place to compare andcontrast info, maybe have somemore advanced sorting andfiltering controls, and reallyread up on all the details.On iPhone, we obviously wantquick information about eachlandmark but since it's socommon to navigate with ourphones, we should also be ableto get driving directions aswell.

    And iPhone of course is also aphone so if we need to place aphone call to call ahead, it's anatural place to do it.Finally on Apple Watch, that'swhere we want to get at-a-glanceinfo about what's most importantto us.And it's the perfect platform toreceive important notificationswhen anything changes.Now the cool thing is that theiOS version of this applicationis already available to youtoday.It's part of a new documentationseries to teach you how to viewSwiftUI.You start from the verybeginning and you can build thisapplication up step by step.It's already available for download today and it's a greatway to learn how to build an iOSapp. And so as a result, we're goingto be focusing more today onbringing this application toAppleTV, Mac, and Apple Watch.And to start us off on thatjourney, I'd like to hand itover to my colleague Ada Turnerto talk to us about SwiftUI onAppleTV.Thanks Jeff.Hi. My name is Ada Turner andI'm really excited to talk toyou today about SwiftUI forAppleTV.

    Designing apps for the TV meansdesigning for the biggest,boldest screen in the entirehome and that comes with somechallenges and considerationsunique to AppleTV.Luckily, SwiftUI allows you tocreate great experiences thatare optimized for the livingroom using the same skill setand toolset that you've learnedwhen developing for Apple'sother devices.

    Today I'd like to focus on threekey points for designing greatexperience on the biggest,boldest screen.TVOS is a 10 foot experience,not a mobile experience.People interact with your appsusing the Siri remote not atouch screen or a mouse andkeyboard.And it is especially importantfor TVOS apps to havestreamlined navigation so peoplecan jump right into your app'scontent.Now, what is a 10 footexperience?It's this, not this.

    Your apps should emphasize richand immersive experiences likebeautiful imagery or video asopposed to accomplishing taskslike taking notes or gettingdirections.

    When sharing SwiftUI code withyour AppleTV app from otherdevices, carefully considerwhich experiences make the mostsense when displayed on a largescreen viewed from across theroom with longer periods of useand potentially more than oneviewer at a time.Let's take a look at whichfeatures we decided to supporton Landmarks for TV and whichones we left on the cutting roomfloor.

    The easiest choice to make wasto include the gorgeousphotographs of the landmarkswhich will look great on the bigscreen.Gathering in the living room topick out favorites together isone of the key features of ourTVOS app so we can't forgetthat.

    And we'll also include basictourism information such ashours of information and cost sothat people can make informeddecisions about where they wantto visit as they browse.

    Now, although our data supportsit, we decided that we're notgoing to include lengthy detailsabout the history of eachlandmark as content like thatreally isn't appropriate on theTV.We also decided not to includeadvanced sorting and filteringas features like that make a lotmore sense on the Mac or iPad.And finally, although our dataincludes geographicalcoordinates, we decided not toimplement geofencednotifications as traveling withan actively running TVOS app isa very rare use case.Next, let's talk about focus.People interact with TVOS appsusing the Siri remote which isoptimized for effortlesslyswiping through your app'sinterface.It is critical that your entireapps interface be intuitivelynavigable using focus.Luckily, many of SwiftUI'sstandard interface elements suchas lists, buttons, text fields,and toggles, all work seamlesslyon TVOS, adopting differentappearances and behaviors thatlook great on the big screen andinteract using focus.

    If you implement your own customcontrols, SwiftUI provides afocusable view modifier thatallows you to control whether ornot your view can become focusedand execute a block of code whenyour view gains or loses focus.You can also use the on playpause command and on exitcommand view modifiers torespond to people pressing theplay pause and menu buttons onthe Siri remote when your viewis focused.

    Thank you.Finally, let's dive into somebest navigation practices onTVOS.

    Long, vertically scrollingtables of content with deeplynested levels of navigation workgreat on the Mac or iPhone, buton TVOS people want aneffortless browsing experiencethat emphasizes content.Using SwiftUI's easilycomposable stack views, listviews, and scroll views, we cancreate an interface like this onLandmarks for a TV with verticalstacks of horizontally scrollingshelves that really takeadvantage of the widescreendisplay on the TV and allowpeople to browse betweendifferent categories withouthaving to navigate betweendifferent pages.

    First, let's take a look at howwe might structure the top levelnavigation of a SwiftUI app forAppleTV.Tab view is the primary means ofnavigation for many TVOS apps.It allows you to break yourapp's content up into distinctcategories that are easy toswitch between and provides apersistent indicator at the topof each view that lets peopleknow where they are in your app.

    Navigation view allows you tonest pages of content andoptionally display a navigationbar with a title or buttons.

    I'd like to make a quick note onstructuring your app's top levelnavigation on TVOS versus iOS.

    On iOS if you use a tabbed view,it will typically be the toplevel view of your app and eachof its child views may be anavigation view with your app'scontent as the navigation view'sroot view.With this structure, when peoplenavigate deeper into your app'scontent, the tab bar will remainvisible allowing people toeasily switch tabs at any time.Here on photos the tab barremains visible on the bottom ofthe screen after navigating tothe details page so that peoplecan easily switch tabs withouthaving to navigate backwards.

    However, on TVOS if you use atab view you will actually wantto make the navigation view thetop level view of your app andset its root view to the tabview with your app's content asthe direct children of the tabview.With this structure, when peoplenavigate deeper into your app'scontent, the top bar willdisappear and we want thisbehavior because TVOS is allabout full screen experiencesthat emphasize your app'scontent.

    Here on photos for TV the tabbar disappears when we navigatedeeper into the album's detailsso that people can focus on thecontents of the album.SwiftUI views are highlycomposable so it's super easy torearrange your app's navigationstructure for TVOS.The nested relationships betweenthe tab view, navigation views,and content views, are allvisually indicated by theinherent structure of your code.Now, let's put some of theseprinciples into practice andtune up landmarks for TV.First we will no longer beneeding this navigation barbutton title.

    Next we'll get rid of thisnavigation button and dataheader label.

    Let's see how this looks.

    This is definitely animprovement but we've got a waysto go.This long, vertically scrollinglist doesn't quite feel right onTVOS so let's use a scroll viewwith a nested HStack instead ofa list.

    And let's display all of thelandmarks within a categoryinside of a row.

    Let's take a closer look at therow.

    It's very similar to categorylandmarks with the addition of aVStack containing a header labeland an HStack wrapping the foureach landmarks.One thing to note here is thatinstead of a plain text view,I'm using a custom view calledlandmark card as the label forthe navigation button and I'msharing this view directly withthe iOS app.Let's give this a run.

    This is starting to feel a lotbetter.By changing only a few lines ofcode, I now have a nice, biginviting buttons with images anda vertically scrolling list thatreally takes advantage of thewide screen.One thing I'd like to point outhere is that while we're stillusing the exact same navigationbutton view in landmarks row,its appearance has changed.The chevron on the right handside of the view is gone and thebackground is different.This is because navigationbutton is no longer beingdisplayed in the list view andhas automatically adapted itsappearance.Now, while the horizontallyscrolling content looks great onthe big screen, it might be alittle too horizontal.Let's vertically stack thecategories by changing the mainview's HStack to a VStack.

    And adding a nested scroll viewaround the row's HStack.

    Let's give this a run.

    Ah, this is feeling really,really great.It's super easy to browsebetween different categories andbrowse the landmarks within eachcategory.

    Finally, let's take a look atthe details page.Well, this beautiful edge toedge photograph of the landmarkwould be looking pretty nice ifit wasn't obscured by all ofthis high density text.Let's see what we can do to makeimprovements for AppleTV.So let's take a look at thedetails view.It's a pretty simple view.We have a background displayinga photo of the landmark, afavorites button, and somehistoric details.Let's try displaying tourismdetails.Try one last time.

    Ah, that's looking so muchbetter.Only the most relevant detailsare being displayed with nicelarge fonts that are easy toread from across the room.We can mark a few landmarks asfavorited for when we do moredetailed research on landmarksfor MacOS.

    Now, back to you Jeff.Thanks Ada.I love that Ada was able to takea pretty standard list-based UIand really make it feel at homeon AppleTV just by rearranging acouple of pieces that shealready had.I think that really shows howpowerful this framework is.So now let's turn our attentionto MacOS.Now there's a lot that goes intomaking a great Mac app and Icould probably fill the wholehour if we had it, but I'm goingto focus on a few key pointsthat SwiftUI can really help youwith-- high information density,multi windowing support,keyboard shortcuts, and supportfor the MacBook Pro Touch Bar.Let's start with highinformation density.

    We generally have a lot ofscreen real estate to work withon the Mac and so we can usethat to provide more informationat a glance.That can make it easier to makemore, to make better decisionsand make comparisons if you haveall that information all in oneplace.

    And because we have a precisionpointing device on the Mac, wecan tolerate smaller clicktargets and denser controls.Now that doesn't mean that yourapp should look like an airplanecockpit, but it does mean thatyou can provide more functionality in one place andleave more room for yourcontent.And the Mac is a great place toread lots of text content if youhave text content.So app sessions are often longeron the Mac and you're usuallyusing it seated so it's verycomfortable to just scrollthrough some text and read it.Now SwiftUI automaticallyadjusts the spacing and paddingsbetween elements to beappropriate for the Mac.And you can use the control sizemodifier to access the small andmini sized controls that we haveavailable on the MacOS system.And that might be great if youwant to make an entire inspectoruse small controls.

    Next multi windowing.You know multiple windows havebeen just a staple of the MacUIfor decades, and people loveusing multiple windows.They love using multiple windowsto compare content acrosswindows side by side.It's often nice to pull a singleitem out into its own window soyou can focus on it in detail.And many people love organizingtheir windows spatially acrosstheir desktop and spaces.And these are all capabilitiesthat you unlock if you supportmulti windowing.And SwiftUI makes this supereasy. I'll show you an example of thatin a little bit.Next, keyboard shortcuts.Keyboard shortcuts are anessential part of a MacUI.Mac users and especially powerusers love using keyboardshortcuts to access commonactions and just fly throughyour app's navigation.And supporting keyboardshortcuts in SwiftUI is reallyeasy and I'm going to show youan example.So let's say we have a tab view.We've got three tabs forexplore, hikes, and tours, andwhat we want to do is bind eachof these tabs to command one,two, and three, so that we canswitch between them reallyquickly.Now when we want to set up akeyboard shortcut on the Mac,the first place that we go isactually the Mac menu bar.We like to put keyboardshortcuts into the Mac menu barbecause it makes them morediscoverable and it ensures thatwhatever actions we're hookingup here are also accessible ifyou're using just a mouse.Now you could do this in code.I've gone ahead and set it up inmy storyboard.And then what I've done isdefined some commands for eachof these keyboard shortcuts.A command is just a name for acommand that can be sent throughthe SwiftUI hierarchy and we canuse them to wrap the selectorssent by each of these menuitems.

    Putting it all together, all wehave to do is use the on commandmodifier attached to the viewthat we want to recognizecommands on.In this case we pass in thecommand that we just defined amoment ago, as what was a blockof code to run when the commandoccurs.Here we're just setting theselected tab variable that ourtab view is already bound to.So when we use one of thesecommands, the selected tabvariable updates, the tab viewnotices and updates itself aswell.

    If you want to know more aboutrecognizing keyboard shortcutsand other system levelintegrations like this youshould check out the integratingSwiftUI talk from this year.

    Finally, the Touch Bar.The Touch Bar is another greatway to accelerate common actionson your Mac.It brings the most common andcontextual actions right at yourfingertips.And supporting the Touch Bar inSwiftUI is easier than ever.

    I'll show you an example.We define a Touch Bar in codeand then just like we'repopulating a list or a stack, wejust put the elements that wewant in the Touch Bar one byone.

    And when we want to attach thisto a view, we'll just use thedot Touch Bar modifier, passingin the Touch Bar that we're justdefined. And it's that easy.Whenever this view is the focused view or the nearestancestor of the focused view,these controls will appear inthe Touch Bar hardware.

    Now let's go back to our demo sowe can put some of these intopractice for Landmarks forMacOS.

    Okay here we are in Xcode.

    Let's just build and runLandmarks for MacOS so we cansee where we're starting.

    Okay, we have a fairly standardmaster detail view here wherewe've got a list of landmarks onthe left and the details on theright.

    We've also added some filteringcontrols so that we can gofilter down by category or wecan choose to see only ourfavorites.Now the really neat thing isthat this list I've got here onthe left side is actuallysomething that I shared completely with iOS.And that was great.It gave me a really big headstart to making this app.And I didn't have to do anyadaptation.I didn't have to adapt it to anew data source or delegateprotocol or anything like that.I just got it for free.

    But I do think that this listcould look better on the Mac.I wish I could see more elementsin my scroll view at once andI'd love to have more details ineach row.

    Let's start by taking a look athow this is defined.In our landmark list we've goneahead and actually defined a Maclandmark list that wraps thislandmark list which is a commonelement that I discussedearlier.Structuring our project likethis is really handy because itmeans that I can still mostlyshare the implementation of thislist but it gives me a place toput my Mac specificcustomizations.Let's follow this to look at howthis is defined.We have some filter criteriathat just describes theconfiguration of our filtercontrols that we looked atearlier.We have a binding to theselected landmarks the list-- sothat the list can show andmodify it.And we have some user data sothat we know what landmarks arefavorited.And the list is pretty simple.You've probably seen this anumber of times already.We have a list we use for eachto iterate over all of ourlandmarks to display.And then we create a landmarkrow for each one.And this is a hard-coded typehere. It's just, this is the type ofrow that we're using right now.Now we could start doingsomething like poundif [assumedspelling] to exchange whatlandmark where we're using oneach OS but I really don't wantto do this as a hack.I want to build a tool that Ican reuse.And so let me show you how I'mgoing to do that.

    So I'm going to redefine thislist to be generic over the typeof landmark row that we're goingto use.And then I'm going to add aproperty which is a closure fromthe landmark to the row typethat we've just defined as ageneric type.

    And then instead of using ahard-coded type here I'm goingto delegate the creation of therow to my block.Now, to adapt that in my Maclandmark list, all I have to dois update my type definitionhere, add the closure that Ijust described, the row provider, and return a row type.Luckily like any good TV demo Ihad one baking in the oven allalong so we'll just use thatone.

    Let's take a look at how thatlooks now.

    Now this is a lot better.My rows are a little bit morecompact.I've added some more details toeach one and I can even see at aglance which ones are favorited,and that's really nice.And the great thing here is thatmy list implementation is stillcompletely shared.So if I still had-- if I hadlike really advanced filtering,sorting, or grouping logic, orif it was especially fancy,let's say I had someasynchronous work that was goingto a database or to theinternet, you know personally Ionly want to write that codeonce.And now we can and we don't haveto compromise on our design todo it.The next thing that I'd love tobe able to do is to double clickone of these rows to pop it outinto its own window.And that's also really easy.I'm going to show you how.The first thing that we need todo is create a window and on theMac, even when we're definingour views with SwiftUI, we useAppKit to define our windows.

    Now I could do this in mystoryboard but the code isreally short so I'm just goingto show it to you.We have a window controller andthen I've defined a convenienceinitializer that takes a SwiftUIview, puts it into a hostingcontroller, and then creates awindow around that hostingcontroller.I've also written a little bitof convenience code here thatjust keeps track of whichwindows exist per landmarkalready so that if I doubleclick on a row that already hasa window, it'll bring theexisting window front instead ofcreating a new one every time.

    Let's go back to our list andadd this integration.So, detail-- let's add a quickconvenience method--shared-- to show a window for agiven landmark.And then to attach it to my row,I can just add a tap action witha count of two because I onlywant it to recognize doubleclicks, and then in this tapaction I'll call my show detailfor landmark method.

    Now, when I double click on myrows, I can pull them out intotheir own windows and I can putthem side by side, arrange themhowever I'd like.And because these are stillAppKit windows I can use all ofthe great windowing featuresthat are built in. So if I like tabs I can mergethem into tabs and it's justlike that. I get that completely for freewhich is really great.And with that, I think that theMac version of this app isstarting to look pretty good soI'm going to go ahead and goback to our slides.So now that we've seen SwiftUIon AppleTV and Mac, it's time toturn our attention to AppleWatch.You know SwiftUI is the firsttruly native framework forbuilding apps on Apple Watch andI think it's going to reallybroaden our horizons for what'spossible. And to walk us through some ofthose possibilities, I'd like tohand it over to my colleagueMeghna.Thank you.Thanks Jeff.With SwiftUI and all the amazingthings you've learned so far youare bound to be on track tobuild an app that provides anawesome experience on alldevices.Hi, I'm Meghna and now I'm goingto talk to you about bringingthis great experience to yourApple Watch App.While your experience may berooted in your application,building for WatchOS means somuch more.Complications, Siri shortcuts,and notifications all contributeto showing the most timelyinformation right on your AppleWatch face.Apple Watch is all about showingthe right information at theright time.For the purposes of this talk,I'm going to focus on the appand notifications.We'll start with talking abouthow SwiftUI allows you todisplay elements and lay outyour Apps UI like never before.

    But first things first.A good rule while building anApple Watch experience is to aimfor the primary information orthe most critical action to beavailable within two or threetaps.While designing this experience,the aim isn't to shrink downyour iPhone app but to bring themost timely and relevant actionsto the context of your wrist.With that, let's dive into someSwiftUI simple concepts.If you have content that exceedsthe bounds of a full screen, youcan wrap it in a SwiftUI scrollview.SwiftUI also gives you thisgreat new digital crown rotationAPI which lets you completelycontrol rotation and haptics.This API also opens the door tousing the digital crown in allnew ways to modify interfaceelements.This is something that was neverpossible before.You're also probably familiarwith groups in WatchKit.SwiftUI now gives you much morepowerful ways to organize yourcontent with horizontal andvertical stacks.

    Tabulating information has neverbeen easier than with lists andwith list sections.

    Lastly, identifying what yourusers care about the most onyour Apple Watch App will helpyou decide what kind of data tosurface.With the views and controlsprovided by SwiftUI, you caneasily build an interface thatconveys the most crucialinformation first.Notifications are a great way togive timely updates, however,too much information or contentthat isn't useful may leadpeople to turn them off for yourapp.

    SwiftUI gives you the ability toeasily provide intuitive andbeneficial controls so peoplecan respond from within your appand not have to dismiss thenotification.Making your notificationsactionable as possible, you canallow people to quickly respond.

    When you send your notificationcan be just as important as whatyou send in it.Try to use what you know abouthow someone uses your app andwith that information you cansend the most timely informationat the most appropriate time.With these powerful new SwiftUIconcepts and a betterunderstanding of what makes agreat Apple Watch experience,let's take a look at thelandmarks app where we put someof these concepts to use.Using the app you've built withSwiftUI for all the otherdevices you're going to have afunctional Apple Watch App.However, it may not be the bestApple Watch experience.I'm going to show you how, witha few tweaks and updates, you'regoing to be able to bring thisapp more in line with thecontext of the wrist.

    Well the first thing you seehere is that we've built alandmarks list.For the watch landmarks, we'vegone ahead and customized thedetails cell.We've included an image for somecontext.We've included some tool detailsand we've also added somecontact capabilities.Now some of these things likethe contact capabilities don'tadd too much value to say, anAppleTV app but they work greatinside an Apple Watch App.

    But that was still way too muchcontent to scroll so what wedecided to do is to narrow itdown to just our favorites.To do that we created a simpleSwift filter.

    Since we've narrowed this datadown, we also wanted users tohave an option to see all thelandmarks if they chose to.That was possible with addingthis button.This button simply toggles thestate between showing all andshowing favorites based on theview that you're in.SwiftUI gives you this uniqueability to pick the pieces thatinterest you for your app andcompose the views that work bestfor your interface.

    We wanted to be able to focus oneach cell more when we scroll.With SwiftUI we were able to dothat with the carousel liststyle.This list style is great whenyou have a fewer number of cellsor when you have cells withinteractive controls.Here our cell has buttons forcontacting, for making a phonecall, for adding or removing thelandmark from favorites, andhaving some navigationcapabilities.

    Lastly, notifications.For the landmarks app we wantedto notify you when a new tourhas been added.We wanted to add some images soyou can decide if you'reinterested in this tour.And also give you the ability tobook it from within thenotification.Using the power of Swift, younot only have the textualinformation but you also havethis gorgeous, rich animationmoving the images.Instead of just talking to youabout it I'm going to show youhow we built this.

    So what you see here is thatI've created a structure for anew tour notification.Now I've already gone ahead andhooked this notification up tomy notification controller whichmeans that whatever is in thisbody is what you see inside thenotification after I run thisscheme.

    This struct takes ina landmark as a parameter whichis what the notification willideally pass to it.Now let's go ahead and add sometext.

    Okay so what we've done here isthat we've created a stack thatincludes some textualinformation.The only reason I have a stackhere is because I'm going to addsome more data inside this.

    In here we have decided a structcalled slideshow which takes inan array of strings.These strings are image names.

    We have a variable which iscalled the current index whichis essentially just to trackwhich image you're on at thispoint.

    Tour image is a customstruct that I've createdwhich is a view.It takes in an image name thataligns the image correctlyinside my app.

    Let's see how this looks in thepreviews so far.

    Now, the next thing I want to beable to add here is an ID for animage.That way when we animate this wewill have a proper track of whatview needs to be inserted andwhat view needs to be removed.

    At this point it looks like--okay we have our text here,great-- at this point it lookslike we can go ahead and addthis slideshow struct inside ournotifications body.

    All right so once this updateswe should be able to see thisview here. This looks great.Now like we talked about here,we should be able to supportmultiple images inside thisstruct. For that, we would need tocalculate the next index.Let's go ahead and do that.Now in here I'm simplycalculating the next index andI'm updating the current index.

    What I also want to do isanimate this change.With a simple animation, everytime my current index is updatedit will have some fluid stringanimation which looks prettygood.

    Now, we've created this but wehaven't actually hooked it up toanything.Inside our ZStack ideally whatwe'd want is that after aparticular interval in time we'dwant the image to change andmove on to the next image.So I created an extension on aview which has a view modifier.Show next image is a simple viewextension which essentiallyinvokes a timer that after everytwo seconds switches on to thenext image index.

    Now the last thing I want to addhere is this gorgeous slidetransition we saw, which is thiseasy command right here.Okay, let's see how this looks.

    Okay so we have these imagesscrolling through.We have some actions that we hadhooked up to the notificationcontroller before.

    As you can see--thank you.Like you see, with very fewchanges we were able to createthis gorgeous, rich notificationwhich in WatchOS was never apossibility before.With that, let's go back toJeff.

    All right, thank you Meghna.I think it's so cool to seesomething so rich andinteractive appearing just inthe context of a notification.I think SwiftUI is going toreally broaden the horizons forwhat's possible on WatchOS.Now this has been just awhirlwind tour so let's kind ofrevisit and sum up what we'velearned today.The first thing is that whenwe're thinking about bringing anapplication to a given device,take a design first approach.This isn't about saying thatI've got this code and I'm goingto try and get it working overhere.It's thinking about what's theright expression for my app onthis device and workingbackwards from there.But, you can share some codesometimes.For example, we didn't reallycall it out but every demo thatyou saw today is effortlesslysharing the model code.The model code has been compiledinto each target identically.

    And you can share view code, youjust have to use good judgmentabout when you do it.And SwiftUI can help you alongthe way by making it really easyto re-factor out small, reusablecomponents that make more senseto reuse across devices.

    And finally, we're not here towrite once and run anywhere.The real power is in yourknowledge.When you learn once, you canapply that to any device and Ithink that's really powerful.

    As always, this talk livesonline. There you can see the videoreplay and get associatedresources and I want to thankyou for your time. We cannot wait to see what youbuild with SwiftUI.[ Applause ]