Native Module एक Java या Objective-C क्लास है जो प्लेटफ़ॉर्म के नेटिव API को React Native में JavaScript से सुलभ बनाता है। प्रत्येक मॉड्यूल Bridge में रजिस्टर होता है और उन विधियों को एक्सपोर्ट करता है जिन्हें JS कोड से सामान्य फ़ंक्शन की तरह कॉल किया जा सकता है। Meta, 2024 के अनुसार, Native Module React Native अनुप्रयोगों में प्लेटफ़ॉर्म कोड को एकीकृत करने का मुख्य तरीका बना हुआ है।
मुख्य बातें
Native Module React Native का एक आर्किटेक्चरल तत्व है जो प्लेटफ़ॉर्म भाषा (iOS के लिए Objective-C/Swift, Android के लिए Java/Kotlin) में कोड निष्पादित करने और परिणाम JavaScript पर लौटाने की अनुमति देता है। Native Module के बिना डिवाइस की नेटिव क्षमताओं — कैमरा, GPS, एक्सेलेरोमीटर, फ़ाइल सिस्टम या Bluetooth तक पहुँचना असंभव है।
React Native बिल्ट-इन Native Modules के एक सेट के साथ आता है: CameraRoll, AsyncStorage, Geolocation, NetInfo और अन्य। हालांकि, विशिष्ट कार्यों के लिए — तृतीय-पक्ष SDK का एकीकरण, हार्डवेयर सेंसर के साथ काम करना या बैकग्राउंड प्रक्रियाएँ — डेवलपर कस्टम मॉड्यूल बनाता है। State of React Native 2024 सर्वेक्षण के अनुसार, 67% डेवलपर अपने प्रोजेक्ट्स में कम से कम एक कस्टम Native Module का उपयोग करते हैं।
Native Module आर्किटेक्चर React Native संस्करण पर निर्भर करता है। क्लासिक आर्किटेक्चर (React Native 0.72 और पुराने) में मॉड्यूल Bridge के माध्यम से जुड़ता है और JSON क्रमांकन के माध्यम से JS के साथ अतुल्यकालिक रूप से संचार करता है। नए आर्किटेक्चर (React Native 0.76+) में मॉड्यूल बिना क्रमांकन के तुल्यकालिक पहुँच के लिए JSI का उपयोग करके Turbo Module की तरह काम कर सकता है।
iOS के लिए Native Module बनाना एक Objective-C क्लास घोषित करने से शुरू होता है जो RCTBridgeModule प्रोटोकॉल को लागू करती है। RCT_EXPORT_MODULE मैक्रो मॉड्यूल को Bridge में रजिस्टर करता है, और RCT_EXPORT_METHOD JavaScript से उपलब्ध एक विधि को एक्सपोर्ट करता है।
// ImageCompressor.m — iOS के लिए Native Module
@interface ImageCompressor () RCT_EXPORT_MODULE()
@end
@implementation ImageCompressor
RCT_EXPORT_METHOD(compressImage:(NSString *)imagePath
quality:(NSNumber *)quality
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
NSData *compressedData = [UIImageJPEGRepresentation(image, quality.floatValue)];
NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"compressed.jpg"];
[compressedData writeToFile:outputPath atomically:YES];
resolve(outputPath);
}
@end
compressImage विधि एक छवि पथ और संपीड़न गुणवत्ता (0.0–1.0) लेती है, नेटिव साइड पर डेटा को प्रोसेस करती है और संपीड़ित फ़ाइल का पथ लौटाती है। मुख्य लाभ यह है कि संपीड़न नेटिव कोड द्वारा किया जाता है, जो समतुल्य JavaScript ऑपरेशन की तुलना में काफी तेज़ और मेमोरी-कुशल है।
Swift मॉड्यूल के लिए, क्लास और विधियों से पहले @objc एनोटेशन का उपयोग किया जाता है ताकि वे Objective-C रनटाइम के लिए उपलब्ध हों जिसके साथ Bridge काम करता है। क्लास को NSObject से इनहेरिट करना चाहिए और RCTBridgeModule को लागू करना चाहिए।
// ImageCompressor.swift — Swift Native Module
@objc(ImageCompressor)
class ImageCompressor: NSObject {
@objc
func compressImage(
_ imagePath: String,
quality: Float,
resolver: @escaping RCTPromiseResolveBlock,
rejecter: @escaping RCTPromiseRejectBlock
) {
guard let image = UIImage(contentsOfFile: imagePath) else {
rejecter("FILE_ERROR", "Cannot load image", nil)
return
}
guard let data = image.jpegData(compressionQuality: CGFloat(quality)) else {
rejecter("COMPRESS_ERROR", "Compression failed", nil)
return
}
let outputPath = NSTemporaryDirectory() + "compressed.jpg"
try? data.write(to: URL(fileURLWithPath: outputPath))
resolver(outputPath)
}
}
Android पर, Native Module ReactContextBaseJavaModule को एक्सटेंड करने वाली Java क्लास के रूप में बनाया जाता है। @ReactMethod एनोटेशन विधि को Bridge में एक्सपोर्ट करता है। परिणाम लौटाने के लिए com.facebook.react.bridge से Promise इंटरफ़ेस का उपयोग किया जाता है।
// ImageCompressorModule.java — Android Native Module
public class ImageCompressorModule
extends ReactContextBaseJavaModule {
@Override
public String getName() {
return "ImageCompressor";
}
@ReactMethod
public void compressImage(
String imagePath,
Float quality,
Promise promise) {
try {
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
File outputFile = new File(
ReactNative.getApplicationContext()
.getCacheDir(), "compressed.jpg");
FileOutputStream fos = new FileOutputStream(outputFile);
bitmap.compress(
Bitmap.CompressFormat.JPEG,
(int)(quality * 100), fos);
fos.close();
promise.resolve(outputFile.getAbsolutePath());
} catch (Exception e) {
promise.reject("COMPRESS_ERROR", e.getMessage());
}
}
}
getName() विधि मॉड्यूल का नाम लौटाती है जिसके तहत यह JavaScript से सुलभ होगा। ऊपर दिए गए उदाहरण में, मॉड्यूल ImageCompressor के रूप में रजिस्टर किया गया है। @ReactMethod एनोटेशन Bridge को बताता है कि विधि को एक्सपोर्ट किया जाना चाहिए। महत्वपूर्ण: विधियाँ void होनी चाहिए और केवल Bridge द्वारा समर्थित प्रकारों को स्वीकार करें: String, Boolean, Integer, Double, ReadableArray, ReadableMap, Promise।
मॉड्यूल क्लास बनाने के बाद, इसे एप्लिकेशन पैकेज में रजिस्टर किया जाना चाहिए। इसके लिए, ReactPackage को लागू करने वाली एक क्लास बनाई जाती है और createNativeModules विधि में मॉड्यूल सूची में जोड़ी जाती है।
// ImageCompressorPackage.java — मॉड्यूल पंजीकरण
public class ImageCompressorPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
return Arrays.asList(
new ImageCompressorModule(reactContext)
);
}
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
दोनों प्लेटफ़ॉर्म के लिए मॉड्यूल बनाने के बाद, उन्हें React Native में रजिस्टर किया जाना चाहिए। Android के लिए, पैकेज MainApplication.java में getPackages() विधि में जोड़ा जाता है। iOS के लिए, मॉड्यूल स्वचालित रूप से RCT_EXPORT_MODULE मैक्रो के माध्यम से रजिस्टर होता है, लेकिन AppDelegate.mm में मैन्युअल पंजीकरण का भी उपयोग किया जा सकता है।
// MainApplication.java — React Native में पैकेज जोड़ना
import com.yourapp.nativemodules.ImageCompressorPackage;
public class MainApplication extends Application
implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new ReactNativeHost(this) {
@Override
protected List<ReactPackage> getPackages() {
List<ReactPackage> packages =
new PackageList(this).getPackages();
packages.add(new ImageCompressorPackage());
return packages;
}
};
}
पंजीकरण के बाद, मॉड्यूल JavaScript में NativeModules के माध्यम से उपलब्ध हो जाता है। React Native स्वचालित रूप से Android के लिए getName() या iOS के लिए RCT_EXPORT_MODULE में निर्दिष्ट मॉड्यूल नाम का उपयोग करता है।
// JavaScript से Native Module का उपयोग
import { NativeModules } from 'react-native';
import { Platform } from 'react-native';
const ImageCompressor = NativeModules.ImageCompressor;
async function compressPhoto(uri: string) {
try {
const result = await ImageCompressor.compressImage(
uri.replace('file://', ''), 0.8
);
console.log('संपीड़ित:', result);
return result;
} catch (error) {
console.error('संपीड़न विफल:', error);
throw error;
}
}
क्लासिक Native Module की Turbo Module से तुलना यह समझने में मदद करती है कि नए प्रोजेक्ट के लिए कौन सा दृष्टिकोण चुनना है। दोनों तंत्र नेटिव कोड तक पहुँच प्रदान करते हैं, लेकिन आर्किटेक्चर और प्रदर्शन में मौलिक रूप से भिन्न हैं।
| विशेषता | Native Module (Bridge) | Turbo Module (JSI) |
|---|---|---|
| संचार | JSON के माध्यम से अतुल्यकालिक | JSI के माध्यम से तुल्यकालिक |
| क्रमांकन | हर कॉल पर JSON | डेटा कॉपी किए बिना |
| टाइपिंग | मैनुअल, बिना जनरेशन के | Codegen के माध्यम से ऑटो |
| लोडिंग | एप्लिकेशन इनिशियलाइज़ेशन पर | लेज़ी लोड (lazy load) |
| संगतता | सभी React Native संस्करण | React Native 0.73+ |
React Native 0.72 और पुराने संस्करणों पर मौजूदा प्रोजेक्ट्स के लिए, क्लासिक Native Modules मुख्य विकल्प बने हुए हैं। नए प्रोजेक्ट्स के लिए Turbo Module की सिफारिश की जाती है, खासकर यदि बार-बार नेटिव विधि कॉल के लिए उच्च प्रदर्शन की आवश्यकता हो। React Native के क्रमिक अपडेट के साथ, समुदाय नई आर्किटेक्चर में पूर्ण संक्रमण की ओर बढ़ रहा है।
अक्सर पूछे जाने वाले प्रश्न
हाँ, Bridge callback का समर्थन करता है। Promise के बजाय iOS में RCTResponseSenderBlock और Android में Callback फ़ंक्शन का उपयोग किया जा सकता है। हालांकि, Promise को आधुनिक मानक माना जाता है और नए मॉड्यूल के लिए अनुशंसित है।
Native Module को सामान्य नेटिव कोड की तरह डीबग किया जाता है — Xcode या Android Studio में ब्रेकपॉइंट सेट करें। iOS के लिए, React Native के साथ बिल्ड स्कीम का उपयोग करें; Android के लिए, Debug कॉन्फ़िगरेशन का उपयोग करें। प्रवेश बिंदु JS से कॉल की गई विधियाँ हैं।
Bridge के माध्यम से Native Module बाइनरी डेटा (NSData/byte[]), कस्टम ऑब्जेक्ट और फ़ंक्शन का समर्थन नहीं करता। छवियों के लिए, फ़ाइल पथ या base64 स्ट्रिंग का उपयोग करें। JSI के माध्यम से Turbo Module इनमें से कुछ सीमाओं को हटा देता है।
आमतौर पर नहीं — Native Module API स्थिर और पिछड़ा-संगत है। नए आर्किटेक्चर (Turbo Module) में संक्रमण करते समय, मॉड्यूल डेकोरेटर के माध्यम से अनुकूलित किया जाता है, लेकिन मौजूदा कोड काम करता रहता है।
iOS में RCTEventEmitter या Android में DeviceEventEmitter का उपयोग करें। मॉड्यूल एक ईवेंट भेजता है, और JS पक्ष react-native से NativeEventEmitter के माध्यम से सब्सक्राइब करता है। यह स्ट्रीमिंग डेटा और सेंसर ईवेंट के लिए उपयोगी है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें