SwiftUI Tutorial - Movie List TMDb iOS App | Full Video

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone will come to the first part of the tutorial series in this series we'll be building a mobile ease app using the MDB api and cui first let me show you the completed application using the simulator will have a wall true of all the features that we are going to build one by one we have a movie list as the home screen of our app there are four sections now playing a coming top rated and popular for each section we use a carousel where users can scroll the movies in a horizontal direction for the narrow playing section we show the posture image of the movie using a portrait aspect ratio for the rest of the sections we show the backdrop image using on landscape aspect ratio and a title tax when users tap a movie on the list the app will push the movie detail screen in this screen we show all the pieces of information related to the selected movie at the navigation bar we have the title for the backdrop image in the next section we have the camera run time for lecture and the for a few description also the sir rating represented by the Khan of stars in the following section you have list of cast directors producers and screenwriters in the last section we show the list of trailers when users tap on the trailer will pass the YouTube URL to the sever webview using a model sheet presentation within this users can watch the trailer directly from the YouTube website let's move on to the second tab in the home screen the movie search field in this view we have a search bar located at the top where users can type to search for movies the search results are shown in a list with the title and really share of the movie when users tap on a movie we push the movie detail screen that's all the features of the app that we'll build in this tutorial series to summarize we have three main screens please detail and search to fetch the movie data we are going to use the MDB api so please make sure to sign up into the movie DB dot orc website after you log in click on the API from the sidebar we'll be using the API key free three L's to authorize the API call you can see the example requests here you need to pass the API key in the URL param there are several endpoints we'll be using in our app we're going to fetch the movie lives that's on the know playing upcoming top rated and popular also to show the movie detail screen we need to fetch a single movie bypassing the ID using this endpoint finally the search movies will be using the Search API by adding the credit tax when the users in the request that's it for the introduction of the movie lists we're going to focus on building the movie model and tmdb API surface first let's create a new Xcode project select single view app and type cui movie DB as the project name set the project into the directory that you prefer to the model for the movie next let me open the JSON response of the movie list API with visual studio called side by side from the project navigator let's create a new folder and name it models in the folder create new zip file name movie declare the movie model using a strap that implements the card able protocol also looking at the JSON response at the root level we have the results key with an array of JSON movies as the value let's declare move the response structure person this as you can see tmdb is using snake as convention for naming the fields in Swift we are going to use camel case for naming the properties will customize the guess and the color key decoding strategy the comfort from snake case later let's move on to create a protocol that represents or API surface from the project navigator create a new folder name surfaces then create a new file name movie surface declare the movie surface protocol before we declare the methods we need to create the movie list and point innama this enum represents the endpoints for the movie list API it has four cases not playing upcoming top rated and popular we use string as the route type of the enum for not playing and top rated we override the default value to use mckay's the raw value will be appended to the URL path of the movie list API later we also declare the description for each case so we can show it in the movie list to represent error when making our API call we need to declare movie error innum that conforms to Swift error protocol for the simplicity of this tutorial we declare five error cases API error which is a generic error 'invalid endpoint which is an error when constructing the endpoint URL invalid response which is an error when the HTTP response status code is not in the range between 200 and 300 no data error and at last Sara Lee's Asian error which is a JSON decoding error to show the error tax to the users we implement the localized description computed property in the body we return the copy text for each of the error cases to print the error text properly when the error is casted as NS error we need to conform to custom NS error protocol and declare the error user info dictionary property in this case we use the NS localized description key with the value of localized description that we created earlier for the movie surface our first method is for fetching the movie lists given a movie list and point innum as the parameter the parameter also accepts an escaping closure using the Streif result type the type of success data is movie response and for the error we use movie error innum the second method is for fetching a single movie given an ID of the movie the type of the ID is an integer the parameter of the success closure is the result type with the movie as the success data the last method is for searching movies when given a query string as the parameter the type of completion closure is the same as the fetching movie list above next let's move on to build the concrete class that implements the movie surface create a new file named movie star in surfaces directory repair the movie store class make it confirms to move his office protocol we're going to use the singleton pattern for this class by declaring a static shared constant and set the initializer as private this will make sure the instance can only be initialized once in the runtime next let's declare the API key constant copy the API key phiiiy from tmdb website by logging into your account past it in here it looks like there's an error here where I incorrectly instantly at the movie surface protocol instead of the movie star class in the shell constant next one is the best API URL constant let's take a look and the HTTP requests main in your app for the hostname let's copy and paste it into our code the URL is HTTP API dot the movie DB with all LG you'll also need to add additional path which is three for the API version to make an URL request let's declare the you enunciation using shared illustration from the system will also need a JSON decoder to decode the data let's create another class named Newton's third Swift in here we declare the JSON decoder as well as the debt for manner using static property the JSON decoder key decoding strategy is to convert from snake case as the jessamine response from tmdb is using snake case naming convention we are using a custom get formatter for the date decoding strategy for the death upon format let's take a look at the JSON response it is year month and day which translates to yyy - mm - DD let's go back to movie star - refil the play early getting the color constant with the failure of json decoder property from yuto's class let's implement all the required methods for the movie surface protocol before that let's create a helper method plot and decode an URL into data using generic method we'll meet the constraint the generic placeholder to make sure it conforms to decodable protocol the method also accepts an optional dictionary as the parameter this will be converted to URL parameter some encoding format the completion closure result-type with the generate pass order as the success data type declare the URL components constant by initializing URL components truck it accepts an URL the initializer itself returns optional instance so we need to use guard here if the failure is nil we just complete passing failure with invalid endpoint next we declare the query items variable it contains the array of URL query item URL query atom itself is a struct representing URL parameter key and value first we have the API key URL param the value is the API key constant we copied from the MDB dashboard next we use a flag to unwrap the params dictionary if the value is not nil we append the param by transforming it into an array of URL query item by assigning the key and value let's assign the query items variable to URL components query items property at last we can access the URL components optional URL property using the guard statement by using this approach all the query items will be escaped using the safe person encoding format max we use the URL session data task method by passing our final URL inside the closure we check if the error is not nil if yes we call the completion closure as in failure with API error as the result type but as you all know the URLs ation that a disclosure is being called in the background thread to make sure we call the result completion in the main thread we need to declare a helper method this method accepts the completion closure and the result using generic placeholder so we can constrain the data only for decodable type in the method Noddy we use dispatch cue men as seen to switch to man thread and invoke the completion closure passing the result failure let's use this helper method in the data task completion handler just like so next let's use the guard statement task the URL response the URL HTTP response type we can use the tilde equal operator to check if the status code is between 200 and 300 range if not we return earlier by passing invalid response error as the result of the completion closure let's unwrap the data using the guard steadman if it is nil let's return and pass the no data error the completion closure class we need to deport the data using the JSON decoder the taught method passing the generic class holder type that conforms to decodable protocol as this method can throw an error we need to wrap it in do try catch block if no error you just invoke the completion closure by passing the success decoded data as the result value if an error is thrown when recording we pass the surly zation error after salt to the completion closure at last to make sure it works correctly we need to invoke resume we will also need to repair the weak self to make sure there is no return cycle when we reference self inside the closure let's implement fetch movies body first we declare the URL bypassing the best you pol stream slash movies slash the raw value of movie list and point if the URL is not nil we invoke the lot and the code method asking the URL as well as the completion closure the swift compiler can automatically resolves the generic pass holder a smoothie response truck confirms to decodable protocol let's copy and paste the same implementation for all the other methods we just need to change the URL for each of the method for fetching a single movie we're going to append the ID as the last pass component also we need to pass additional parents in this case we're going to pass the append to URL response with the failure of video and credits finally for the search movie we are going to use the slash search slash movie at the URL path for the additional parents we set the language - and - us and also we make sure not to include the adult content in the response the region is going to be us and at last we have the query key this will be the text that user types in the search bar next let's create an extension for the movie give it a name of movie first stop at Swift in this extension we declare a static helper stop for array of movies as well a single movie this will come in handy later when we build or feel using the CFU I live preview to do this we need to import a JSON response files into our project create a new folder named ressources and drop the JSON response files into the folder you can then load the JSON files by cloning or downloading the project from the github repository by using the link that I provided in the description to help us to load and code the JSON file from the bundle let's go and help our extension for the bundle this is a generic method that accepts the file name of the Gazin as the parameter using the bundle for our sources method we asked the system for the URL path in the app Mandal if found will coat the JSON using the JSON decoder from the utils class let's declare a static variable names top movies the top of this is an array of movies using the extension method that we have declared earlier we're going to load and cut the Gazin by passing the movie lists as the filename as this is just a stub use in the bugging we can just force unwrap the failures next for our single stop movie we can just use the stop movies failure by accessing the first index we're going to build the movie screen it shows the image of the movies with in horizontal chorus all sections along the way we're going to build image loader observable object to fetch images from the network and cache it with an ax sketch in memory cache also we'll create the movie state observable object to fetch movie list data given an end point so just now playing or upcoming movies so either food or I do let's start coding and build or app containing from part 2 where we have built the movie model and movie surface tmdb epic client now let me open the preview of the UI will creep will start building the movie backdrop card it has an image with 16 line 9 aspect ratio and a text inside a vertical stack crying new folder name feels from the project navigator then create a new CPU I file name movie that drop heart not Swift before we implement this view we need to create image loader observable object to fetch image from the network so all of you can subscribe and update when the image has been downloaded successfully from the project navigator create a new folder named bindings then create a new suit file name image loader let's import UIKit as we are going to store your image as the property inside our class cache the data locally we use an S cache this class is similar to a dictionary but it has a built-in mechanism automatically release objects from the memory if the system memories are low we also store this as a global variable we declare image loader class and make it conforms to observable protocol we also declare our image and it's loading properties using published property wrapper with this in place safe UI fu will be able to observe and update the view whenever one of the property is assigned with new value we declare the image cache property and assign it using the global and a sketch variable that we declare earlier let's fix the build issue by importing CV UI instead of foundation let's create a lot image method that accepts an image URL as a parameter first we get the absolute string of the URL and aside in a variable this acts as the key to retrieve the image from the cache if the image exists we assign it to the image property and return to download the image a synchronous Lee I am going to switch to default background thread using this patch queue make sure to mark self as we love what return cycle then we can use the blocking data initializer that accepts an URL to download the image if no error is thrown we initialize uiimage using the data in a guard statement if success we cache the image using the URL tax as the key at last we switch back to the man track and update the image property let's go back to movie backdrop card file and start implementing the class the first property is the movie instance the second one is the image loader observable object we need to add observe object relative wrapper for the view to receive notifications when the published properties are updated to display image and text vertically we can use fistic to wrap the spews we will set the alignment as leading let's use C stack as the container for the image then we declare the tax using the movie the title as the failure we use a rectangle shape as the pass order when image is new we set the fill color as black with 0.3 as the opacity value next we used if condition the check if the image value exists if yes we use the image view passing the UI image to the initializer to make the image resize we need to use the resizable modifier let's use the live preview to see the results we need to pass the stop movie in the preview as you can see the Cystic feel all the remaining space within the view we can limit this by either using a frame modifier or an aspect ratio modifier in our case if the backdrop image is using 16 by 9 aspect ratio we need to use aspect ratio modifier and pass fit as the content mode let's also pass corner radius as 8 to make the corner a bit rounded and set the shadow radius to 4 to download the image from the network we need to invoke the image loaders lot image method and pass the image URL we can use the on appear modifier to fetch the image when the field appears on the screen as we only have the backdrop path string we need to create a computed property to generate the backdrop you are we generate the backdrop URL we need to prefix it with image dot tmdb that OLG / t / p / w 5 0 0 then we can append a backdrop path string as the last path let's update the invocation by passing the backdrop URL make sure to tap on the arrow button and does the project you should be able to see the results of the gun on image in the left preview let's move on to the next part to build the movie that drop causal so we can put the backdrop card feel in our horizontal scroll view from the project together in the views folder create a new C fui file named movie backdrop carousel viewed of safe the first property is the title of the section the second one is the array of movie instances make sure to pass the properties in the previous Eliezer in this case we can just pass a hard-coded string and stop movies array let's implement the body of the view we'll use a fist as the content of you we also set the alignment bleeding and spacing to zero at the top we show the text containing the title using modifiers we set the phone using paddle style one way to vault and add a default horizontal painting below the text we have the scroll view with the access set to horizontal we also set the show indicators as false to hide it when scrolling to make a codicil in a scroll view we need to use H then set the admin to top and spacing to 16 inside we can use for each passing the movies array let's make movie model conforms to identifiable by using identifiable protocol CFU I will use the ID property to give to failure when the array changes in the closure with initialize movie backdrop card by passing the movie instance and return it also we are adding four leading item if it is to first item in the array and the padding for trailing if it is the last item in the array also just by not after the recording of this video that instead of doing this we can also add the horizontal painting in the h2 gravel you can use that approach as it's more cleaner with additional logic let's build and run the live preview looks like the image is overflowing the container of view to fix this we need to use the frame modifier and constraint the with two 272 and the haste to 200 result still looks pretty weird we need to make the text line consistent in this case we have to limit the number of the lines to only one so let's go back to the movie backdrop card and had unlimited modifier and pass the value as one the result is looking pretty good let's try to scroll the parasol in a horizontal direction to make sure it works correctly let's move on to the next part in this part we'll be focusing on building the movie parcel card that shows an image using portrait aspect ratio trigger new CI file name movie poster card in the fields folder let's at the movie as the instance property and the image loader observable all jet using observed object property rapper don't forget to inject the stop movie in the preview just like the backdrop card we use these stacked to the container view in this case we use an if condition we check if the image is not nil then if yes we declare the image view advertised ibill modifier set the content mode to fit also we set the corner radius to eight and shadow to four if image is Neil we show so rectangle placeholder with great color and opacity set to 0.3 also on top of that we show a text containing the title of the movie with Central Admin in case the imaged or not fails at last using the frame modifier on C stack he constrained with tu-204 and hate to 306 make sure to add on up here modifier inside the closure we invoke the image loaders image method passing the posture URL but before that we need to create a computed property to generate the URL using the posture backpacks properly you'll select the approach we use beginner already the backdrop URL let's run the live preview and see the results okay looks good let's move on to show the postures in the car create a new file name movie poster carousel viewlets with in the fuse folder plural tidal stream and movie sorry as the instance properties at last stop the values in the preview we use feedstock to the expected title and posture cut vertically set the feedstock almond bleeding and spacing to 16 at the top we have tax containing the title fun in the title style and fun way as well and we also add a horizontal adding in websites blow that we declare our scroll view with horizontal axis and set the shows indicator as false then we use horizontal stack with a lineman set the top and spacing of 16 using for each we pass the array of movies in the closure we need shall as the movie poster card passing the movie at last we at leading heading for the first item and trailing heading for the last item let's run left preview and seed results whoa looks nice with all the views in place we can move to build the movie screen trade a new sea view I file name move Elizabeth's roof fetch the movie list given an endpoint from IMDB API we need to create an observable object create a new C filename movie listed in bendings folder let's import swift UI at the top then the claire movie list ed class and conforms to observable object protocol we have three published properties the state of fetching the data array of movies it's loading boolean and error which is in an error let's also declare the movie surface interface and store it in a constant in the initializer we inject the service with movie store as the default value we declare lot movies method with one parameter which is the movie list end point before fetching the data were a set all the properties and then invoke movie surface fetch movies passing the end point in the closure make sure to use week on south to avoid memory and settle it's loading to false then we can use switch statement on the result in if success will retrieve the response a shield failure and access the result property and then as I need to remove this property if fail we assign the error as shedded failure to error property when fetching the movie data you want to show some kind of visual feedback to the user so let's build this component create a new file name activity indicator feudal thrift inside you are keyed fuels folder in uikit we can use UI activity indicator view for this purpose what is if UI doesn't provide this kind of view to solve this hi pal profits UI view representable protocol where we can use it to show you I could feel in a three few I view declare a new strop name activity indicator view that conforms to UI view representable there are two required methods to implement the first one is the Mac UI view method that expects us to return and you of you this protocol is using associated type generic in this case we replace the placeholder with UI activity indicator view in the body we initialize the field passing large as the indicator style then we invoke start animating then return to view the other method is update UI view map in our case we can leave this as empty let's move on to the next component where we'll use the activity indicator view in create a new file name in loading view dot Swift the purpose of this view is to act as a container for the activity indicator view when we load the data from the network and if an error occurs we have to stat properties this loading and error also one optional protocol show that we call ret reaction in the body implementation we use the group view in this view we can return a different view depending on the conditional condition if it's loading is true we'll return the activity indicator view inside a hatch stack between a spacer to Center it if error is not nil we show the error copy in a V stack if the retro a closer exists we add a retro button that invoke the closure given by the parent for you let's see how this work later on when we build to move in this view let's go back to the movie ListView file and begin implementing the view the approach we are going to use here is to fetch the movie list endpoint independent of each other in this case we have four movie lists end points so let's declare for observe object properties for each of the endpoint not playing upcoming popular and operated in the body we'll use a navigation view that's the route view because we are going to push the movie detail screen later on then we declare release view as the vertical scroll view for the car results for each of the movie lists state we are going to check if the step movies array properties exists if exists we're going to display the carrizal view else we display that the loading view we just built in the previous section or they're not playing section we use movie poster carousel view to show the posture image for the rest of the sections we use movie backdrop corazon view to show the backdrop image in the loading field a try closure we need to pass the correct endpoint to refresh the data in tests of the trying and error we set the navigation bar title as the movie DB finally we need to add on-air modifier on the navigation view so we can fetch the data when the navigation screen appears on the screen let's try to run the app in the live preview awesome the movie data is successfully displayed on the screen but there are two things we can improve first the horizontal painting on the carousel looks hot second one we have to remove the line separator for each row when using a ListView we can use the Leafs role in stats modifier to customize the inset in four directions in this case we want to set the leading and trailing 2-0 so the carousel can scroll scrub edge to edge we also want to add some inserts on the bottom and top padding so there are particles at spacing between sections currently in cui there is no API that we can use to remove the separate or from the list but there's a little hack that I found where we can use UI tableview appearance proxy and set the separator style none so we can remove the separator for the reminder this will remove this operator for all the lists in the CV UI app in our case this is the behavior that we want we'll be focusing on building the movie detail screen along the way we are going to fetch the data for a movie then display pieces of information in a list finally we'll learn how to display a safari view controller in safe UI to show the YouTube video using UI view controller represent the below so let's open Xcode and start coding we're going to continue from part two where we have successfully built the movie screen let me open the preview file to show you the movie detail screen first we'll focus on building notification title and the movie banner image let's create a new file named movie detail field of swift in the fuse holder a movie ID instant property inside the class we'll pass the ID of the selected movie when instantly adding this view next to handle loading data from the tmdb API we need the credit observable object create a new save file named movie detail state declare the class that implements two of sufferable object protocol declared the movie service API client as a private constant for the published properties we declare movie is loading and error then we create an initializer with movie surface as the parameter then we assign the movie star singleton as the default value we said it removing surface instant property in X declared a lot movie method it accepts a single ID integer as the parameter first we set the movie to nil and set its loading to false to rest the state then we invoke fetch movie passing the ID of the movie inside the closure make sure the declare itself as weak to avoid memory leak when referencing south then set its loading to false and use a switch statement on the result in um in case of success will retrieve and assign - agility failure to movie property then for a failure case assigned as I said failure to the error property now forget that to the movie detail view then declare the movie detail state property using observe object property wrapper assign the movie little state instance as the default failure also we need to pass the movie ID in the movie detail view initializer located at the bottom of the file let's implement the body next we use sister as the container of you then we declare the loading view passing is loading state and optional error property with this the activity indicator of you will be shown when the movie is being fetched in the rhetoric closure we just invoke the lot movie passing the movie ID to reload the data before we declare the list let's set the navigation bar title first the value is the title of the movie as it can be empty when fetching is still in progress we need to provide an empty string as the file that failure make sure to add on up your modifier while we load the movie and passing the ID to the state when the screen appears also to enable navigation in the live preview we need to wrap the movie detail view in the preview class at the bottom for the list we create a new view called movie detailed ListView declare a movie constant as a single property in the body we use ListView as the container at the top of the list we have the banner image of the movie let's create a new component for this as it has its own state to handle the loading of the image from the network prepare a new few name movie detail image to handle loading the image we declare the image loader of surf object as the property and also the image URL to load in the body we declare our sister at the bottom we use a rectangle as the best holder when fetching the movie we set the fill color to gray and opacity to 0.3 using the modifier on top of that we check the image has been downloaded then we declare the image passing the image data and sell it to resizable then using the aspect ratio modifier at C's that we set the aspect ratio to 16 by 9 and content mod as with at last we use the own appear modifier to fetch the image passing the image URL let's declare this into the top of the movie detail list view and see the results with the live preview looks like we forgot at the movie details view inside the movie detail view so let's edit at the top so let's build and run it again yeah looks good let's remove the extra padding on both horizontal sides by setting the literal in sets and pass H inserts top leading bottom trailing 2-0 moving on to the next part we're going to build the section containing the information of the movie genre release year runtime overview and writing as the movie model currently doesn't have general added property we need to create it first let's take a look at the gate and response it's actually an array of JSON objects containing the ID and name now forget to the movie dot shift file we clear the gun rest property in the movie the type is an array of movie gallery at the bottom of the file declare a news truck named movie gallery and confirms to decodable protocol next declare the single property name we don't need to be declared ID as the property go back to the movies truck and declare a computed property called gender attacks in the implementation we just get the first index for real generous array and use the name property next we create a computed property to show the rating stars name rating tax first we cast the fault average W property to an integer this will remove the fraction and run down the number to simplify the logic to display the stars as we are going to use a star emoji to show the rating by using a half closed range operator that starts from 0 to the rating integer we use a reduced method to add and accumulate the value which stars emoji at last we return their soul besides the stars count will display the score of the rating in terms of one to ten declare the score tax property using Garth Steadman in check the count of rating tax is greater than zero if yes we just use string interpolation on the rating tax and so fix it with slash tan the next one is the tax for the year to show the year we need to create a new debt fermenter and set the format to yyy with the formatter we can use a guard statement to invoke the get debt from the release debts tax and then use the year net formatter to get a formatted string from the date the next one is the tax for duration we can use the runtime property for this it is a representation of total running seconds for the movie the formerly show in the format like one hour 30 minutes we can use that component for matter Plus declare the duration for matter set the unit style to full and allowed units to hours and minutes at last we can use the formatter and pass the runtime second of the movie multiplied by 60 because the formatter expecting a unit of minutes let's go back to the movie detail ListView below the movie little image declara h tag inside we declare the text containing general text text containing hard-coded dot string as a separator the text were movie here and the tax for movie duration moving on to the next row let's declare the movie overview text then we declare an H tab if movie reading text is not empty we display the Stars reading text and set the foreground color to yellow then at last we display the score tax let's use a divider below to add a horizontal line for a clearer visual spiration between sections in the next section we'll show the credits of the movie cast directors producers and screenwriters we need to add the credits property to the movie model let's take a look at the guess in response the movie jason has credit spill containing Jason of crews and costs for the cast we only need the name property while for the crews we need the name and the job with job we can filter the crews desk on the producer director and screenwriters let's not forget that the movie that Swift file scroll to the bottom and add a new trap name movie credit next declare a movie cast trap @ib character and name as the property then declare movie crew with ID job and name of the properties go back to the movie credit and the player cast property with movie cast array as the type and cruel probability with movie crew array as the type with this in place we can declare the credits property which is using movie credit as the type we'll set this as optional as this property is not return when we fetch the movie lists API next we declare the cast and crew's completed property with this we can retrieve the cast and crew from the credits property to get the directors producers and screenwriters we declare the completed properties inside we just filter the crew array that's on the job stream director producer our story now let's go back to the movie detail view and build the credits section to stack the cast and crew horizontally we can use H stack set the alignment as top and spacing to four then we declare our fee stack with alignment of leading and spacing of four to stack the staring tasks at the top we show the title text and set the phone as headline then using for each we pass the test of the movie in this case we only want to display the first nine cast so we can use the prefix method in the array in the closure we just display the name text of the cast or looks like the compiler is complaining as for each needs movie cast to come from the interval protocol let's add this to the strap we had a frame modifier azing 0 as minimum with an infinity as the maximum with then we add a spacer we'll use this sort of aesthetic and have equal spacing with the orifice tab containing the crews that will create next next we declare the V stack for the cruise data a screws can be and Daniel will use conditional before declaring the V step first we check if movie directors count is greater than 0 then we declare the directors tax and using for each passing the array of Directors in this case we only want to show the maximum of two crews let's also add the same conditional check for the movie cast as it is possible for the cast to the MD then let's move this into the edge stat to show it besides the cast make sure to set the phone as headline for the heading tax let's do the same approach for producers and writers also add some padding in the producer and screenwriter text to add some vertical spacing that's it for the crew sections don't forget to add the Defiler at the bottom next let's move on to create the trailers section whenever the user taps on one of the trailer will present a model sheet showing the Safari V controller containing the YouTube page for playing the video let's create the movie video strap to represent the trailer navigate to the movie instance and declare this truck at the bottom of the file let's take a look at the guess and response for the videos we'll be needing ID key name and site then we declare the movie video response truck with results property containing array of movie videos to match the yes in response hierarchy at last we declare a computed optional property called YouTube URL as video can come from a different site in our app we only want to show the trailers from YouTube so using God Stedman we check if the site equals to YouTube then we construct the URL there prefixing it with HTTPS youtube.com slash watch and adding additional URL param passing the key property back to the movie body we declare our videos property with type of optional movie video response then at last declare a YouTube trailers computed property which returns an array of movie videos with a file YouTube URL let's go back to the movie detail view below the last divider we check if the movies YouTube trailers array is not empty if X is we show the trailer tags set the phone as sub-headline we use for each and pass the trailers in the closure we use a button and let's leave the action closure and evil now for the view inside the button we declare an H tack on tanning the text of the trailer named spacer and image with SF icon with the name of played circle that fill then we set the foreground color to system blue next we need to create a view to host the Safari V controller create a new file named suffer if you in you I confuse folder import Safari surfaces and CPU I at the top of the file to host a V controller in CV wife you we can use the provided you I feel controller representable protocol eclairs our review and make it confirmed to UI view controller presentable we need to implement two required methods let's declare one instance property name URL the first required method is Maki IV controller which expects us to return a UI v controller in this case we replace it with safari view controller in the implementation we can just initialize it pass the URL from the instance property and return it let's leave the other method implementation as empty go back to movie detail view then declare a state property to store the trailer when the user selects from the lists then in the button action closure we just need to assign the selected trailer to the property to present the model sheet we just need to add sheet modifier at the bottom pass the selected trailer state as the binding item then in the closure we just initialize and the Tron Safari view passing the trailer from YouTube growl let's try and run from the live preview to make sure everything works scroll to the bottom and tap one of the trailer nice the Safari VC is presented perfectly there's one little dock though where when we dismiss the model the image banner will blame out of nowhere I don't really know why this happened maybe it's a buck from Serie UI but I have found a solution we just need to declare of surf object for the image loader in the movie detail ListView and pass it to the movie little image so let's do this try to run again looks like all is good finally we need to add navigation lien on the movie screen so it can navigate to the movie detail screen whenever the user taps on the movie from the carousel in the list let's add this to the movie backdrop carousel and movie call stir colors all views we just need to wrap the view in navigationally then pass the movie little view in initializer also we need to set the button style as plain Latin style otherwise the image will be overlaid by a blue background let's try and run the app to test the navigation just select a movie from the list and voila you successfully navigate to the movie detail screen we're going to build the search movies feature into the app we'll learn on how to use us search bar on safe UI and using the combine framework the throttle of survival query text type by the user before we make an API call without further ado let's open Xcode and start coding we continuing right off from the previous part where we have successfully built the movie detail screen that shows the pieces of information of a single movie let me open the preview file to show you the search screen will build the search movie screen has a search bar located at the top of the screen then a lease for showing the results over the movie search by the user each of the movies has a title and release your text the movie screen itself is located in the same hierarchy as the movie list screen using a top bar view at the bottom from the project navigator create a new Civ UI file named movies search view let's fill the body with a navigation view at the root level so we can navigate to the movie little screen when the user taps on the row in a list declare the list put a single text for a placeholder so we can build the project without error we need a search bar at the top of the screen as if UI currently doesn't have a search bar component we need to breach us search bar to sift UI using UI few representable protocol declare a new SIM file name search bar view inside the uikit first folder imports if you eye at the top of the file then declare the search bar view struck that confirms to you I view representable protocol there are two properties we have to declare the first one is the pass holder text the other one is the text string as the parent view will pass the state we need to use binding property wrapper so I navigate to this property will be propagated back to the object who owned the state next let's implement the required methods the first one is the meki uiview method let's use us search bar as the return type in the body we initialize UI search bar passing 0 as the frame rectangle assign the placeholder property with the placeholder property we declare then set the search bar style as minimal set the enable certain keys automatically as false so the return button is always enabled effin if the text is empty a PLAs will turn the search bar the second one is the update UI fu method which invoked the first time your search bar shown in this case we assign the text property value to the search bar text before we can use this view we need to receive a callback whenever the user is typing on the keyboard so we need to implement UI search bird delegate which requires a class type to solve this Apple prophets a way for us to use a coordinator object let's declare the chord another class as a subclass of nsobject also let's come from the UI search bar delegate protocol declare a text property using binding property move rapper as this is a class type there is no default initializer we need to create it by ourselves then inside the initializer we to prefix the tax with an underscore to assign the binding past in the initializer as the projected failure for the UI search bar delegate methods the first method we implement is search bar tax the change in this case we update the text property using the search bar stacks following method is search bar search button click in this case we want to dismiss the keyboard we can use the search bars resign first responder method at last we need to implement the mentor another method to initialize and return the coordinator object let's initialize the coordinator and passing the tax binding using the Euler prefix as the parameter don't forget to implement and set the search bar delegate to the contacts coordinator in the Maki IV method let's never get that to the movie search view and declare the search bar view at the top of the list it requires us to pass the binding text we need a state property let's use an officer Ville object for death deterrence if filename movie search stayed inside the bindings walder import stiff UI combined and Foundation at the top the clear movie search state class that confirms to observable object below we have four published properties that represent the state of the movie search first the tax which the user types second movies and narrator percent in the response of the search movie from the API third is loading a boolean property representing whether the data fetching from the API is currently in progress fourth error and an S error that indicates if there's an error when making the API call we'll use the combine framework to subscribe the observable tax value and throttle the updated value to one second so new wait until the user stops typing on the keyboard up to one second before making an API call it helps to reduce the number of API calls when the user is typing fast as we don't have to fetch the data every time the user types a new character the player subscription token property to store the token we'll be removing the token in the object get the initialized declare the movie service property then create an initializer that accepts a movie service the default value is the movie store let's assign this to the movie surface property let's declare a method name start off serve which will be invoked when the movie search free appears on the screen using the on appear modifier first using guard steadman which have if the subscription token is not nil if it exists will return early to access the observable from the query we can use this dollar sign as the prefix we're going to use the office herbal chaining first we use a map operator this allows us to transform the valley to another value in this case we only want to result the error and the movie properties values then return the same value for the following chain operator we use throttle passing one second as the interval set the schedule to be dispatched in the main thread using this patch queue main then our strew are still at us as we don't need to receive the initial query value we use the sync operator to subscribe to the value from the chain in the closure we receive the value of the query and invoke the search method passing the query let's declare the search method that accepts a single parameter which is the query string here we reset all the state properties to the default value then using guard statement we check if the query text is not empty for your info combined also provided a filter operator that we can use before in the observable chain I'll lift that to all of you as the exercise to practice using the combine framework next we set the East loading property to true then using the movie service we invoke the search movie method passing the query in the closure we declare self as week to avoid memory leak very time cycle then using guard we check on the current value of Cuervo body equals the query we pass to the search movie API it's possible when the searching is still waiting for the response from the API the user already types a new search query at last we set is loading back to false and use the switch statement on the result in am failure in case of success we assign the movie property from The Associated value and in case of failure we assigned an error property with casted and as error finally we need to remove the subscription token of surfer in the they ended by invoking cancel so the object and the release from the system's memory go back to movie search view and declare the movie search step property using observable object property wrapper let's complete the search bar view implementation and pass the binding query text from movie search step let's run the live preview to see the results of our work let's add the navigation bar title using a hard-coded search string we'll need to fix the extra horizontal padding on both sides by using this row in sets modifier we can pass eight as leading and trailing value let's run looks good next let's declare the loading view to show the loading indicator when we fetch the search result from the tmdb API in the initializer we pass the east loading state property from the movie state the error and return closure in the closure we invoke the movie switch state search movie asking the query text let's declare the list for showing the results of the movie we need to use if conditional statement will check if the failure of the movies from this thread properties is a nil then we used for each pass in the movies array to the initializer in the closure we'll wrap the field using a navigation link so the user can navigate to the movie little view when the row is tab in the navigation link we declare a vista with leading alignment and then we declare the title and your text for the movie next make sure add-on appear modifier and inside the closure we can just invoke the movie search state start off source method let's build the app and run the live preview type into the search bar to search your favorite movie then tap on the road to navigate to the movie detail screen let's move on to the final part where we will add the tap view containing the movie list and movie search screen within this same hierarchy we get the content view the swift file in the body declared tap view as the root view then for the first step we declare the movie list view then by using the tap edom modifier we can customize the title and incan of the tap meet the use of his tag then we declare the image passing DV from the SF symbol as the next system name then for the text we pass movies we also need to add a unique hash above that modifier for each tab let's pass 0 for the first step let's do the same for the second map the movie search view for the image we use magnifying glass' FF symbol and for the text we use search string let's pass 1 as the tag failure that's it let's build and run the app from the live preview to test the top bar is not shown at the bottom and we can switch tabs between movie lists and the movie search congratulations on finishing this tutorial to summarize we have built a custom search bar component using us search bar with you I feel representable then we created the movie search state of several object and use combine to subscribe to the observable query text in the process we used to use the observable operator to throttle the query text finally we built the top bar content the movie list and movie search within the same hierarchy thanks everyone for following the tutorial series if you like and want to support this channel please like share and subscribe it really motivates me to keep producing video tutorials so until the next one let's keep the lifelong learning goes on bye
Info
Channel: Xcoding with Alfian
Views: 10,256
Rating: undefined out of 5
Keywords: swiftui, iosapp, iosdevelopment, tmdb, mobileapp, coding, swift, tutorial
Id: cTNhMgNV53s
Channel Id: undefined
Length: 75min 49sec (4549 seconds)
Published: Thu Jun 11 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.