How to use Futures and Promises in Combine with SwiftUI | Advanced Learning #20

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] all right welcome back everyone i'm nick this is swiffle thinking in this video we're going to look at future publishers this is basically a wrapper that where we can take functions that have regular escape enclosures and convert them into publishers so that we can use them in combine all right welcome back guys i am back in our xcode project uh-huh anywhere else would we be right uh the last bunch of videos were way longer than i had expected and thankfully i'm happy to announce that this video is going to be significantly shorter uh and in this video we are going to cover futures which are a lesser-known feature of the combine framework they're actually included inside that framework let's right-click the navigator create a new file for the code in this video it will be a swift ui view and let's call this futures boot camp once again make sure we're in our regular target and not in our testing targets now let's click create and once we're inside let's click resume on the canvas and we are not going to use the navigator for the rest of this video so i'm going to close it up and make the text a little bit bigger so hopefully you guys can see it well i do have a new microphone here and we are recording in 4k so i hope the quality in these videos is getting a little better up to your guys's standards uh we're not going to do much in the view in this video but we are going to do a little bit in a view model so let's create a class and call it futures boot camp view model view model let's make it conform to observable object and as always let's let's observe that object from our view with an at state object object private var let's call it vm and we'll set it equal to a futures bootcamp view model open and close the parentheses to initialize a new one so most of the work we're going to do in our view model here first we're going to put a very simple at published var let's call it title of type string and we'll set it equal to starting title for now just so that we can see it let's put that on the screen by referencing the vm dot title and click resume just to make sure we get that title up here and inside this view model we're going to create an init and when we initialize we're going to call a function called download let's just call it download for now so we call download when we init and the way this video is going to be set up is first we're going to create a fake function to download with combine just so we can see what the code should look like when we're using the combine framework so these fun this function will have a publisher and a subscriber we will subscribe to the publisher and we'll get all the publishes this is what i did in the last video i've been doing this all along if you've been following my courses but then we're going to look at how to download with closures and more specifically the at escaping closure so i've also covered at escaping in a previous boot camp but essentially when we are working with asynchronous code if that code is does not support publishers and subscribers and it is not supported basically by the combine framework the way we have to use it is using at escaping and closures so this is basically like the legacy way of how we worked with asynchronous code before combine became a thing before we started subscribing to publishers and subscribers which i love doing and highly recommend but before all that all the frameworks that predate that are based on asynchronous code that revolve around using these closures so the question becomes in our apps if we are using any of those functions that are based on this ad escaping how can we convert that code so that we can use it with combine so that we can convert the ad escape enclosure into a publisher that we can then subscribe to in combine and the purpose here is that if we're using combine across our entire app and then we run into maybe a couple functions that that are not publishers and we want to convert those to publishers so that we can then use them in our pipelines and intermingle them with all of our other publishers and subscribers we need some way to convert the closure data to a publisher and if that sounds confusing don't worry because we're going to clear it up in literally about five minutes the third thing we're going to then do is convert an at escaping closure to combine we're going to convert some functions using the regular closures into publishers so that we can use them with the combine framework all right so firstly let's create a func here let's say uh get combine publisher open close parentheses open the brackets so if we were using the actual combine framework uh let's we would do something like urlsession.shared.datatask publisher for url and we need to pass any url here so let's just up here maybe create a let url equals url with a string let's do uh https colon forward size photoslash let's just do www.google.com and i'm gonna force unwrap it here with an exclamation point uh be careful doing that in your actual code but that's not what we're focused on right now so here we're gonna pass in our url and we know this url is not gonna actually have any data there's no data this is not actual get request so let's just give it a timeout so that it fails after one second and let's do that on the dispatch queue.main and after that let's dot erase to any publisher all right so i want to return this publisher from this function here so let's actually return any publisher sorry and we don't have access to any publisher yet because we did not yet import combine and let's return again any publisher with type string error and let's just convert it to a string actually before we return out of here so in here let's just map uh whatever value we get let's just create an underscore here and just return let's call it new value all right and it looks like uh this is actually giving us a url error so we can just put that here url error so again this is not what i really want to focus on in this video but this is like a typical combine publisher we create a publisher it's any publisher and then in our actual app we could subscribe to that publisher so in our app we could then let's download using this publisher so we could say get combine publisher and that's going to return us a publisher and we can maybe sync the value so we'll get a completion which we're not going to use and this will be the returned value let's create a weak reference to self here and we can set self dot title equal to the returned value all right so if i click resume and we need to store the subscriber somewhere so up here let's create a var cancelables we'll set it equal to a set of type any cancelable open close parenthesis and here and here we will store in our cancelables all right if i click resume on the canvas here uh when we initialize the view model we're gonna call download download is gonna get that publisher subscribe to it and when we get a return value we're gonna update it so if i press play here after about one second because our timeout is one second uh we're just gonna force map whatever value comes back from that which we know is not going to be actual data uh to the word new new value and we put it on the screen so again this is not what we're focused on but this is what it should look like if we can use combine we have publishers and we can convert them even to any publisher and then we can subscribe to those publishers awesome so before we had this datatask publisher that supports publishing and combine and all that we had at escaping closures so just to show you an example let's say funk get let's call it escaping closure open close parentheses open the brackets all right and in here we're going to call urlsession.shared.datatask and now i want to point out here so before we had these awesome publishers before they even came out because these were only available in ios 13 and above before that we had these methods here so they don't have the word publisher because they're not publishers instead these have completion handlers so let's use this first one with a url and a completion handler here and we're going to pass in our url and then of course we have our completion handler so if i click enter on the handler it's going to return us back data a response and an error and because this is asynchronous code we can't just return here i've covered all of this in previous videos i did a whole video on downloading with combine and downloading with escaping which are probably prerequisites to this video but if we wanted to return values from this function we would create some sort of completion handler and it would be add escaping and then that handler would be a function that returned void and inside that function we would pass in some values so we can do an underscore and the first value we'll call it uh we'll call it let's just call it value of type string and then another underscore and we'll do uh error of type error and the error will be optional so then inside this closure we want to call that completion handler so here we can call uh completion handler we'll pass in let's do the value as maybe new value 2 and then the error will be nil for now and finally in order to actually execute this and do the actual data task we need to call dot resume all right so i'm going to put the canvas back on the screen here and let's call this escape enclosure from our code so coming up here right now we're using the get combine publisher i'm going to comment that out and instead we're going to use get uh escaping closure and we get our completion handler here so we can press enter and we get a return value and an error let's call it return value uh and i'm gonna make it weak just like we did above and then here we get itself dot title equal to the return value if i click play on the canvas here we should see that new value 2 popping up and what i really want to get the point across here is that when we have these publishers we can nice and easily use combine we can get publishers and then we can subscribe to publishers and that's what we did here we are subscribing to the publisher and i do this throughout pretty much all my videos all the courses i've made so far we have subscribed to publishers however there are functions and usually it's frameworks and libraries that predate combine so before we have publishers and subscribers that you're going to use that will actually have these at escaping closures so when you get a closure like this you can't actually just subscribe to it so if we had an app where we had all these big combine uh pipelines where we were subscribing to all these different sources and then manipulating that data in a pipeline and then syncing that across our app we wouldn't be able to use this data with all of our combine pipelines so the question is how can we convert something that has an ad escape enclosure into a publisher that we could then use with our combine framework so coming down here i'm going to create another func and let's call this get future publisher open those parentheses open the brackets and this just like up here we returned any publisher here we are going to return a future which is actually a publisher and we can see here is a publisher that will eventually produce a single value and then finish or fails so the only difference when we use these futures is that it's producing a single value where our regular publishers can possibly keep publishing over their lifetime and be subscribed to them forever the difference here with futures is that they produce one value and then that's it so it's not the exact same as a publisher but for that one value we can use it and subscribe to it just like we do with any other publisher so here let's create a future and the future will have type string and let's just do a regular error and of course in this function we need to return a future i'll open the parentheses and use the attempt to fulfill we can see here attempt to fulfill a function with at escaping and then we have a promise and a promise is basically just uh the function promising that it will return a value in the future so let's click enter here and i'm going to call this value a promise and very simply all we're going to do in inside this future is call our ad escape enclosure so here i'm going to call get escape enclosure and then we have our completion handler so i'll click enter on the completion handler this will be the returned value and an error and we are inside a closure here so we actually need a reference to self on the get escape enclosure here and then in here we basically can fulfill our promise so this promise as we read in this future is either going to finish or fail so here we can decide if we want this promise to finish successfully or fail now we know we're just returning nil here because we didn't build out this entire function but if there was an error we would probably want to fail so we'll say if let error equals error and then we can call promise open the parentheses and then in here we can see that we have to return a result and the result is either going to be a string or an error and that matches up with the value that we put in right here so of course this is going to be a failure and the error will be the error that we got back we can say else so if there is no error which we know there's not going to be we can call promise and we can call dot success and the success has a string which will just use the returned value all right and now that we have our future built out and because all we're doing in here is returning the future we actually don't even need the word return here we can now call our get future publisher so coming up here i'm going to comment out our get escape enclosure and the same way we ever get combine publisher i'm going to uncomment all this and we're just going to call get future publisher let's click resume click play on the simulator and just like that we have new value 2 coming on to the screen so you might not have even realized what happened here but we took a function that was an escape enclosure so this is an escape enclosure there's no publishers or subscribers in this function this is just a closure that has uh some data coming back and a completion handler so this is pretty much how we did asynchronous code prior to ios 13. so something like this where you had your ad escaping and you get your closure and all we need to do is wrap that function inside a future and then we can fulfill the promise of that future uh based on the return values inside the closure so obviously in your actual app there'll probably be some different logic here but if there was an error you can force an error and if it's successful you can then send out that success so we converted this ad escape enclosure into a future publisher and because it's a future publisher we can then subscribe to it we can sync to it we could then combine latest and combine it with some other publishers in our app and do some really cool uh data manipulation with the combine framework so that's kind of the whole gist of this video we can take closures that do not have publishers and convert them into a publisher that will emit one single value and we call that a future publisher so let's do one more even simpler example just to get you guys used to this so let's create a func here and let's just call it um do something open with parentheses open the brackets and in here we'll call it dot dispatchqueue.maine.ace after dot now plus maybe four seconds and then we can execute some code and this again is a closure so if we wanted to return a value out of here if we wanted to return a string let's just say in here we could try to return new string well we're going to get that error again i've gone through all this in previous videos that we can't just return when we're inside this asynchronous code and that's because this is taking four seconds to complete and this return function here should be synchronous it should happen immediately not after four seconds so the way to work around this would be instead of returning a string here you return through your completion handler with add escaping and we can pass in a value which will be of type string and this will return void and then we would call completion with a new string so now we have our completion function and to convert it let's say funk do something let's call it in the future open with parentheses open brackets and this will return us a future with a string and let's do uh never because this future will never fail and here we can return a future attempt to fulfill with a promise and of course we'll call self dot do something with our completion handler here and click enter and it's never going to fail so we can just call promise dot uh success and we can pass in our value so again this whole video in a nutshell is right here we get asynchronous code with the ad escaping and we can convert it to a future publisher that produces one single value so up here we had the option of failing and succeeding here we are just succeeding because this future publisher has a never has an error but i think this is enough to get the point across so when you start running into a lot of especially a lot of third-party frameworks but even some of apple's frameworks like cloud kit they might not have publishers and subscribers yet if it is some sort of asynchronous code that goes out and fetches and returns a single value we can very easily wrap it in a future and then convert it into a publisher all right guys that's it for this video uh do not forget to hit the like the subscribe button if you want to stay updated and as always thank you all for watching i am nick this is swivel thinking and i'll see you in the next video [Music]
Info
Channel: Swiftful Thinking
Views: 721
Rating: undefined out of 5
Keywords: swiftUI future, swiftui futures, swiftui promises, swiftui combine, swiftui combine futures, swiftui combine promise, how to use future combine, how to use future swiftui, how to use combine, what is a future swift, what is a future swiftui, what is a future combine, Combine futures, combine future, combine promise
Id: yCGbhbFK8sY
Channel Id: undefined
Length: 21min 25sec (1285 seconds)
Published: Wed Nov 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.