Native Module στο React Native — τι είναι, πώς να το δημιουργήσετε και να το ενσωματώσετε

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-06-03 Χρόνος ανάγνωσης: 9 λεπ

Το Native Module είναι μια κλάση Java ή Objective-C που καθιστά τα εγγενή API της πλατφόρμας προσβάσιμα από το JavaScript στο React Native. Κάθε module καταχωρίζεται στο Bridge και εξάγει μεθόδους που μπορούν να κληθούν από κώδικα JS σαν συνηθισμένες συναρτήσεις. Σύμφωνα με τα στοιχεία της Meta, 2024, το Native Module παραμένει ο κύριος τρόπος ενσωμάτωσης κώδικα πλατφόρμας σε εφαρμογές React Native.

Βασικά σημεία

  • Native Module — γέφυρα μεταξύ JavaScript και εγγενούς κώδικα iOS ή Android.
  • Καταχώριση — το module δηλώνεται μέσω σχολιασμών iOS (RCT_EXPORT_MODULE) ή Android (@ReactMethod).
  • Τύποι δεδομένων — υποστηρίζονται πρωτότυποι τύποι, συμβολοσειρές, πίνακες, λεξικά και Promise.
  • Χρήση — από το JS το module είναι προσβάσιμο μέσω NativeModules.ΌνομαModule.
  • Νέα αρχιτεκτονική — στο React Native 0.76+ το Native Module μπορεί να λειτουργήσει ως Turbo Module μέσω JSI.

Τι είναι το Native Module;

Native Module είναι ένα αρχιτεκτονικό στοιχείο του React Native που επιτρέπει την εκτέλεση κώδικα στη γλώσσα πλατφόρμας (Objective-C/Swift για iOS, Java/Kotlin για Android) και την επιστροφή του αποτελέσματος στο JavaScript. Χωρίς το Native Module, η πρόσβαση στις εγγενείς δυνατότητες της συσκευής — κάμερα, GPS, επιταχυνσιόμετρο, σύστημα αρχείων ή Bluetooth — είναι αδύνατη.

Το React Native συνοδεύεται από ένα σύνολο ενσωματωμένων Native Module: CameraRoll, AsyncStorage, Geolocation, NetInfo και άλλα. Ωστόσο, για συγκεκριμένες εργασίες — ενσωμάτωση SDK τρίτου μέρους, εργασία με αισθητήρες υλικού ή διεργασίες παρασκηνίου — ο προγραμματιστής δημιουργεί τα δικά του modules. Σύμφωνα με την έρευνα State of React Native 2024, το 67% των προγραμματιστών χρησιμοποιεί τουλάχιστον ένα προσαρμοσμένο Native Module στα έργα τους.

Η αρχιτεκτονική του Native Module εξαρτάται από την έκδοση του React Native. Στην κλασική αρχιτεκτονική (React Native 0.72 και παλαιότερες) το module συνδέεται μέσω Bridge και επικοινωνεί με το JS ασύγχρονα μέσω σειριοποίησης JSON. Στη νέα αρχιτεκτονική (React Native 0.76+) το module μπορεί να λειτουργήσει ως Turbo Module, χρησιμοποιώντας JSI για σύγχρονη πρόσβαση χωρίς σειριοποίηση.

Δημιουργία Native Module για iOS

Η δημιουργία Native Module για iOS ξεκινά με τη δήλωση μιας κλάσης Objective-C που υλοποιεί το πρωτόκολλο RCTBridgeModule. Η μακροεντολή RCT_EXPORT_MODULE καταχωρίζει το module στο Bridge, ενώ η RCT_EXPORT_METHOD εξάγει μια μέθοδο προσβάσιμη από το JavaScript.

objective-c
// ImageCompressor.m — Native Module για iOS
@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.

Για modules Swift, χρησιμοποιείται ο σχολιασμός @objc πριν από την κλάση και τις μεθόδους ώστε να είναι προσβάσιμες στο περιβάλλον εκτέλεσης Objective-C με το οποίο λειτουργεί το Bridge. Η κλάση πρέπει να κληρονομεί από το NSObject και να υλοποιεί το RCTBridgeModule.

swift
// 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)
    }
}

Δημιουργία Native Module για Android

Στο Android το Native Module δημιουργείται ως κλάση Java που κληρονομεί από το ReactContextBaseJavaModule. Ο σχολιασμός @ReactMethod εξάγει τη μέθοδο στο Bridge. Για την επιστροφή του αποτελέσματος χρησιμοποιείται η διεπαφή Promise από το com.facebook.react.bridge.

java
// 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() επιστρέφει το όνομα του module υπό το οποίο θα είναι προσβάσιμο από το JavaScript. Στο δεδομένο παράδειγμα, το module καταχωρίζεται ως ImageCompressor. Ο σχολιασμός @ReactMethod υποδεικνύει στο Bridge ότι η μέθοδος πρέπει να εξαχθεί. Σημαντικό: οι μέθοδοι πρέπει να είναι void και να δέχονται μόνο τύπους που υποστηρίζονται από το Bridge: String, Boolean, Integer, Double, ReadableArray, ReadableMap, Promise.

Μετά τη δημιουργία της κλάσης, το module πρέπει να καταχωριστεί στο πακέτο εφαρμογής. Για αυτό δημιουργείται μια κλάση που υλοποιεί το ReactPackage και προστίθεται στη λίστα modules στη μέθοδο createNativeModules.

java
// ImageCompressorPackage.java — καταχώριση module
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();
    }
}

Καταχώριση και χρήση του Native Module

