<?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: Utkarsh Shrivastava</title>
    <description>The latest articles on DEV Community by Utkarsh Shrivastava (@utkarsh4517).</description>
    <link>https://dev.to/utkarsh4517</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%2F1069989%2F9cefe9e9-3c91-468a-8686-771a99494110.jpeg</url>
      <title>DEV Community: Utkarsh Shrivastava</title>
      <link>https://dev.to/utkarsh4517</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/utkarsh4517"/>
    <language>en</language>
    <item>
      <title>Using FFmpegKit Locally in React Native After Retirement</title>
      <dc:creator>Utkarsh Shrivastava</dc:creator>
      <pubDate>Wed, 09 Apr 2025 20:35:46 +0000</pubDate>
      <link>https://dev.to/utkarsh4517/using-ffmpegkit-locally-in-react-native-after-retirement-3a9p</link>
      <guid>https://dev.to/utkarsh4517/using-ffmpegkit-locally-in-react-native-after-retirement-3a9p</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/arthenica/ffmpeg-kit" rel="noopener noreferrer"&gt;FFmpegKit&lt;/a&gt; has been officially retired, but you can still use it by building and integrating it locally. This guide provides step-by-step instructions to set up FFmpegKit in your React Native (iOS Only as of now :/) project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clone FFmpegKit Repository
&lt;/h3&gt;

&lt;p&gt;Navigate to a directory next to your project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /path/to/your/projects/
git clone https://github.com/arthenica/ffmpeg-kit.git 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install Build Dependencies
&lt;/h3&gt;

&lt;p&gt;For macOS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install automake libtool pkg-config
brew reinstall autoconf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build FFmpegKit for iOS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /path/to/your/projects/ffmpeg-kit
./ios.sh -x --disable-arm64e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This might take some time. The command builds FFmpegKit with external libraries disabled.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup Project Structure
&lt;/h3&gt;

