<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Priya Raman</title>
    <description>The latest articles on DEV Community by Priya Raman (@priya_raman_1044cc8523a37).</description>
    <link>https://dev.to/priya_raman_1044cc8523a37</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1232718%2F1a473fdf-162c-42e6-a177-0f462e3ef99c.png</url>
      <title>DEV Community: Priya Raman</title>
      <link>https://dev.to/priya_raman_1044cc8523a37</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/priya_raman_1044cc8523a37"/>
    <language>en</language>
    <item>
      <title>Swift - Structured Concurrency - Actor</title>
      <dc:creator>Priya Raman</dc:creator>
      <pubDate>Thu, 21 Dec 2023 17:54:08 +0000</pubDate>
      <link>https://dev.to/priya_raman_1044cc8523a37/swift-structured-concurrency-actor-5gbj</link>
      <guid>https://dev.to/priya_raman_1044cc8523a37/swift-structured-concurrency-actor-5gbj</guid>
      <description>&lt;p&gt;Actor - Way to serve the incoming requests with shared mutable state, protects data from inadvertently modified/accessed. These are otherwise enforced by Locks, serial queues, Semaphores.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Thread safe requests for the shared state - ex, Multiple reads during write&lt;/li&gt;
&lt;li&gt;Serialize multiple write requests. ex, write-1 vs write-2 initiated at the same time.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;actor is similar to class nominal type, reference type, has methods, properties isolated to that actor, can have protocol conformance. NO inheritance - so no convenience initializers, no final or no override with actors.&lt;/li&gt;
&lt;li&gt;Properties and methods within actors are async in nature, so, any access to properties/methods outside actor should be marked with &lt;code&gt;await&lt;/code&gt; and any references of other instances of actor within the actor should also be with &lt;code&gt;await&lt;/code&gt; while internal references within actor of properties are synchronous in nature so, it could be direct access unless its within a &lt;code&gt;Task.detached&lt;/code&gt; which would require &lt;code&gt;await&lt;/code&gt;.
-- Every access request to actor's method or property creates a potential suspension point - meaning the request could be served by the actor right away or within a moment or 2,basically saying that "serve me as soon as you can"&lt;/li&gt;
&lt;li&gt;Internally, its a private serial queue processing 1 request at a time in the order in which the requests are received unless specified with priority escalation.&lt;/li&gt;
&lt;li&gt;There could be unprotected state within the actor which could be accessed without &lt;code&gt;await&lt;/code&gt; but should be specifically marked so.&lt;/li&gt;
&lt;li&gt;Care should be taken that internally it will process only 1 request at a time by a single thread as actor is specifically to avoid ambiguity in shared mutable state and avoid data races, so performance consideration to handle multiple requests at a time is not the architecture design of actor. Creating multiple instances does not cause any perf issue rather the time spent on potential suspension points when called by the requests is something that's bound to happen.&lt;/li&gt;
&lt;li&gt;Function Parameter based isolation:
Ability for external functions to execute within the specified actor's isolated context as if this function was defined within the actor, meaning the function could access the actor's properties or methods freely/synchronously but this method could called only using &lt;code&gt;await&lt;/code&gt;. Though not marked async, it would still be executed in actor's isolated context single thread.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;actor CachedData {
 private var variable1, variable2, ...
 func doSomething() {
 }
}

class anotherClass {
func anotherFunc(data: isolated CachedData) {
print(data.variable1)
print(data.variable2)
}
init() {
  await anotherFunc(CachedData())
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Non isolated functions : An inverse of external isolated functional parameters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;-- Can access only constant properties which are thread safe in nature and other non-isolated methods. &lt;/p&gt;

&lt;p&gt;-- Could be accessed synchronously by external methods not within the actor without using &lt;code&gt;await&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;-- If this method requires accessing any actor isolated properties or methods, it would be as if this method is external to the actor and accessed through &lt;code&gt;await&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;actor SampleActor {
 private var str1 = ""
 private var int1 = 0
 private let str2 = "hi"
 func doSomething() {
 }
 nonisolated func doNonIsolatedCommonForActor() {
  print(str2)
 }
 nonisolated func doNonIsolatedCommonForSameActor() {
  await doSomething()
  print(await str1)
 }
}
let actorInstance = SampleActor()
actorInstance.doNonIsolatedCommonForActor()
actorInstance.doNonIsolatedCommonForSameActor()
await actorInstance.doSomething()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My Notes as understood from HackingWithSwift Structured Concurrency series.&lt;/p&gt;

</description>
      <category>swift</category>
      <category>structuredconcurrency</category>
      <category>asyncawait</category>
      <category>actor</category>
    </item>
    <item>
      <title>Swift - Structured Concurrency - Notes about TaskGroup</title>
      <dc:creator>Priya Raman</dc:creator>
      <pubDate>Tue, 19 Dec 2023 21:45:02 +0000</pubDate>
      <link>https://dev.to/priya_raman_1044cc8523a37/swift-structured-concurrency-notes-about-taskgroup-1cpf</link>
      <guid>https://dev.to/priya_raman_1044cc8523a37/swift-structured-concurrency-notes-about-taskgroup-1cpf</guid>
      <description>&lt;p&gt;TaskGroup - Concurrent requests similar to DispatchGroup&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;withTaskGroup - No throw variant. grp conforms to AsyncSequence, so return value could be collated by &lt;code&gt;for await&lt;/code&gt; loop or &lt;code&gt;while let item = await grp.next()&lt;/code&gt; or &lt;code&gt;await grp.reduce(initial, transform)&lt;/code&gt;. &lt;code&gt;.waitForAll()&lt;/code&gt; will discard the result though.
-- returnValue for each Task within the group should be the same representing &lt;code&gt;await withTaskGroup(String.self)&lt;/code&gt; but overall group could return a different data type as well with collated Task results.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let something = await withTaskGroup(String.self) { grp -&amp;gt; String
grp.addTask {
...
...
return "abc" 
}
grp.addTask {
...
...
return "def" 
}
var collectedReturn = ""

//3 Ways to fetch
for await val in grp {
 // indv return from indv task and collate
 collectedReturn += val
}
return collectedReturn }
//OR
return await grp.reduce(""){$0 += $1} }
//OR
while let val = await grp.next() {
 collectedReturn +=val
}
return collectedReturn }
print("val is \(something)") // prints val is abcdef
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;withThrowingTaskGroup - can throw Errors, grp conforms to AsyncSequence, so return value could be collated by &lt;code&gt;for try await&lt;/code&gt; loop or &lt;code&gt;while let item = try await grp.next()&lt;/code&gt; or &lt;code&gt;try await grp.reduce(initial, transform)&lt;/code&gt;. &lt;code&gt;.waitForAll()&lt;/code&gt; will discard the result though.
-- returnValue for each Task within the group should be the same representing &lt;code&gt;try await withTaskGroup([Model].self)&lt;/code&gt; but overall group could return a different data type as well with collated Task results.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func loadStories() async {
        do {
            let allStories = try await withThrowingTaskGroup(of: [Model].self) { grp -&amp;gt; [Model] in

                for i in 1...5 {
                    grp.addTask {
                        let url = URL(string: "URL")!
                        let (data, _) = try await URLSession.shared.data(from: url)
                        _//if Task.isCancelled { return []}_
                        return try JSONDecoder().decode([Model].self, from: data)
                    }
                }
                _//grp.cancelAll()_
                //return try await grp.reduce(into: [Model]()) { $0 += $1 }
                var collectedItems = [Model]()
                while let item = try await grp.next() {
                    collectedItems.append(contentsOf: item)
                }
                return collectedItems

            }
            newsItems = allStories.sorted {
                $0.id &amp;lt; $1.id
            }
        } catch let error {
            if error as! CancelError == CancelError.Icancelled {
                print("I cancelled")
            }
            print("Error \(error.localizedDescription)")
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Task Cancellation: &lt;code&gt;.cancelAll()&lt;/code&gt; Method on grp, wont cancel unless check for cancellation is cooperative but seems to work even otherwise, meaning check for cancellation such as &lt;code&gt;if Task.isCancelled&lt;/code&gt; or &lt;code&gt;try Task.checkCancellation&lt;/code&gt; calls within the grp's individual task as shown above in the comments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Heterogenous Return type for each task in Taskgroup is possible with wrapping up actual return type with enum so that each task can return same enum with different case having different associated value type. And still, taskGroup can ultimately return different data type as well.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My Notes as understood from HackingWithSwift Structured Concurrency series.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Swift - Structured Concurrency - Notes about Task</title>
      <dc:creator>Priya Raman</dc:creator>
      <pubDate>Mon, 18 Dec 2023 18:39:18 +0000</pubDate>
      <link>https://dev.to/priya_raman_1044cc8523a37/swift-structured-concurrency-notes-about-task-1l69</link>
      <guid>https://dev.to/priya_raman_1044cc8523a37/swift-structured-concurrency-notes-about-task-1l69</guid>
      <description>&lt;p&gt;Task - Independent chunk of work in async context.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;async let doSomething = funcCall() is syntactic sugar for a creating a task underneath + await result.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Task Priority - High[~userInitiated], medium to low[~utility] and then, background.&lt;br&gt;
-- Child task inherits from parent, UI task from Main thread inherits userInitiated, if neither, gets nil or Swift queries to figure out the priority.&lt;br&gt;
-- &lt;code&gt;Task.currentPriority&lt;/code&gt; gives current priority&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Task priority escalation scenarios.&lt;br&gt;
-- Task B with low priority gets invoked by Task A with high priority, Task B priority gets elevated to Task A's priority. Task.currentPriority for Task B is also high.&lt;br&gt;
-- Task B with low priority is getting executed by an actor which has enqueued Task A with high priority, Task B priority gets elevated to Task A's priority. Task.currentPriority is still the same but executes faster though.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Task Syntax&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let fetchTask = Task(priority: .high) {() -&amp;gt; returnValueType  in 
try ...
return returnValueType
} 
do {  
  let val = try await fetchTask.value // .value gives the   
                                      return value.
} catch {
  print("Error")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Inferences: 
-- try await task.value gives the return value with specified return type as part of Task closure.
-- Another way to retrieve value is through &lt;code&gt;.result&lt;/code&gt; and &lt;code&gt;.get()&lt;/code&gt;, it returns the Result struct with Return type and Error as values, so, &lt;code&gt;let result  = await task.result()&lt;/code&gt; but it could be TRIED when the result is accessed as &lt;code&gt;let val = try result.get()&lt;/code&gt;, this is helpful to the caller as it could decide when exactly to throw and deal with the error and result leading to just pass around the encapsulated result as a whole to the caller chain up further.
-- Tasks get kickstarted the moment we initialize, it runs concurrently with other code as below.
&lt;code&gt;fetchUpdates Started 14:46:48:1850 - actual async function call
headlinesTask Started 14:46:48:1850
ScoreTask Started 14:46:48:1850
scoreTask Value Started 14:46:48:1850 
headlinesTask API Ended 14:46:48:2120
ScoreTask API ended 14:46:48:2120
scoreTask Value Ended 14:46:48:2130
headlinesTask Value Started 14:46:48:2130
headlinesTask Value Ended 14:46:48:2130
fetchUpdates Ended 14:46:48:2520&lt;/code&gt;
We can see that tasks started at the same time and value retrieval was hit at the same time. once API ended, value retrieval ended and moved on to 2nd value retrieval.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@State&lt;/code&gt; property could be accessed from any thread, the view will be refreshed on Main thread.&lt;/li&gt;
&lt;li&gt;Task and &lt;code&gt;.task&lt;/code&gt;modifier to view - modifier is intelligent enough to be bound to life time of the view so, will be cancelled after view is moved out of memory. Task runs to completion until its either complete or cancelled. if async API call is attached to &lt;code&gt;.task&lt;/code&gt; modifier, and if view tends to get recreated, API gets called though with URLSession, it might be cached. Dynamic identifier conforming to Equatable can be applied to &lt;code&gt;.task&lt;/code&gt; modifier, so API could get called based on equatable value.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Task Cancellation &lt;br&gt;
-- &lt;code&gt;Task.isCancelled -&amp;gt; Bool&lt;/code&gt; Static method within Task definition&lt;br&gt;
-- &lt;code&gt;try Task.checkCancellation&lt;/code&gt; : Static method within Task definition that throws TaskCancellation Error.&lt;br&gt;
-- &lt;code&gt;.cancel()&lt;/code&gt; method on task instance.&lt;br&gt;
-- URLSession throws cancellation Errors if call is cancelled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Task vs detachedTask&lt;br&gt;
-- Task/ detachedTask is differentiated by its priority, local values and actor context&lt;br&gt;
--- Priority: Task is inherently defined by its context in which its executed, meaning it inherits the parent priority, if button action initiates the task, it gains userinitiated priority and runs the task with that priority. WHILE, Task.detached does not have any parent to inherit priority so, its nil or something we prescribe.&lt;br&gt;
--- local values: defined as static types within task letting us share the values within the specific task. WHILE, Task.detached does not have any parent to inherit local values so, no local values will be inherited.&lt;br&gt;
---- Task Local value: Struct/Class/Enum/Actor with static dataType associated @TaskLocal property wrapper. It can have different meaning ~Values according to the Task in which its associated with, similar to local and global variables scope. Task starts and ends with &lt;code&gt;try await Type.$staticVar.withValue(customVal)&lt;/code&gt; and can be nested as well, with global scope still retaining original declared value.&lt;br&gt;
--- actor isolation: When a task is defined within actor,its isolated to that actor - meaning other parts of the code could be used synchronously within the task. Everything within a task executes sequentially and synchronously though it might entail other API calls. Task has the control of code execution flow.WHILE, Task.detached does not have any parent or any control over how the code execution flows, so, within detachedTask, any code run requiring async context runs concurrently, so, to sequence the task, we would have to await the async function call to make it the way we want the task.detached to run. As it does not have a parent, it has greater restriction towards executing other pieces of code even within that actor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Task Sleep - &lt;code&gt;try await Task.sleep(nanoSeconds: 3_000_000_000)&lt;/code&gt; , requires try as if the task is cancelled, it will throw a cancellation error inherently, requires await as it causes the execution to be suspended. It wont block the underlying thread, it will go on to execute something else.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Voluntarily suspend Task - &lt;code&gt;Task.yield()&lt;/code&gt; , gives Swift a chance to run other priority tasks if present by suspending current task. This is a suggestion to Swift runtime, so, the current task could or need not be suspended.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My Notes as understood from HackingWithSwift Structured Concurrency series.&lt;/p&gt;

</description>
      <category>swift</category>
      <category>structuredconcurrency</category>
      <category>asyncawait</category>
      <category>task</category>
    </item>
    <item>
      <title>SwiftUI - Basic Core Image Processing</title>
      <dc:creator>Priya Raman</dc:creator>
      <pubDate>Wed, 13 Dec 2023 17:36:36 +0000</pubDate>
      <link>https://dev.to/priya_raman_1044cc8523a37/swiftui-core-image-processing-4dl</link>
      <guid>https://dev.to/priya_raman_1044cc8523a37/swiftui-core-image-processing-4dl</guid>
      <description>&lt;p&gt;Steps to create a processed image based on CI filter in SwiftUI&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create CIFilter instance to be sepia or any filter type.&lt;/li&gt;
&lt;li&gt;Convert selectedItem  - PhotosPickerItem into Data format using loadTransferable method.&lt;/li&gt;
&lt;li&gt;Convert imageData into UIImage&lt;/li&gt;
&lt;li&gt;For Core Image processing, Image needs to be in CI format, so convert UIImage into CIImage.&lt;/li&gt;
&lt;li&gt;CIFilter is a specific container within Core Image that can accept input CI image and generate output CI image and apply filter in between.&lt;/li&gt;
&lt;li&gt;Set CurrentFilter's CI inputImg using setValue with Img key.&lt;/li&gt;
&lt;li&gt;Set CurrentFilter's intensity or any valid inputKeys with respective float value&lt;/li&gt;
&lt;li&gt;Fetch CurrentFilter's CI outputImg&lt;/li&gt;
&lt;li&gt;Now that processing within CI is over, its time to convert that to proper pixels in Coregraphics.&lt;/li&gt;
&lt;li&gt;CIContext can create cgImage with this generated CIImage with applied filter to the fullest extent size.&lt;/li&gt;
&lt;li&gt;Back convert from CGImage to UIImage as CIImage conversion is not needed as image has been processed.&lt;/li&gt;
&lt;li&gt;Back convert from UIImage to Image initializer in SwiftUI.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;My Notes as understood from HackingWithSwift 100 days of SwiftUI.&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>swiftui</category>
      <category>coreimage</category>
    </item>
  </channel>
</rss>