Μετά τη δημιουργία modules και για τις δύο πλατφόρμες, πρέπει να καταχωριστούν στο React Native. Για Android, το πακέτο προστίθεται στο MainApplication.java στη μέθοδο getPackages(). Για iOS, το module καταχωρίζεται αυτόματα μέσω της μακροεντολής RCT_EXPORT_MODULE, αλλά μπορεί να χρησιμοποιηθεί και χειροκίνητη καταχώριση στο αρχείο AppDelegate.mm.

java
// 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;
        }
    };
}

Μετά την καταχώριση, το module γίνεται προσβάσιμο στο JavaScript μέσω NativeModules. Το React Native αντικαθιστά αυτόματα το όνομα module που καθορίστηκε στο getName() για Android ή στο RCT_EXPORT_MODULE για iOS.

js
// Χρήση Native Module από JavaScript
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 και του Turbo Module βοηθά να κατανοήσετε ποια προσέγγιση να επιλέξετε για ένα νέο έργο. Και οι δύο μηχανισμοί παρέχουν πρόσβαση στον εγγενή κώδικα, αλλά διαφέρουν ουσιαστικά σε αρχιτεκτονική και απόδοση.

ΧαρακτηριστικόNative Module (Bridge)Turbo Module (JSI)
ΕπικοινωνίαΑσύγχρονη μέσω JSONΣύγχρονη μέσω JSI
ΣειριοποίησηJSON σε κάθε κλήσηΧωρίς αντιγραφή δεδομένων
ΤυποποίησηΧειροκίνητη, χωρίς δημιουργίαΑυτόματη μέσω Codegen
ΦόρτωσηΚατά την αρχικοποίηση εφαρμογήςΤεμπέλης (lazy load)
ΣυμβατότηταΌλες οι εκδόσεις React NativeReact Native 0.73+

Για υπάρχοντα έργα σε React Native 0.72 και παλαιότερες, το κλασικό Native Module παραμένει η κύρια επιλογή. Για νέα έργα, συνιστάται η χρήση του Turbo Module, ειδικά εάν απαιτείται υψηλή απόδοση σε συχνές κλήσεις εγγενών μεθόδων. Με τη σταδιακή ενημέρωση του React Native, η κοινότητα κινείται προς την πλήρη μετάβαση στη νέα αρχιτεκτονική.

Συχνές ερωτήσεις

Μπορώ να μεταβιβάσω callback αντί για Promise στο Native Module;

Ναι, το Bridge υποστηρίζει callback. Αντί για Promise μπορούν να χρησιμοποιηθούν οι συναρτήσεις επιστροφής RCTResponseSenderBlock στο iOS και Callback στο Android. Ωστόσο, το Promise θεωρείται σύγχρονο πρότυπο και συνιστάται για νέα modules.

Πώς να κάνω debug το Native Module στο Xcode ή στο Android Studio;

Το Native Module γίνεται debug όπως ο συνηθισμένος εγγενής κώδικας — ορίστε σημεία διακοπής στο Xcode ή στο Android Studio. Για iOS χρησιμοποιήστε το σχήμα build με React Native, για Android — διαμόρφωση Debug. Το σημείο εισόδου — μέθοδοι που καλούνται από το JS.

Ποιους τύπους δεδομένων ΔΕΝ υποστηρίζει το Native Module;

Native Module μέσω Bridge δεν υποστηρίζει δυαδικά δεδομένα (NSData/byte[]), προσαρμοσμένα αντικείμενα και συναρτήσεις. Για μετάδοση εικόνων χρησιμοποιήστε διαδρομή αρχείου ή συμβολοσειρά base64. Το Turbo Module μέσω JSI αφαιρεί μέρος αυτών των περιορισμών.

Χρειάζεται να ξαναγράψω το Native Module κατά την ενημέρωση του React Native;

Συνήθως όχι — το Native Module API είναι σταθερό και συμβατό προς τα πίσω. Κατά τη μετάβαση στη νέα αρχιτεκτονική (Turbo Module) το module προσαρμόζεται μέσω διακοσμητών, αλλά ο υπάρχων κώδικας συνεχίζει να λειτουργεί.

Πώς να στείλω συμβάν από το Native Module στο JavaScript;

Χρησιμοποιήστε το RCTEventEmitter στο iOS ή το DeviceEventEmitter στο Android. Το module στέλνει το συμβάν και η πλευρά JS εγγράφεται μέσω NativeEventEmitter από το react-native. Αυτό είναι χρήσιμο για δεδομένα ροής και συμβάντα αισθητήρων.

Περίληψη

  • Native Module — κλάση Java/Objective-C που καθιστά τα εγγενή API προσβάσιμα από το JavaScript στο React Native.
  • Καταχώριση — iOS χρησιμοποιεί RCT_EXPORT_MODULE, Android — ReactContextBaseJavaModule με @ReactMethod.
  • Κλήση — από το JS το module είναι προσβάσιμο μέσω NativeModules.Module και υποστηρίζει Promise και callback.
  • Τύποι δεδομένων — το Bridge μεταδίδει μόνο τύπους συμβατούς με JSON: συμβολοσειρές, αριθμούς, πίνακες, λεξικά.
  • Απόδοση — το κλασικό Native Module υστερεί έναντι του Turbo Module λόγω ασύγχρονης λειτουργίας και σειριοποίησης.
  • Μετάβαση — κατά τη μετάβαση σε React Native 0.76+ το module μπορεί να λειτουργήσει ως Turbo Module χωρίς επανεγγραφή λογικής.
  • Εφαρμογή — το Native Module είναι απαραίτητο για κάμερα, Bluetooth, σύστημα αρχείων και ενσωμάτωση SDK.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης