{"id":56186,"date":"2022-12-23T11:55:21","date_gmt":"2022-12-23T06:25:21","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=56186"},"modified":"2022-12-30T12:04:11","modified_gmt":"2022-12-30T06:34:11","slug":"concurrency-with-swift-async-await","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/concurrency-with-swift-async-await\/","title":{"rendered":"Concurrency with Swift: Async\/Await"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">Concurrency is not something we haven\u2019t known, but in Swift 5.5 this is built-in.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Wait&#8230;Why ?? We have been doing concurrent programming for so long and our apps were pretty good and responsive.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Yes, we were able to achieve concurrency in swift by using frameworks like <\/span><b>Grand Central Dispatch (GCD) <\/b><span style=\"font-weight: 400;\">and <\/span><b>Operations. <\/b><span style=\"font-weight: 400;\">They were handy and we made the best use of them to overcome most possible scenarios where we need an async approach similar to downloading images off the main thread and setting the image in image view back on the main thread, persisting data to the local file system, concurrent use of DB (SQLite, CoreData). In situations where some level of dependency was required we may have used <\/span><b>Operations Dependency, DispatchSemaphore or DispatchTasks<\/b><span style=\"font-weight: 400;\"> to manage those scenarios.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">So, Why do we need another API when we have solved almost all our problems with <\/span><b>GCD<\/b><span style=\"font-weight: 400;\"> and <\/span><b>Operations?\u00a0<\/b><\/p>\n<p><b>There are two takes on why we needed another robust threading model.<\/b><\/p>\n<ul>\n<li><b>\u00a0Unstructured, <\/b><span style=\"font-weight: 400;\">Yes though GCD and Operations were good friends in need but had their pros and cons. Like GCD lacks <\/span><b>Structured Flow<\/b><span style=\"font-weight: 400;\"> and both GCD and Operations are unable to enforce compiler-level <\/span><b>concurrency <\/b><span style=\"font-weight: 400;\">checks. So, <\/span><span style=\"font-weight: 400;\">using Swift\u2019s language-level concurrency support for concurrency means Swift can help you catch problems at compile time.<\/span><\/li>\n<li>Swift Concurrency is not built on GCD, unlike Operations, and is designed to be more efficient than GCD by avoiding problems like <b>Thread Explosion.<\/b><\/li>\n<\/ul>\n<p><i><span style=\"font-weight: 400;\">When we talk about concurrency let me emphasize that we talk about asynchronous and parallel code. To learn more about asynchronous and parallel code, Please check out Swift\u2019s <\/span><\/i><a href=\"https:\/\/docs.swift.org\/swift-book\/LanguageGuide\/Concurrency.html#\"><i><span style=\"font-weight: 400;\">official document.<\/span><\/i><\/a><\/p>\n<p><span style=\"font-weight: 400;\">Let\u2019s now understand the modern swift concurrency, It has 3 significant features:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Async\/await<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Structured Concurrency<\/span>\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">async let<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Tasks<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Tasks group<\/span><\/li>\n<\/ol>\n<\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Actors<\/span><\/li>\n<\/ol>\n<p><b>Async\/await <\/b><span style=\"font-weight: 400;\">and <\/span><b>Structured concurrency<\/b><span style=\"font-weight: 400;\"> is mostly used in conjunction to remove the call back type (closure-based) asynchronous programming whereas <\/span><b>Actors<\/b><span style=\"font-weight: 400;\"> help to avoid data races.<\/span><\/p>\n<p><b>Async\/Await:<\/b><\/p>\n<p><span style=\"font-weight: 400;\">To understand Async\/Await it is a must to understand the context of why it is a need in today\u2019s programming. In the early days of programming, it was all about a set of instructions that made our programs jump all around but with programming evolution, we don\u2019t see that today and we managed to have a set paradigm of <\/span><b>structured control flow<\/b><span style=\"font-weight: 400;\"> as you see with if .. else.<\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-56168\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/IMG_0173.png\" alt=\"\" width=\"408\" height=\"460\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/IMG_0173.png 639w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/IMG_0173-266x300.png 266w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/IMG_0173-624x703.png 624w\" sizes=\"(max-width: 408px) 100vw, 408px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Also, with Structured Programming, we get static scoping which means the lifetime of a variable defined in a block will end when leaving the block. So, When our program executes sequentially, it makes our life easier. But with a more evolved CPU architecture, we needed to make our programs asynchronous.\u00a0 <\/span><\/p>\n<p><span style=\"font-weight: 400;\">We\u2019ll talk more about <\/span><b>structured concurrency<\/b><span style=\"font-weight: 400;\"> and <\/span><b>Actors<\/b><span style=\"font-weight: 400;\"> in the later part of this series. Let\u2019s focus on learning Async\/await asynchronous functions over closure call-back hell.<\/span><\/p>\n<p><b>Functions: synchronous vs. asynchronous<\/b><\/p>\n<p><b>Synchronous:<\/b><\/p>\n<div id=\"attachment_56169\" style=\"width: 1168px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-56169\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-56169 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/SynchronousFunctionn.png\" alt=\"\" width=\"1158\" height=\"322\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/SynchronousFunctionn.png 1158w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/SynchronousFunctionn-300x83.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/SynchronousFunctionn-1024x285.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/SynchronousFunctionn-768x214.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/SynchronousFunctionn-624x174.png 624w\" sizes=\"(max-width: 1158px) 100vw, 1158px\" \/><p id=\"caption-attachment-56169\" class=\"wp-caption-text\"><a href=\"https:\/\/gist.github.com\/ankittlp\/d04b67082c991a684b539cd16cb0d7a2\">Synchronous function<\/a><\/p><\/div>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-56170\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.42-PM.png\" alt=\"\" width=\"1518\" height=\"46\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.42-PM.png 1518w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.42-PM-300x9.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.42-PM-1024x31.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.42-PM-768x23.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.42-PM-624x19.png 624w\" sizes=\"(max-width: 1518px) 100vw, 1518px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Here we are calling <\/span><i><span style=\"font-weight: 400;\">someHeavySynchronousTask<\/span><\/i><span style=\"font-weight: 400;\"> from the main thread so this function runs on the main thread only.<\/span><\/p>\n<p><b>Asynchronous:<\/b><\/p>\n<div id=\"attachment_56171\" style=\"width: 1552px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-56171\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-56171 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-09-29-at-1.23.54-PM.png\" alt=\"\" width=\"1542\" height=\"534\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-09-29-at-1.23.54-PM.png 1542w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-09-29-at-1.23.54-PM-300x104.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-09-29-at-1.23.54-PM-1024x355.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-09-29-at-1.23.54-PM-768x266.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-09-29-at-1.23.54-PM-1536x532.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-09-29-at-1.23.54-PM-624x216.png 624w\" sizes=\"(max-width: 1542px) 100vw, 1542px\" \/><p id=\"caption-attachment-56171\" class=\"wp-caption-text\"><a href=\"https:\/\/gist.github.com\/ankittlp\/d04b67082c991a684b539cd16cb0d7a2\">Asynchronous function<\/a><\/p><\/div>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-56172 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.58-PM.png\" alt=\"\" width=\"2034\" height=\"96\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.58-PM.png 2034w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.58-PM-300x14.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.58-PM-1024x48.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.58-PM-768x36.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.58-PM-1536x72.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-20-at-8.02.58-PM-624x29.png 624w\" sizes=\"(max-width: 2034px) 100vw, 2034px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Similar task with an asynchronous call type is a better option to run it asynchronously. We used GCD to dispatch the task on a global queue which uses a background thread, and the main thread was unblocked immediately.<\/span><\/p>\n<p><i><span style=\"font-weight: 400;\">A rule to remember: Sync code blocks threads, async code doesn\u2019t.<\/span><\/i><\/p>\n<p><span style=\"font-weight: 400;\">You may have written code similar to this many times. For eg. URLSession\u2019s dataTask asynchronous method with closure argument.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This is great but it has a bug as it doesn\u2019t complete the task even though my function definition is exactly what it has to be.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Any guesses !!\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If you guessed it right, it is we missed writing the <\/span><b>completionHandler<\/b><span style=\"font-weight: 400;\"> at the appropriate place.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">When writing async code with completion handlers you unblock threads but it\u2019s easy to not call your completion handlers. For example when you use a guard let and only return in the else clause. Swift can\u2019t enforce this in the compiler which can lead to subtle bugs.<\/span><\/p>\n<p><b>The shortcoming of using GCD\/Operations for Concurrent programming.\u00a0<\/b><\/p>\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">No check for concurrency constraints at compile time.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">We can not use try\/catch error handling.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Awkward order of execution. We will end up with a so-called pyramid of doom.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Retain cycles need to be avoided using weak references.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Data Races.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Thread explosions are common.<\/span><\/li>\n<\/ol>\n<p><strong>Let\u2019s improve the above asynchronous function with Swift 5.5.<\/strong><\/p>\n<p><span style=\"font-weight: 400;\">We\u2019ll start by removing the <\/span><b>completionHandler<\/b><span style=\"font-weight: 400;\"> and returning the [Int]. Just as a synchronous function. Now we add the <\/span><b>async <\/b><span style=\"font-weight: 400;\">keyword just before the \u2192 to make this function async type.<\/span><\/p>\n<div id=\"attachment_56173\" style=\"width: 2256px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-56173\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-56173 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncFunctionn.png\" alt=\"\" width=\"2246\" height=\"684\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncFunctionn.png 2246w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncFunctionn-300x91.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncFunctionn-1024x312.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncFunctionn-768x234.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncFunctionn-1536x468.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncFunctionn-2048x624.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncFunctionn-624x190.png 624w\" sizes=\"(max-width: 2246px) 100vw, 2246px\" \/><p id=\"caption-attachment-56173\" class=\"wp-caption-text\">Async function using swift async\/await <a href=\"https:\/\/gist.github.com\/ankittlp\/d04b67082c991a684b539cd16cb0d7a2\"><span style=\"font-weight: 400;\">Code gist link<\/span><\/a><\/p><\/div>\n<p><span style=\"font-weight: 400;\">You may have noticed that the body of func has also changed a little. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">Let\u2019s visit the changes:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Function definition was changed and we removed the completion handler. Instead added the keyword <\/span><b>async<\/b><span style=\"font-weight: 400;\"> to denote the function as asynchronous and awaitable.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Here we are using <\/span><b>Task <\/b><span style=\"font-weight: 400;\">instead of <\/span><b>DispatchQueue.Global<\/b><span style=\"font-weight: 400;\"> to start the operation asynchronously and use <\/span><b>await <\/b><span style=\"font-weight: 400;\">to wait for the operation to finish. This is our suspension point and at this point our func waits for the async task to finish successfully or with error (if throwable task).\u00a0<\/span>\n<p style=\"text-align: center;\"><i><span style=\"font-weight: 400;\">\u201cThe <\/span><\/i><b><i>await<\/i><\/b><i><span style=\"font-weight: 400;\"> keyword signals to the developer that the state of your app can change dramatically while a function is suspended and the thread that the function is on is free to do other work. Swift does not guarantee which thread it will resume your function on. This is an implementation detail that you shouldn\u2019t care about.\u201d<\/span><\/i><\/p>\n<p style=\"text-align: center;\"><span style=\"font-weight: 400;\">\u201c<\/span><i><span style=\"font-weight: 400;\">A<\/span><\/i><b><i> Task<\/i><\/b><i><span style=\"font-weight: 400;\"> is an asynchronous unit that allows us to bridge the async function call from a synchronous context. Also Within the context of a task, code can be suspended and run asynchronously.<\/span><\/i><span style=\"font-weight: 400;\">\u201d<\/span><\/p>\n<\/li>\n<li>Once the task operation is complete and it is ready with the result. Our function will resume from the suspension point. Here it is to notice that OS may resume on any arbitrary thread and not be confirmed to resume on the calling thread.<\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">Do notice the <\/span><b>Task\u2019s value<\/b><span style=\"font-weight: 400;\"> computed property is an async throwable property. We\u2019ll talk about async throwable in a while.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">That is all it took to refactor our closure-based asynchronous function to <\/span><b>Swift 5.5 concurrency<\/b><span style=\"font-weight: 400;\">. <\/span><\/p>\n<p><span style=\"font-weight: 400;\"><strong>Error<\/strong>\u2026 Huh!! But why ?<\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-56174 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFunc.png\" alt=\"\" width=\"2242\" height=\"112\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFunc.png 2242w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFunc-300x15.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFunc-1024x51.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFunc-768x38.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFunc-1536x77.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFunc-2048x102.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFunc-624x31.png 624w\" sizes=\"(max-width: 2242px) 100vw, 2242px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Yes, the function call site is complaining about making calls to asynchronous functions from a synchronous context. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">This is solved by creating a bridge between synchronous and asynchronous context and is done by creating a Task or by making the call site function <\/span><b>async. <\/b><span style=\"font-weight: 400;\">Doing later will just move the error to the call site for the current function. So, We\u2019ll eventually end up creating the asynchronous context.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">So, our call site is from within the Task that creates an asynchronous context.<\/span><\/p>\n<p><span style=\"font-weight: 400;\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-56175 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFuncFromTask.png\" alt=\"\" width=\"1300\" height=\"118\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFuncFromTask.png 1300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFuncFromTask-300x27.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFuncFromTask-1024x93.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFuncFromTask-768x70.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncFuncFromTask-624x57.png 624w\" sizes=\"(max-width: 1300px) 100vw, 1300px\" \/><\/span><\/p>\n<div id=\"attachment_56176\" style=\"width: 2332px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-56176\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-56176 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/ConsoleForAsyncFuncCallFromTask.png\" alt=\"\" width=\"2322\" height=\"144\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/ConsoleForAsyncFuncCallFromTask.png 2322w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ConsoleForAsyncFuncCallFromTask-300x19.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ConsoleForAsyncFuncCallFromTask-1024x64.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ConsoleForAsyncFuncCallFromTask-768x48.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ConsoleForAsyncFuncCallFromTask-1536x95.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ConsoleForAsyncFuncCallFromTask-2048x127.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ConsoleForAsyncFuncCallFromTask-624x39.png 624w\" sizes=\"(max-width: 2322px) 100vw, 2322px\" \/><p id=\"caption-attachment-56176\" class=\"wp-caption-text\">Console log for async func call<\/p><\/div>\n<p><span style=\"font-weight: 400;\">The logs on the console shows that \u201csomeHeavyAsynchronousTask\u201d async func starts on Thread #6 where as Thread #7 perform the heavy task and someHeavyAsynchronousTask is suspended by \u201c<\/span><b>await<\/b><span style=\"font-weight: 400;\">\u201d, Once the heavy task is done and system resume the function someHeavyAsynchronousTask, it is on thread #9.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">As said earlier\u00a0 &#8211; <\/span><i><span style=\"font-weight: 400;\">\u201cSystem may or may not suspend the function\u201d<\/span><\/i><span style=\"font-weight: 400;\">. So, we should not get confused if you see the system resuming back on the same calling thread.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">That was the most straightforward application of async\/await and Task. We\u2019ll talk about Tasks in more detail later in the series.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Let us now see the <\/span><b>handling error<\/b><span style=\"font-weight: 400;\"> with <\/span><b>async\/await<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Syntactically, the <\/span><b>async<\/b><span style=\"font-weight: 400;\"> and <\/span><b>await<\/b><span style=\"font-weight: 400;\"> keywords are used similarly to <\/span><b>throws<\/b><span style=\"font-weight: 400;\"> and <\/span><b>try.<\/b><span style=\"font-weight: 400;\"> So similar to the simple throwing sync function, an async func can throw as well.<\/span><\/p>\n<div id=\"attachment_56177\" style=\"width: 2282px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-56177\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-56177 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorThrowingAsyncFunc.png\" alt=\"\" width=\"2272\" height=\"398\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorThrowingAsyncFunc.png 2272w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorThrowingAsyncFunc-300x53.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorThrowingAsyncFunc-1024x179.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorThrowingAsyncFunc-768x135.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorThrowingAsyncFunc-1536x269.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorThrowingAsyncFunc-2048x359.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorThrowingAsyncFunc-624x109.png 624w\" sizes=\"(max-width: 2272px) 100vw, 2272px\" \/><p id=\"caption-attachment-56177\" class=\"wp-caption-text\">async throws function<\/p><\/div>\n<p>&nbsp;<\/p>\n<div id=\"attachment_56178\" style=\"width: 1666px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-56178\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-56178 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncThrowsFunction.png\" alt=\"\" width=\"1656\" height=\"274\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncThrowsFunction.png 1656w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncThrowsFunction-300x50.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncThrowsFunction-1024x169.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncThrowsFunction-768x127.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncThrowsFunction-1536x254.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/CallToAsyncThrowsFunction-624x103.png 624w\" sizes=\"(max-width: 1656px) 100vw, 1656px\" \/><p id=\"caption-attachment-56178\" class=\"wp-caption-text\">Calling async throwable func from task and handling error. <a href=\"https:\/\/github.com\/ankittlp\/SwiftConcurrency.git\"><span style=\"font-weight: 400;\">Download as Xcode project<\/span><\/a><\/p><\/div>\n<p>&nbsp;<\/p>\n<div id=\"attachment_56179\" style=\"width: 1888px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-56179\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-56179 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorHandllingTaskFailed.png\" alt=\"\" width=\"1878\" height=\"134\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorHandllingTaskFailed.png 1878w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorHandllingTaskFailed-300x21.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorHandllingTaskFailed-1024x73.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorHandllingTaskFailed-768x55.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorHandllingTaskFailed-1536x110.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/ErrorHandllingTaskFailed-624x45.png 624w\" sizes=\"(max-width: 1878px) 100vw, 1878px\" \/><p id=\"caption-attachment-56179\" class=\"wp-caption-text\">Error propagation and structured error handling.<\/p><\/div>\n<p><span style=\"font-weight: 400;\">Here we see how the error has propagated over function call stack.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Also, don&#8217;t miss how asyncAwaitVM object was accessed without explicit self. Better to say <\/span><i><span style=\"font-weight: 400;\">implicit capturing,<\/span><\/i><span style=\"font-weight: 400;\"> that happens whenever we create a Task, or use await to wait for the result of an asynchronous call. Any object used within a Task will automatically be retained until that task has finished (or failed), including self whenever we\u2019re referencing any of its members.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In the start we talked about<\/span><b> Async\/Await<\/b><span style=\"font-weight: 400;\"> help to clear the programming hassle <\/span><b>Pyramid of doom<\/b><span style=\"font-weight: 400;\"> and write our code in structured flow.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Let&#8217;s see with an example.<\/span><\/p>\n<div id=\"attachment_56180\" style=\"width: 1754px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-56180\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-56180 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-22-at-3.11.32-AM.png\" alt=\"\" width=\"1744\" height=\"462\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-22-at-3.11.32-AM.png 1744w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-22-at-3.11.32-AM-300x79.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-22-at-3.11.32-AM-1024x271.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-22-at-3.11.32-AM-768x203.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-22-at-3.11.32-AM-1536x407.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-22-at-3.11.32-AM-624x165.png 624w\" sizes=\"(max-width: 1744px) 100vw, 1744px\" \/><p id=\"caption-attachment-56180\" class=\"wp-caption-text\"><a href=\"https:\/\/github.com\/ankittlp\/SwiftConcurrency.git\">Download as Xcode project<\/a><\/p><\/div>\n<p><span style=\"font-weight: 400;\">The order of execution is messed up. 1\u2192 5 \u2192 2 \u2192 6 \u2192 3 \u2192 7 \u2192 4<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Let\u2019s get it right. Doing so with Async\/Await will require an async version of each function.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">We can easily do it using the refactor support from xcode.<\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-56181 aligncenter\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertFunctionOptions.png\" alt=\"\" width=\"1748\" height=\"1090\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertFunctionOptions.png 1748w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertFunctionOptions-300x187.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertFunctionOptions-1024x639.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertFunctionOptions-768x479.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertFunctionOptions-1536x958.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertFunctionOptions-624x389.png 624w\" sizes=\"(max-width: 1748px) 100vw, 1748px\" \/><br style=\"font-weight: 400;\" \/><br style=\"font-weight: 400;\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Of the 3 refactor options we may choose the option of our need. I chose the <\/span><b>Add Async Alternative<\/b><span style=\"font-weight: 400;\"> and my function was refactored<\/span><\/p>\n<div id=\"attachment_56182\" style=\"width: 1760px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-56182\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-56182 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertedCode.png\" alt=\"\" width=\"1750\" height=\"622\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertedCode.png 1750w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertedCode-300x107.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertedCode-1024x364.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertedCode-768x273.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertedCode-1536x546.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/XcodeConvertedCode-624x222.png 624w\" sizes=\"(max-width: 1750px) 100vw, 1750px\" \/><p id=\"caption-attachment-56182\" class=\"wp-caption-text\"><a href=\"https:\/\/github.com\/ankittlp\/SwiftConcurrency.git\">Download as Xcode project<\/a><\/p><\/div>\n<p><span style=\"font-weight: 400;\">As you can see this refactoring creates an async function with the same name and its body is returning with an awaitable continuation closure. The <\/span><b>withCheckedContinuation() <\/b><span style=\"font-weight: 400;\">function creates a new continuation that can run whatever code you want, then call <\/span><b>resume(returning:)<\/b><span style=\"font-weight: 400;\"> to send a value back whenever you\u2019re ready \u2013 even if that\u2019s part of a completion handler closure. It is to be noted that with this type of refactoring we need to be careful to call tha resume only once.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">I purposely opted to use refactoring using <\/span><b>continuations <\/b><span style=\"font-weight: 400;\">to demonstrate that it will be goto option for APIs we don&#8217;t have an actual implementation source to refactor. But as we have access to <\/span>HeavyOperationApi<span style=\"font-weight: 400;\"> class source, I implemented the async version of the required functions manually.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Learn more about continuations <\/span><a href=\"https:\/\/developer.apple.com\/documentation\/swift\/checkedcontinuation\"><span style=\"font-weight: 400;\">here<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<pre><span style=\"font-weight: 400;\">func multipleHeavyAsynchronousCallBackTask(start: Int, end: Int, completionHandler: @escaping ([Int]) -&gt; Void) <\/span><\/pre>\n<p>This function is refactored to<\/p>\n<div id=\"attachment_56183\" style=\"width: 1742px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-56183\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-56183 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/MultipleHeavyOperationns.png\" alt=\"\" width=\"1732\" height=\"524\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/MultipleHeavyOperationns.png 1732w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/MultipleHeavyOperationns-300x91.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/MultipleHeavyOperationns-1024x310.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/MultipleHeavyOperationns-768x232.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/MultipleHeavyOperationns-1536x465.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/MultipleHeavyOperationns-624x189.png 624w\" sizes=\"(max-width: 1732px) 100vw, 1732px\" \/><p id=\"caption-attachment-56183\" class=\"wp-caption-text\">Refactored multiple heavy operation async function <a href=\"https:\/\/github.com\/ankittlp\/SwiftConcurrency.git\"><span style=\"font-weight: 400;\">Download as Xcode project<\/span><\/a><\/p><\/div>\n<p><span style=\"font-weight: 400;\">With the above code refactor we fixed the <\/span><b>Pyramid of doom.<\/b><\/p>\n<p><b>Effectful Read-only Properties (get async throws):<\/b><\/p>\n<p><span style=\"font-weight: 400;\">As I mentioned before <\/span><b>Task\u2019s value<\/b><span style=\"font-weight: 400;\"> property is an <\/span><b>async throwable<\/b><span style=\"font-weight: 400;\"> read-only property. <\/span><\/p>\n<div id=\"attachment_56184\" style=\"width: 980px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-56184\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-56184 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-22-at-2.45.04-AM.png\" alt=\"\" width=\"970\" height=\"528\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-22-at-2.45.04-AM.png 970w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-22-at-2.45.04-AM-300x163.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-22-at-2.45.04-AM-768x418.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/Screenshot-2022-12-22-at-2.45.04-AM-624x340.png 624w\" sizes=\"(max-width: 970px) 100vw, 970px\" \/><p id=\"caption-attachment-56184\" class=\"wp-caption-text\">get async throw readonly property<\/p><\/div>\n<p><span style=\"font-weight: 400;\">To demonstrate <\/span><b>get async throws <\/b><span style=\"font-weight: 400;\">property, I added a custom <\/span><b>reducedValue <\/b><span style=\"font-weight: 400;\">property on Array&lt;Int&gt; and used it in above function we just refactored. It is called just like async function using <\/span><b>try await.<\/b><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-56185 size-full\" src=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncThrowableProperty.png\" alt=\"\" width=\"878\" height=\"378\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncThrowableProperty.png 878w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncThrowableProperty-300x129.png 300w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncThrowableProperty-768x331.png 768w, \/blog\/wp-ttn-blog\/uploads\/2022\/12\/AsyncThrowableProperty-624x269.png 624w\" sizes=\"(max-width: 878px) 100vw, 878px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Check out this <\/span><a href=\"https:\/\/github.com\/apple\/swift-evolution\/blob\/main\/proposals\/0310-effectful-readonly-properties.md\"><span style=\"font-weight: 400;\">SE-0310<\/span><\/a><span style=\"font-weight: 400;\"> for more on <\/span><b>async<\/b><span style=\"font-weight: 400;\"> get properties.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Though i wanted to talk about <\/span><b>async-let <\/b><span style=\"font-weight: 400;\">binding in this part but as it contribute more to Structured concurrency. I am keeping it to my next article <\/span><b>Concurrency with swift: Structured Concurrency<\/b><\/p>\n<p><span style=\"font-weight: 400;\">That concludes <\/span><b>async\/await.<\/b><\/p>\n<p><span style=\"font-weight: 400;\">let\u2019s recall a few rules and benefits of using Swift 5.5 concurrency async\/await.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Rules of <\/span><b>async<\/b><span style=\"font-weight: 400;\"> func:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Can not simply call async func similar to sync func. We need an asynchronous context to initiate the async call.<\/span>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Make the call site an <\/span><b>async<\/b><span style=\"font-weight: 400;\"> func, method or property.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Start with <\/span><b>Unstructured Task<\/b><span style=\"font-weight: 400;\">, a task with no parent task. (<\/span><i><span style=\"font-weight: 400;\">We\u2019ll talk more about Tasks in the later part of this series.<\/span><\/i><span style=\"font-weight: 400;\">)<\/span>\n<ul>\n<li style=\"font-weight: 400;\"><em><span style=\"font-weight: 400;\">Task.init(priority:operation)\u00a0<\/span><\/em><span style=\"font-weight: 400;\">creates an unstructured task on the current actor. (<\/span><i><span style=\"font-weight: 400;\">The Task we saw in the above example.)<\/span><\/i><\/li>\n<li style=\"font-weight: 400;\"><em><span style=\"font-weight: 400;\">Task.detached(priority:operation)<\/span><\/em><span style=\"font-weight: 400;\"> creates an unstructured task that is not a part of the current actor.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Static <\/span><b>main<\/b><span style=\"font-weight: 400;\"> method of struct, class or enumeration marked with @main.<\/span><\/li>\n<\/ul>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Async functions can call other async functions, but they can also call regular synchronous functions if they need to.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">If you have async and synchronous functions that can be called in the same way, Swift will prefer whichever one matches your current context \u2013 if the call site is currently async then Swift will call the async function, otherwise it will call the synchronous function.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\"><strong>Benefits<\/strong>:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Simple flow of execution. No more back and forth between closures.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">No more missing completion handlers.\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">No memory leak due to retain cycle formation.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Structured error handling.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Performance boosted due to much optimised thread handling (Cooperative threading model).<\/span><\/li>\n<\/ul>\n<p>Happy learning !<\/p>\n<p>&nbsp;<\/p>\n<div class=\"ap-custom-wrapper\"><\/div><!--ap-custom-wrapper-->","protected":false},"excerpt":{"rendered":"<p>Concurrency is not something we haven\u2019t known, but in Swift 5.5 this is built-in.\u00a0 Wait&#8230;Why ?? We have been doing concurrent programming for so long and our apps were pretty good and responsive.\u00a0 Yes, we were able to achieve concurrency in swift by using frameworks like Grand Central Dispatch (GCD) and Operations. They were handy [&hellip;]<\/p>\n","protected":false},"author":1138,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":142},"categories":[1400],"tags":[5065],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/56186"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1138"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=56186"}],"version-history":[{"count":6,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/56186\/revisions"}],"predecessor-version":[{"id":56276,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/56186\/revisions\/56276"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=56186"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=56186"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=56186"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}