Method Channel Flutter میں Dart کوڈ اور iOS اور Android کے نیٹیو سائیڈ کے درمیان دو طرفہ مواصلات کا طریقہ کار ہے۔ Flutter Documentation, 2026 کے مطابق، Method Channel Dart اور ہوسٹ پلیٹ فارم کے درمیان ٹائپ شدہ پیغامات کی منتقلی فراہم کرتا ہے۔ اس طریقہ کار کے بغیر، ڈیوائس کی ہارڈویئر صلاحیتوں، نیٹیو SDK اور سسٹم کالز تک ایپلیکیشن کوڈ سے رسائی ممکن نہیں ہے۔
اہم نکات
Method Channel Flutter پلیٹ فارم کی تہہ کا مرکزی جز ہے، جس کے ذریعے Dart الگ تھلگ iOS یا Android پر ہوسٹ ایپلیکیشن کے ساتھ پیغامات کا تبادلہ کرتے ہیں۔ چینل کا بنیادی کام دونوں پلیٹ فارمز کے درمیان ڈیٹا کی منتقلی کے پروٹوکول میں فرق کو چھپانا اور ڈویلپر کو ایک متحد API فراہم کرنا ہے۔
جب Flutter ایپلیکیشن کو کیمرہ، Bluetooth، سینسرز یا کسی دوسرے نیٹیو API تک رسائی کی ضرورت ہوتی ہے، تو Dart سے براہ راست کال ممکن نہیں ہے۔ Flutter C++ پر بنے انجن میں چلتا ہے اور اسے UIKit یا Android SDK فریم ورکس تک رسائی نہیں ہے۔ Method Channel Dart کی دنیا اور نیٹیو کوڈ کی دنیا کے درمیان ایک پل بنا کر اس مسئلے کو حل کرتا ہے۔
Google I/O 2024 کے مطابق، پروڈکشن میں 80% سے زیادہ Flutter ایپلیکیشنز پلیٹ فارم سروسز کے ساتھ انضمام کے لیے کم از کم ایک Method Channel استعمال کرتی ہیں۔ یہ جدید منصوبوں کے فن تعمیر میں چینل کے اہم کردار کی تصدیق کرتا ہے۔
ڈویلپر کے لیے، Method Channel ایک عام غیر ہم وقت فنکشن کال کی طرح لگتا ہے۔ پردے کے پیچھے، پیغام کی ترتیب، انجن بفر کے ذریعے اس کی منتقلی اور پلیٹ فارم کے مرکزی دھاگے پر نیٹیو کوڈ کا نفاذ ہوتا ہے۔
Method Channel کے ذریعے تعامل اس وقت شروع ہوتا ہے جب Dart طرف میتھڈ کا نام اور آرگیومینٹ پر مشتمل پیغام بھیجتی ہے۔ Flutter Engine اس پیغام کو وصول کرتا ہے، اسے معیاری StandardMethodCodec فارمیٹ میں تبدیل کرتا ہے اور BinaryMessenger کے ذریعے نیٹیو طرف کو بھیجتا ہے۔
نیٹیو طرف میں ایک ہینڈلر — MethodCallHandler ہوتا ہے، جو ڈی سیریلائزڈ کال وصول کرتا ہے اور متعلقہ منطق انجام دیتا ہے۔ نتیجہ Response کے طور پر Dart کو واپس بھیجا جاتا ہے، جس میں یا تو کامیاب نتیجہ یا کوڈ اور پیغام کے ساتھ خرابی ہوتی ہے۔
Method Channel کے ذریعے پورے کال سائیکل کو چھ مراحل میں تقسیم کیا جا سکتا ہے۔ Dart الگ تھلگ کنکشن کی شناخت کے لیے ایک منفرد نام کے ساتھ چینل کی ایک مثال بناتا ہے۔ invokeMethod کو کال کرتے وقت، Dart پلیٹ فارم کوڈ MethodCodec کا استعمال کرتے ہوئے میتھڈ کے نام اور آرگیومینٹ کو ترتیب دیتا ہے، جو StandardMessageCodec کے ذریعے انہیں بائنری بفر میں تبدیل کرتا ہے۔
Flutter Engine اس بفر کو ساکٹ کے ذریعے نیٹیو طرف بھیجتا ہے۔ نیٹیو BinaryMessenger پیغام پڑھتا ہے، نام سے چینل کی شناخت کرتا ہے اور رجسٹرڈ ہینڈلر کو کال کرتا ہے، اسے پارس کردہ ڈیٹا کے ساتھ ایک FlutterMethodCall آبجیکٹ بھیجتا ہے۔ ہینڈلر مطلوبہ کوڈ انجام دیتا ہے اور نتیجہ واپس کرتا ہے، جو الٹی ترتیب کے راستے سے گزر کر Future کے طور پر Dart تک پہنچتا ہے۔
Method Channel کا فن تعمیر کئی باہم منسلک اکائیوں پر مشتمل ہے، جن میں سے ہر ایک ڈیٹا کی منتقلی کے اپنے مرحلے کے لیے ذمہ دار ہے۔ Dart API MethodChannel کلاس فراہم کرتا ہے، جو ڈویلپر سے ترتیب اور روٹنگ کی نچلی سطح کی تفصیلات چھپاتا ہے۔
BinaryMessenger Dart اور ہوسٹ پلیٹ فارم کے درمیان بائنری پیغامات بھیجنے اور وصول کرنے کے لیے Flutter Engine کا نچلی سطح کا انٹرفیس ہے۔ ہر MethodChannel ایک مخصوص BinaryMessenger سے منسلک ہوتا ہے جو چینل کے نام سے روٹنگ فراہم کرتا ہے۔ Dart طرف BinaryMessenger کلاس استعمال ہوتی ہے، Android پر — io.flutter.embedding.engine پیکیج سے BinaryMessenger، iOS پر — FlutterBinaryMessenger پروٹوکول۔
MethodCodec ایک انکوڈر ہے جو میتھڈ کالز اور واپسی کی قدروں کو بائنری فارمیٹ میں تبدیل کرتا ہے۔ Flutter دو بلٹ ان نفاذ کے ساتھ آتا ہے: StandardMethodCodec (پہلے سے طے شدہ) اور JSONMethodCodec (JSON سٹرنگز کے لیے)۔ StandardMethodCodec اندرونی طور پر StandardMessageCodec استعمال کرتا ہے، جو تمام بنیادی Dart اقسام کی حمایت کے ساتھ ڈیٹا کو ترتیب دیتا ہے۔
StandardMessageCodec Dart، Kotlin اور Swift کے درمیان مطابقت کو یقینی بنانے کے لیے ڈیٹا کی اقسام کے ایک محدود سیٹ کو سپورٹ کرتا ہے۔ فہرست میں شامل ہیں: null، bool، int، double، String، Uint8List، Int32List، Int64List، Float64List، List اور سٹرنگ کلیدوں کے ساتھ Map۔
دیگر تمام اقسام — DateTime، DTO آبجیکٹ یا کسٹم کلاسیں — درج فارمیٹس میں سے کسی ایک میں تبدیل کی جانی چاہئیں۔ سب سے عام طریقہ یہ ہے کہ پیچیدہ آبجیکٹ کو فیلڈز کے ساتھ Map میں ترتیب دیا جائے اور وصول کرنے والی طرف فیلڈ ڈکشنری سے ساخت کو دوبارہ تشکیل دیا جائے۔
بڑے بائنری ڈیٹا، جیسے کیمرہ تصاویر، کی منتقلی کے لیے Flutter MethodChannel کے ذریعے ہر کال پر مکمل بفر کاپی سے بچنے کے لیے Uint8List کے ساتھ BasicMessageChannel استعمال کرنے کی سفارش کرتا ہے۔
| Dart قسم | Kotlin قسم | Swift قسم |
|---|---|---|
| null | null | nil |
| bool | Boolean | NSNumber |
| int | Int | NSNumber |
| double | Double | NSNumber |
| String | String | NSString |
| Uint8List | ByteArray | FlutterStandardTypedData |
| List | List | Array |
| Map | HashMap | Dictionary |
Android طرف Method Channel کی ترتیب ایک ایسی کلاس میں کی جاتی ہے جو FlutterPlugin کو لاگو کرتی ہے، یا براہ راست MainActivity میں۔ پہلا طریقہ تجویز کیا جاتا ہے کیونکہ یہ پلگ ان لائف سائیکل کا مناسب انتظام اور add-to-app منظرناموں کے ساتھ مطابقت فراہم کرتا ہے۔
Dart طرف کی طرح اسی نام کے ساتھ چینل کی ایک مثال بنانے کے بعد، setMethodCallHandler کے ذریعے MethodCallHandler رجسٹر کرنا ضروری ہے۔ ہینڈلر کے اندر، ڈویلپر when کے ذریعے آنے والے میتھڈ کے نام کی جانچ کرتا ہے اور result.success کے ذریعے نتیجہ یا کوڈ اور پیغام کے ساتھ result.error کے ذریعے خرابی واپس کرتا ہے۔
package com.example.app
import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.MethodChannel
class MainActivity : FlutterActivity() {
private val CHANNEL = "samples.flutter.dev/battery"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
val channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
channel.setMethodCallHandler { call, result ->
when (call.method) {
"getBatteryLevel" -> {
val batteryLevel = getBatteryLevel()
if (batteryLevel != null) {
result.success(batteryLevel)
} else {
result.error("UNAVAILABLE", "Battery not available", null)
}
}
else -> result.notImplemented()
}
}
}
}
اس مثال میں، samples.flutter.dev/battery نامی چینل getBatteryLevel کال کو ہینڈل کرتا ہے، Android BatteryManager کے ذریعے بیٹری کی سطح حاصل کرتا ہے اور اسے Dart کوڈ میں واپس کرتا ہے۔ چینل کا نام دونوں طرف مماثل ہونا چاہیے، ورنہ پیغام ہینڈلر تک نہیں پہنچے گا۔
پروڈکشن کوڈ کے لیے، Method Channel منطق کو FlutterPlugin لاگو کرنے والی ایک علیحدہ کلاس میں الگ کرنے کی سفارش کی جاتی ہے۔ یہ پلگ ان کو منصوبوں کے درمیان دوبارہ استعمال کرنے کی اجازت دیتا ہے اور onDetachedFromEngine کو کال کرنے پر وسائل کی مناسب صفائی کو یقینی بناتا ہے۔ پلگ ان registerWith کے ذریعے رجسٹر ہوتا ہے اور Activity سے علیحدہ جانچا جا سکتا ہے۔
iOS پر Method Channel کو FlutterPlugin پروٹوکول لاگو کرنے والی کلاس میں یا AppDelegate میں ترتیب دیا جاتا ہے۔ تجویز کردہ طریقہ ایک علیحدہ پلگ ان کلاس بنانا ہے جو FlutterPluginRegistrar کے ذریعے رجسٹر ہوتی ہے اور Flutter Engine کے زیر انتظام ہوتی ہے۔
Dart طرف ایک کال بھیجتی ہے، اور نیٹیو ہینڈلر میتھڈ کے نام اور آرگیومینٹ کے ساتھ ایک FlutterMethodCall آبجیکٹ وصول کرتا ہے۔ ڈویلپر call.method پر switch کے ذریعے کال کیے گئے میتھڈ کی شناخت کرتا ہے اور result بندش کے ذریعے نتیجہ واپس کرتا ہے۔ iOS API تک رسائی کے لیے UIKit اور دیگر سسٹم فریم ورک استعمال کیے جاتے ہیں۔
import Flutter
import UIKit
public class BatteryPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(
name: "samples.flutter.dev/battery",
binaryMessenger: registrar.messenger())
let instance = BatteryPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "getBatteryLevel":
let device = UIDevice.current
device.isBatteryMonitoringEnabled = true
let level = Int(device.batteryLevel * 100)
result(level)
default:
result(FlutterMethodNotImplemented)
}
}
}
FlutterPlugin طریقہ Flutter Engine کی تباہی پر پلگ ان کی مناسب رجسٹریشن اور غیر فعالی کو یقینی بناتا ہے۔ Swift ہینڈلر میں call.method پر switch استعمال کیا جاتا ہے، ہر کیس result بندش کے ذریعے نتیجہ واپس کرتا ہے۔ آرگیومینٹ call.arguments کے ذریعے مناسب قسم میں تبدیلی کے ساتھ قابل رسائی ہیں۔
Method Channel کے ساتھ کام کرتے وقت، ایپلیکیشن کی کارکردگی اور استحکام کو یقینی بنانے کے لیے کئی اہم اصولوں پر عمل کرنا ضروری ہے۔ بنیادی سفارش منتقل کردہ ڈیٹا کی مقدار اور حجم کو کم سے کم کرنا ہے، خاص طور پر اینیمیشن لوپس یا زیادہ فریکوئنسی والی کالز میں۔
نیٹیو طرف پر ہمیشہ استثنیات کو ہینڈل کرنا چاہیے اور result.error کے ذریعے انسانی پڑھنے کے قابل پیغام کے ساتھ خرابی واپس کرنی چاہیے۔ Dart طرف پر، PlatformException کو پکڑنے کے لیے ہر invokeMethod کال کو try-catch میں لپیٹنا چاہیے۔ خرابیوں کو نظر انداز کرنا واضح وجہ کے بغیر غیر متوقع ایپلیکیشن کریش کا سبب بن سکتا ہے۔
پہلے سے طے شدہ طور پر، Method Channel نیٹیو کوڈ کو پلیٹ فارم کے مرکزی دھاگے پر انجام دیتا ہے۔ اگر ہینڈلر بھاری آپریشن انجام دیتا ہے، تو Android پر Kotlin Coroutines یا iOS پر Grand Central Dispatch استعمال کرتے ہوئے عملدرآمد کو پس منظر کے دھاگے میں منتقل کرنا چاہیے۔ نتیجہ صرف مرکزی دھاگے پر کام مکمل ہونے کے بعد result کے ذریعے واپس کیا جانا چاہیے۔
الٹی ڈومین نوٹیشن استعمال کرتے ہوئے چینلز کے لیے منفرد نام منتخب کریں — مثال کے طور پر، com.example.app/feature۔ چھوٹے نام دوسرے پلگ ان سے ٹکرا سکتے ہیں۔ Flutter چینلز کو عالمی طور پر رجسٹر کرتا ہے، لہذا مختلف پلگ ان میں ایک جیسے نام ہینڈلر اوور رائٹ اور ٹوٹی ہوئی کالز کا سبب بنتے ہیں۔
اکثر پوچھے گئے سوالات
MethodChannel MethodCodec کے ذریعے انکوڈنگ کے ساتھ درخواست-جواب کے پیٹرن میں میتھڈ کال کرنے کے لیے ڈیزائن کیا گیا ہے۔ BasicMessageChannel میتھڈ اور آرگیومینٹ فارمیٹ کے بغیر صوابدیدی پیغامات بھیجتا ہے، جو سٹریمنگ ڈیٹا اور پلیٹ فارم سے آنے والے واقعات کے لیے آسان ہے۔
براہ راست — نہیں۔ StandardMessageCodec صرف بنیادی اقسام کو سپورٹ کرتا ہے: پریمیٹو، String، Uint8List، List اور Map۔ کسٹم آبجیکٹ کو بھیجنے سے پہلے دستی طور پر Map میں ترتیب دیا جانا چاہیے اور وصول کرنے والی طرف فیلڈ ڈکشنری سے دوبارہ تشکیل دیا جانا چاہیے۔
نیٹیو طرف پر، خرابی کوڈ اور پیغام کے ساتھ result.error استعمال کریں۔ Dart طرف پر، invokeMethod کو try-catch میں لپیٹیں اور PlatformException کو پکڑیں۔ اگر میتھڈ پلیٹ فارم پر لاگو نہیں کیا گیا ہے، تو result.notImplemented واپس کریں۔
ہر کال الگ تھلگ اور پلیٹ فارمز کے درمیان ترتیب اور ڈیٹا کاپی کرتی ہے۔ نایاب کالز کے لیے، اضافی بوجھ نہ ہونے کے برابر ہے۔ فی فریم میگا بائٹس ڈیٹا منتقل کرتے وقت، تاخیر اور FPS میں کمی واقع ہو سکتی ہے۔ سٹریمنگ ڈیٹا کے لیے، پلیٹ فارم ویوز یا ٹیکسچر رینڈر آبجیکٹ استعمال کریں۔
EventChannel استعمال کریں — یہ نیٹیو طرف سے Dart میں ایونٹس کی سٹریمنگ کے لیے ڈیزائن کیا گیا ہے۔ پلیٹ فارم EventSink کے ذریعے بھیجنا شروع کرتا ہے، اور Dart receiveBroadcastStream کا استعمال کرتے ہوئے سٹریم کو سبسکرائب کرتا ہے۔ Method Channel اس منظر نامے کے لیے موزوں نہیں ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