Native Module — bu Java yoki Objective-C sinfi bo'lib, React Native-da JavaScript-dan platformaning native API-lariga kirish imkonini beradi. Har bir modul Bridge-da ro'yxatdan o'tadi va JS kodidan oddiy funksiyalar kabi chaqirilishi mumkin bo'lgan metodlarni eksport qiladi. Meta, 2024 ma'lumotlariga ko'ra, Native Module React Native ilovalarida platforma kodini integratsiya qilishning asosiy usuli bo'lib qolmoqda.
Asosiy ma'lumotlar
Native Module — React Native-ning arxitektura elementi bo'lib, platforma tilida (iOS uchun Objective-C/Swift, Android uchun Java/Kotlin) kod bajarish va natijani JavaScript-ga qaytarish imkonini beradi. Native Module bo'lmasa, qurilmaning native imkoniyatlariga — kameraga, GPS-ga, akselerometrga, fayl tizimiga yoki Bluetooth-ga kirish mumkin emas.
React Native o'rnatilgan Native Module-lar to'plami bilan keladi: CameraRoll, AsyncStorage, Geolocation, NetInfo va boshqalar. Biroq, maxsus vazifalar uchun — uchinchi tomon SDK integratsiyasi, apparat sensorlari bilan ishlash yoki fon jarayonlari — dasturchi o'z modullarini yaratadi. State of React Native 2024 so'roviga ko'ra, dasturchilarning 67% o'z loyihalarida kamida bitta maxsus Native Module dan foydalanadi.
Native Module arxitekturasi React Native versiyasiga bog'liq. Klassik arxitekturada (React Native 0.72 va eski) modul Bridge orqali ulanadi va JS bilan JSON serializatsiyasi orqali asinxron aloqa qiladi. Yangi arxitekturada (React Native 0.76+) modul Turbo Module sifatida ishlashi mumkin, serializatsiyasiz sinxron kirish uchun JSI dan foydalanadi.
Native Module ni iOS uchun yaratish RCTBridgeModule protokolini amalga oshiradigan Objective-C sinfini e'lon qilish bilan boshlanadi. RCT_EXPORT_MODULE makrosi modulni Bridge-da ro'yxatdan o'tkazadi, RCT_EXPORT_METHOD esa JavaScript-dan kirish mumkin bo'lgan metodni eksport qiladi.
// ImageCompressor.m — iOS uchun 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 metodi rasmga yo'l va siqish sifatini (0.0–1.0) qabul qiladi, ma'lumotlarni native tomonda qayta ishlaydi va siqilgan faylga yo'lni qaytaradi. Asosiy afzallik — siqish native kod bilan amalga oshiriladi, bu JavaScript-dagi o'xshash operatsiyadan sezilarli darajada tezroq va xotira jihatidan samaraliroq.
Swift modullari uchun sinf va metodlardan oldin @objc annotatsiyasidan foydalaniladi, ular Bridge ishlaydigan Objective-C muhitida mavjud bo'lishi uchun. Sinf NSObject dan meros olishi va RCTBridgeModule ni amalga oshirishi kerak.
// 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 da Native Module ReactContextBaseJavaModule dan meros oladigan Java sinfi sifatida yaratiladi. @ReactMethod annotatsiyasi metodni Bridge-ga eksport qiladi. Natijani qaytarish uchun com.facebook.react.bridge dan Promise interfeysi ishlatiladi.
// 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() metodi modulning JavaScript-dan kirish mumkin bo'lgan nomini qaytaradi. Berilgan misolda modul ImageCompressor sifatida ro'yxatdan o'tadi. @ReactMethod annotatsiyasi Bridge-ga metod eksport qilinishi kerakligini ko'rsatadi. Muhim: metodlar void bo'lishi va faqat Bridge tomonidan qo'llab-quvvatlanadigan turlarni qabul qilishi kerak: String, Boolean, Integer, Double, ReadableArray, ReadableMap, Promise.
Sinf yaratilgandan so'ng, modul ilova paketida ro'yxatdan o'tkazilishi kerak. Buning uchun ReactPackage ni amalga oshiradigan sinf yaratiladi va createNativeModules metodidagi modullar ro'yxatiga qo'shiladi.
// ImageCompressorPackage.java — modul ro'yxatdan o'tkazish
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();
}
}
Ikkala platforma uchun modullar yaratilgandan so'ng, ularni React Native-da ro'yxatdan o'tkazish kerak. Android uchun paket MainApplication.java faylida getPackages() metodiga qo'shiladi. iOS uchun modul RCT_EXPORT_MODULE makrosi orqali avtomatik ro'yxatdan o'tadi, lekin AppDelegate.mm faylida qo'lda ro'yxatdan o'tkazish ham mumkin.
// MainApplication.java — paketni React Native-ga qo'shish
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;
}
};
}
Ro'yxatdan o'tgandan so'ng, modul JavaScript-da NativeModules orqali mavjud bo'ladi. React Native avtomatik ravishda Android uchun getName() yoki iOS uchun RCT_EXPORT_MODULE da ko'rsatilgan modul nomini almashtiradi.
// JavaScript dan Native Module dan foydalanish
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('Siqildi:', result);
return result;
} catch (error) {
console.error('Siqish muvaffaqiyatsiz:', error);
throw error;
}
}
Klassik Native Module va Turbo Module ni taqqoslash yangi loyiha uchun qaysi yondashuvni tanlashni tushunishga yordam beradi. Ikkala mexanizm native kodga kirishni ta'minlaydi, ammo arxitektura va ishlash jihatidan tubdan farq qiladi.
| Xususiyat | Native Module (Bridge) | Turbo Module (JSI) |
|---|---|---|
| Aloqa | JSON orqali asinxron | JSI orqali sinxron |
| Serializatsiya | Har bir chaqiruvda JSON | Ma'lumot nusxalanmaydi |
| Tipizatsiya | Qo'lda, generatsiyasiz | Codegen orqali avtomatik |
| Yuklash | Ilova ishga tushganda | Kechiktirilgan (lazy load) |
| Moslik | React Native ning barcha versiyalari | React Native 0.73+ |
React Native 0.72 va eski versiyalaridagi mavjud loyihalar uchun klassik Native Module asosiy tanlov bo'lib qoladi. Yangi loyihalar uchun Turbo Module dan foydalanish tavsiya etiladi, ayniqsa native metodlarni tez-tez chaqirishda yuqori ishlash talab qilinsa. React Native ni bosqichma-bosqich yangilash bilan jamoa yangi arxitekturaga to'liq o'tish tomon harakat qilmoqda.
Tez-tez beriladigan savollar
Ha, Bridge callback-ni qo'llab-quvvatlaydi. Promise o'rniga iOS da RCTResponseSenderBlock va Android da Callback qayta chaqiruv funksiyalaridan foydalanish mumkin. Biroq, Promise zamonaviy standart hisoblanadi va yangi modullar uchun tavsiya etiladi.
Native Module oddiy native kod kabi tuzatiladi — Xcode yoki Android Studio da breakpoint-larni o'rnating. iOS uchun React Native bilan qurish sxemasidan, Android uchun Debug konfiguratsiyasidan foydalaning. Kirish nuqtasi — JS dan chaqirilgan metodlar.
Native Module Bridge orqali binary ma'lumotlarni (NSData/byte[]), maxsus obyektlarni va funksiyalarni qo'llab-quvvatlamaydi. Rasmlarni uzatish uchun fayl yo'li yoki base64 satridan foydalaning. JSI orqali Turbo Module bu cheklovlarning bir qismini olib tashlaydi.
Odatda yo'q — Native Module API si barqaror va orqaga mos keladi. Yangi arxitekturaga (Turbo Module) o'tishda modul dekoratorlar orqali moslashtiriladi, ammo mavjud kod ishlashda davom etadi.
iOS da RCTEventEmitter, Android da DeviceEventEmitter dan foydalaning. Modul hodisani yuboradi, JS tomoni esa react-native dan NativeEventEmitter orqali obuna bo'ladi. Bu oqim ma'lumotlari va sensor hodisalari uchun foydali.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.