&lt;p&gt;Create a directory for frameworks in your OG React Native project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /path/to/your/projects/your-react-native-app
mkdir ffmpeg-kit-ios-https
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Copy Framework Files
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp -R /path/to/your/projects/ffmpeg-kit/prebuilt/bundle-apple-xcframework-ios/*.xcframework /path/to/your/projects/your-react-native-app/ffmpeg-kit-ios-https/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a Local Podspec
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a file named your-app-name-ffmpeg-kit-ios-https.podspec in your project root:


require "json"

Pod::Spec.new do |s|
  s.name         = "your-app-name-ffmpeg-kit-ios-https"
  s.version      = "6.0.2"
  s.summary      = "FFmpeg Kit iOS Https Shared Framework"
  s.description  = "Includes FFmpeg with gmp and gnutls libraries enabled."
  s.homepage     = "https://github.com/your-username/ffmpeg"
  s.license      = { :type =&amp;gt; "LGPL-3.0", :file =&amp;gt; "ffmpeg-kit-ios-https/ffmpegkit.xcframework/ios-arm64/ffmpegkit.framework/LICENSE" }
  s.authors      = "your-username"

  s.platform          = :ios
  s.ios.deployment_target = "12.1"
  s.requires_arc      = true
  s.static_framework  = true

  s.source        = { :git =&amp;gt; 'https://github.com/your-username/ffmpeg.git', :tag =&amp;gt; s.version.to_s }

  s.libraries = [
    "z",
    "bz2",
    "c++",
    "iconv"
  ]

  s.frameworks = [
    "AudioToolbox",
    "AVFoundation",
    "CoreMedia",
    "VideoToolbox"
  ]
  s.vendored_frameworks = [
    "ffmpeg-kit-ios-https/ffmpegkit.xcframework",
    "ffmpeg-kit-ios-https/libavcodec.xcframework",
    "ffmpeg-kit-ios-https/libavdevice.xcframework",
    "ffmpeg-kit-ios-https/libavfilter.xcframework",
    "ffmpeg-kit-ios-https/libavformat.xcframework",
    "ffmpeg-kit-ios-https/libavutil.xcframework",
    "ffmpeg-kit-ios-https/libswresample.xcframework",
    "ffmpeg-kit-ios-https/libswscale.xcframework",
  ]
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Update FFmpegKit React Native Module
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;cd /path/to/your/projects/ffmpeg-kit/react-native&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Edit ffmpeg-kit-react-native.podspec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require "json"

package = JSON.parse(File.read(File.join(__dir__, "package.json")))

Pod::Spec.new do |s|
  s.name         = package["name"]
  s.version      = package["version"]
  s.summary      = package["description"]
  s.homepage     = package["homepage"]
  s.license      = package["license"]
  s.authors      = package["author"]

  s.platform          = :ios
  s.requires_arc      = true
  s.static_framework  = true

  s.source = { :git =&amp;gt; 'https://github.com/arthenica/ffmpeg-kit.git', :tag =&amp;gt; s.version.to_s }

  s.dependency "React-Core"

  s.source_files      = '**/FFmpegKitReactNativeModule.m',
  '**/FFmpegKitReactNativeModule.h'

  s.dependency 'your-app-name-ffmpeg-kit-ios-https'

  s.ios.deployment_target = '12.1'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Edit package.json to use the local FFmpegKit:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"dependencies": {
  "ffmpeg-kit-react-native": "file:../ffmpeg-kit/react-native",
  // other dependencies...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Update metro config
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {getDefaultConfig} = require('@react-native/metro-config');
const path = require('path');

const config = {
  watchFolders: [
    path.resolve(__dirname, '../ffmpeg-kit/react-native'),
  ],
  resolver: {
    extraNodeModules: {
      'react-native': path.resolve(__dirname, 'node_modules/react-native'),
      'react': path.resolve(__dirname, 'node_modules/react'),
      '@babel/runtime': path.resolve(__dirname, 'node_modules/@babel/runtime'),
    },
    blockList: [
      /.*\/ffmpeg-kit\/react-native\/node_modules\/.*/,
    ],
  },
  transformer: { 
    getTransformOptions: async () =&amp;gt; ({
      transform: {
        inlineRequires: true,
      },
    }),
  },
};

module.exports = getDefaultConfig(__dirname, config);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Update ios podfile of your OG Project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;target 'YourAppName' do
  pod 'your-app-name-ffmpeg-kit-ios-https', :path =&amp;gt; '..'

  # Comment out or remove this line if it exists:
  # pod 'ffmpeg-kit-react-native', :subspecs =&amp;gt; ['audio'], :podspec =&amp;gt; '../node_modules/ffmpeg-kit-react-native/ffmpeg-kit-react-native.podspec'

  # Rest of your Podfile...
end

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install dependencies and run.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rm -rf node_modules
rm -rf ios/Pods
npm install
cd ios &amp;amp;&amp;amp; pod install &amp;amp;&amp;amp; cd ..
npx react-native run-ios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;huge thanks to &lt;a href="https://github.com/cvincentcoleman" rel="noopener noreferrer"&gt;https://github.com/cvincentcoleman&lt;/a&gt; for &lt;a href="https://github.com/arthenica/ffmpeg-kit/issues/1144#issuecomment-2784446707" rel="noopener noreferrer"&gt;https://github.com/arthenica/ffmpeg-kit/issues/1144#issuecomment-2784446707&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;hit the like and maybe follow, if the blog helped you.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Practical Hands-On Guide to Flutter Isolates</title>
      <dc:creator>Utkarsh Shrivastava</dc:creator>
      <pubDate>Sat, 26 Oct 2024 15:25:23 +0000</pubDate>
      <link>https://dev.to/utkarsh4517/the-practical-hands-on-guide-to-flutter-isolates-4834</link>
      <guid>https://dev.to/utkarsh4517/the-practical-hands-on-guide-to-flutter-isolates-4834</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Picture this: You're building a flutter application that needs to process large datasets, handle UI interactions, and maintain smooth animations - all simultaneously. If you're coming from JavaScript, you might be thinking, "I'll just use Web Workers!" But what if I told you Dart has an even more elegant solution?&lt;/p&gt;

&lt;p&gt;Like JavaScript, &lt;em&gt;Dart is fundamentally a single-threaded language&lt;/em&gt;, yes. This means that at its core, it executes one piece of code at a time in a single thread of execution, dubbed the "main isolate." However, where JavaScript uses Web Workers for parallel processing, Dart introduces us to the concept of Isolates - and this is where things get interesting.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;gt; p.s we will be building a small project in the end&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's first understand &lt;em&gt;"how isolates are different compared to threads"&lt;/em&gt;?
&lt;/h3&gt;

&lt;p&gt;Traditional threads are like &lt;em&gt;multiple cooks sharing one kitchen&lt;/em&gt;. They're all working in the same space, using the same tools, and accessing the same ingredients. Sure, you can get more done, but:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Someone might grab the knife you were using (&lt;em&gt;resource contention&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Two cooks might reach for the same ingredient (&lt;em&gt;race conditions&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Everyone has to constantly check what others are doing 
(&lt;em&gt;synchronization overhead&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;The kitchen becomes chaos without strict rules (&lt;em&gt;mutex/locks&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Isolates
&lt;/h3&gt;

&lt;p&gt;Dart looked at this chaos and said, "What if each cook had their own kitchen?" That's essentially what isolates are. Instead of sharing memory and fighting over resources, each isolate gets its own memory heap. It's like having multiple copies of your app running independently.&lt;/p&gt;

&lt;p&gt;Isolates provide:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Complete Memory Isolation:

&lt;ul&gt;
&lt;li&gt;Each isolate has its own memory heap&lt;/li&gt;
&lt;li&gt;No shared memory between isolates&lt;/li&gt;
&lt;li&gt;Memory safety by design&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Message-Passing Communication (&lt;em&gt;We will dive deep into this&lt;/em&gt;)

&lt;ul&gt;
&lt;li&gt;Since Isolates have separate memories, we communicate between 
them by passing messages using the receiver port and sender port.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Resource Efficiency

&lt;ul&gt;
&lt;li&gt;Lighter weight than OS threads.&lt;/li&gt;
&lt;li&gt;More efficient memory usage.&lt;/li&gt;
&lt;li&gt;Better suited for Dart's garbage collection.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The messages between the isolates are like orders going between kitchens (Memory Space)&lt;/p&gt;

&lt;p&gt;The dart &lt;strong&gt;&lt;em&gt;event loop&lt;/em&gt;&lt;/strong&gt; is the waiter taking orders and delivering dishes&lt;/p&gt;

&lt;p&gt;The event loops ensures that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Messages are delivered in the right order&lt;/li&gt;
&lt;li&gt;No isolate gets overwhelmed&lt;/li&gt;
&lt;li&gt;Everything stays responsive&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To understand dart event loop in detail, you can look up to this official &lt;a href="https://dart.dev/language/concurrency" rel="noopener noreferrer"&gt;blog&lt;/a&gt; by dart. &lt;/p&gt;

&lt;p&gt;Dart event loop has two queues (like having two types of order tickets in our restaurant):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Microtask Queue (VIP Orders)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handles high-priority tasks&lt;/li&gt;
&lt;li&gt;Always processed first&lt;/li&gt;
&lt;li&gt;Perfect for quick, internal operations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Event Queue (Regular Orders)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handles regular async operations&lt;/li&gt;
&lt;li&gt;I/O operations, timers, isolate messages&lt;/li&gt;
&lt;li&gt;Processed after all microtasks are done&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Understanding the &lt;strong&gt;Main Isolate&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The main isolate in Flutter isn't just another isolate - it's the VIP of your app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void main() {
  // You're already in the main isolate when this runs!
  runApp(MyApp());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;UI Updates happen only in main isolates.&lt;/li&gt;
&lt;li&gt;Only the main isolate can communicate with platform-specific code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Event loop example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void main() {
  print('🏃 Starting the show');  // 1: Regular synchronous code

  Future(() {
    print('🎭 Event queue');      // 3: Gets queued in event queue
  });

  Future.microtask(() {
    print('⚡ Microtask queue');   // 2: Gets queued but runs first
  });

  print('🏁 Synchronous end');    // 1: Regular synchronous code
}

// Output:
// 🏃 Starting the show
// 🏁 Synchronous end
// ⚡ Microtask queue
// 🎭 Event queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The real magic happens when isolates and event loops work together. Each isolate has its own event loop, but they can communicate through message passing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with isolates
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void main() async {
  // Create a ReceivePort for incoming messages
  final receivePort = ReceivePort();

  // Spawn a new isolate
  final isolate = await Isolate.spawn(
    simpleWorker,        // Function to run in isolate
    receivePort.sendPort // Port for sending messages back
  );

  // Listen for messages
  receivePort.listen((message) {
    print('Received: $message');
    // Clean up when done
    receivePort.close();
    isolate.kill();
  });
}

// Worker function that runs in the isolate
void simpleWorker(SendPort sendPort) {
  sendPort.send('Hello from isolate!');
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Understanding Ports
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;ReceivePort&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Acts as the inbox for messages&lt;/li&gt;
&lt;li&gt;Created in the isolate where you want to receive messages&lt;/li&gt;
&lt;li&gt;Provides a SendPort that others can use to send messages to this 
isolate&lt;/li&gt;
&lt;li&gt;Can be listened to using listen() or used in an async for loop&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;SendPort&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Acts as the outbox for sending messages&lt;/li&gt;
&lt;li&gt;Obtained from a ReceivePort&lt;/li&gt;
&lt;li&gt;Used to send messages to the corresponding ReceivePort&lt;/li&gt;
&lt;li&gt;Can be passed between isolates&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Passing complex messages
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'dart:isolate';

class WorkMessage {
  final String command;
  final Map&amp;lt;String, dynamic&amp;gt; data;

  WorkMessage(this.command, this.data);
}

void main() async {
  final receivePort = ReceivePort();

  // Spawn isolate with initial message
  final isolate = await Isolate.spawn(
    dataProcessor,
    [
      receivePort.sendPort,
      WorkMessage('process', {'items': [1, 2, 3]})
    ],
  );

  // Handle responses
  await for (final message in receivePort) {
    if (message is String) {
      print('Received: $message');
      receivePort.close();  // Close after processing
      break;  // Exit loop when done
    }
  }

  isolate.kill();
}

void dataProcessor(List&amp;lt;dynamic&amp;gt; initialMessage) {
  final SendPort sendPort = initialMessage[0];
  final WorkMessage workMessage = initialMessage[1];
  final result = processData(workMessage);
  // Send back result
  sendPort.send('Processed: $result');
}

String processData(WorkMessage message) {
  final items = message.data['items'] as List&amp;lt;int&amp;gt;;
  final processedItems = items.map((item) =&amp;gt; item * 2).toList();
  return processedItems.toString();
}


// Output
// Received: Processed: [2, 4, 6]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Points to Remember:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Always close ReceivePorts when they're no longer needed to prevent 
memory leaks&lt;/li&gt;
&lt;li&gt;Only send data that can be serialized (basic types, lists, maps, 
etc.)&lt;/li&gt;
&lt;li&gt;Consider using typed ports or message enums for better code 
organization&lt;/li&gt;
&lt;li&gt;Handle errors appropriately as they don't automatically propagate 
across isolates&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Image processing using Isolates vs Without Isolates.
&lt;/h2&gt;

&lt;p&gt;In this example code, We will apply filter over an image by vertically breaking the image into 4 equal chunks, applying blur filter over them using isolates. We will Process each chunk in parallel using isolates, and compare it to normal case&lt;/p&gt;

&lt;h3&gt;
  
  
  With Isolates
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'dart:io';
import 'dart:isolate';
import 'package:image/image.dart' as img;

void main() async {
  print('Image processing using isolates...');
  final stopwatch = Stopwatch()..start();
  final inputFile = File('bin/input_image.jpg');

  // Decode the image from file bytes
  final image = img.decodeImage(inputFile.readAsBytesSync());
  final width = image!.width;
  final height = image.height;

  final numberOfIsolates = 4;
  final chunkHeight = height ~/ numberOfIsolates;


  // Divide image into chunks
  final chunks = List.generate(
    numberOfIsolates,
    (i) =&amp;gt; img.copyCrop(image, x: 0, y: i * chunkHeight, width: width, height: chunkHeight),
  );

  // Process each chunk in parallel using isolates
  final results = await Future.wait(
    List.generate(numberOfIsolates, (i) =&amp;gt; processInIsolate(chunks[i])),
  );

  // Create an empty image to hold the final result
  final resultImage = img.Image(width: width, height: height);

  // Manually copy pixels from processed chunks into the result image
  for (int i = 0; i &amp;lt; numberOfIsolates; i++) {
    final chunk = results[i];
    for (int y = 0; y &amp;lt; chunk.height; y++) {
      for (int x = 0; x &amp;lt; chunk.width; x++) {
        // Set pixel from chunk to the result image
        resultImage.setPixel(x, y + (i * chunkHeight), chunk.getPixel(x, y));
      }
    }
  }

  // Save the resulting image
  final outputFile = File('output_image.jpg');
  outputFile.writeAsBytesSync(img.encodeJpg(resultImage));

  stopwatch.stop();
  print('Image processed in ${stopwatch.elapsedMilliseconds} ms');
}

Future&amp;lt;img.Image&amp;gt; processInIsolate(img.Image chunk) async {
  final receivePort = ReceivePort();
  await Isolate.spawn(applyBlur, [chunk, receivePort.sendPort]);
  return await receivePort.first;
}

void applyBlur(List&amp;lt;dynamic&amp;gt; args) {
  final img.Image chunk = args[0];
  final SendPort sendPort = args[1];

  // Apply Gaussian blur to the image chunk
  final blurred = img.gaussianBlur(chunk, radius: 10);

  // Send the processed image back to the main isolate
  sendPort.send(blurred);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Without Isolates
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'dart:io';
import 'package:image/image.dart' as img;

void main() {
  final stopwatch = Stopwatch()..start();

  final inputFile = File('bin/input_image.jpg');
  final image = img.decodeImage(inputFile.readAsBytesSync())!;

  final blurred = img.gaussianBlur(image, radius: 10);

  File('output_no_isolates.jpg').writeAsBytesSync(img.encodeJpg(blurred));

  stopwatch.stop();
  print('Processing time without isolates: ${stopwatch.elapsedMilliseconds} ms');
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comparing the results
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;With Isolates
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Image processing using isolates...
Image processed in 269 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Without Isolates
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Processing time without isolates: 812 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Messaging between Isolates
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Basic One-way Messaging
The simplest form of isolate communication - when you just need to send data and forget about it.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void main() async {
  // Create a receive port for incoming messages
  final receivePort = ReceivePort();
  // Spawn an isolate and pass the SendPort
  await Isolate.spawn(
    simpleWorker,
    receivePort.sendPort,
  );
  // Listen for any messages
  receivePort.listen((message) {
    print('Main received: $message');
  });
}

void simpleWorker(SendPort sendPort) {
  sendPort.send('Task completed!');
  sendPort.send('More results...');
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Main received: Task completed!
Main received: More results...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You saw that we didn't kill the port here, hence the code will run forever&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Two-way Communication Pattern
When your isolates need to have a conversation - useful for ongoing tasks or complex data processing.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'dart:isolate';

void main() async {
  // Set up the initial communication channel
  final mainReceivePort = ReceivePort();

  // Spawn the isolate
  final isolate = await Isolate.spawn(
    twoWayWorker,
    mainReceivePort.sendPort,
  );

  // Store worker's SendPort when received
  late SendPort workerSendPort;

  // Set up the two-way communication
  mainReceivePort.listen((message) {
    if (message is SendPort) {
      // First message is the worker's SendPort
      workerSendPort = message;

      // Now we can start sending messages to worker
      workerSendPort.send('Start processing!');
    } else {
      print('Main received: $message');
    }
  });
}

void twoWayWorker(SendPort mainSendPort) {
  // Create a receiver for the worker
  final workerReceivePort = ReceivePort();

  // Send the worker's SendPort back to main
  mainSendPort.send(workerReceivePort.sendPort);

  // Listen for messages from main
  workerReceivePort.listen((message) {
    print('Worker received: $message');
    // Process and send back results
    mainSendPort.send('Processed: $message');
  });
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks for reading :p&lt;br&gt;
Connect with me on twitter at https:x.com/twtutkarsh&lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>isolates</category>
      <category>programming</category>
    </item>
    <item>
      <title>Type Safety and Null safety in Dart.</title>
      <dc:creator>Utkarsh Shrivastava</dc:creator>
      <pubDate>Sat, 03 Jun 2023 12:40:50 +0000</pubDate>
      <link>https://dev.to/utkarsh4517/type-safety-and-null-safety-in-dart-1756</link>
      <guid>https://dev.to/utkarsh4517/type-safety-and-null-safety-in-dart-1756</guid>
      <description>&lt;h2&gt;
  
  
  Have you ever wondered why Dart is called a Type Safe language?
&lt;/h2&gt;

&lt;p&gt;It is so becauase the only operations that can be performed on data in the language are those allowed by the type of the data.&lt;/p&gt;

&lt;p&gt;In short the operations that are defined for &lt;code&gt;String&lt;/code&gt; can not be applied on &lt;code&gt;int&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;for example -&lt;br&gt;
&lt;code&gt;int x;&lt;br&gt;
 x.toUpperCase();&lt;/code&gt; is not allowed in dart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's take a deep dive into this.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There must be some tools in the Dart programming language which is analyzing whether the developer is writing typesafe code or not? Well Yes! There are two such type of tools..&lt;/p&gt;

&lt;p&gt;(i) Static Type Check - Checks at Compile time.&lt;br&gt;
(ii) Runtime check - Checks at runtime.&lt;/p&gt;

&lt;p&gt;This whole system is referred as Sound Type System.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But Why is it called so?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whenever we type code on our keyboard we make noise right? imagine that for everykey we press the sound print is being sent to the "Dart Static Analyzer" it checks everything and makes sure that the code we wrote is type safe when it detects that something isn't right it will display an error and it won't let us run the program until the issue is resolved.&lt;/p&gt;

&lt;p&gt;We can think of Static type check as a local type check which happens whenever a change is made.&lt;/p&gt;

&lt;p&gt;While the runtime check is like an additional Check which happens at the runtime.&lt;/p&gt;

&lt;p&gt;But Sometimes the developer might know what they are doing they would want to stop the Static checking of the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In that case we use the &lt;code&gt;dynamic&lt;/code&gt; data type.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;dynamic ignores the Static type check. We can declare a variable of dynamic type and the Static type check will not care about it anymore but the runtime check will care about it and will show an exception if a wrong method is applied to it.&lt;/p&gt;

&lt;p&gt;for example -&lt;br&gt;
&lt;code&gt;dynamic b = 3.14&lt;br&gt;
b.toUpperCase();&lt;/code&gt; in this case the program will run because the static type check will not show any error but the at the runtime the runtime check will throw an exception that the methodn &lt;code&gt;toUpperCase()&lt;/code&gt; is not defined for a value of double.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type Interference and Dynamic vs Var in Dart
&lt;/h2&gt;

&lt;p&gt;Types are mandatory in dart but they don't need to be annotated because Dart can Infer types by using the &lt;code&gt;var&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;example - &lt;br&gt;
&lt;code&gt;var x = 5.4;&lt;/code&gt; &lt;br&gt;
In this case the static type check will will think that variable x was assigned to a double value then it's type must be double for it's entire lifetime.&lt;/p&gt;

&lt;p&gt;but in somecases we wouldn't want that therefore we can use &lt;code&gt;dynamic x = 5.4&lt;/code&gt; and we can put any other type  of value in x now like -&lt;br&gt;
&lt;code&gt;x = 'abcd';&lt;br&gt;
x = 41;&lt;br&gt;
x = anyFunction();&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Runtime check will dynamically infer the type of x at the runtime while Static type check will not even care about x.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here comes the null safety of Dart&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What if we do not initialize a var at the time of declaration?&lt;/p&gt;

&lt;p&gt;ex- &lt;code&gt;var a;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Dart analyzer will set the the type of &lt;code&gt;a&lt;/code&gt; as dynamic throughout it's lifetime, Here dart analyzer played it safe and passed the job to the runtime check. But the problem is that the runtime check also doesn't know about the type of &lt;code&gt;a&lt;/code&gt; because it is uninitialized. &lt;/p&gt;

&lt;p&gt;hence the runtime check will set it's value to null.&lt;/p&gt;

&lt;p&gt;This is not a good practice..&lt;br&gt;
&lt;strong&gt;Therefore Dart introduced a new feature Sound Null Safety.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It means that the value can't be null unless the developer say's that it is null.&lt;/p&gt;

&lt;p&gt;which means Data can either be nullable or nun-nullable but can't be both during the runtime.&lt;/p&gt;

&lt;p&gt;This is the reason why you might see Null type exception at the runtime.&lt;/p&gt;

&lt;p&gt;If a dart variable is non-nullable that variable will always be non-nullable also non-nullability is retained at the runtime.&lt;/p&gt;

</description>
      <category>dynamic</category>
      <category>dart</category>
      <category>var</category>
      <category>soundsafety</category>
    </item>
  </channel>
</rss>
