استفاده از کتابخانه اندروید و iOS در ری اکت نیتیو — راهنمای کاربردی

۷۰ بازدید
آخرین به‌روزرسانی: ۲۹ آبان ۱۴۰۲
زمان مطالعه: ۶ دقیقه
استفاده از کتابخانه اندروید و iOS در ری اکت نیتیو — راهنمای کاربردی

گاهی اوقات لازم است که اقدام به استفاده از کتابخانه اندروید و iOS در ری اکت نیتیو کنیم، اما ممکن است این کتابخانه‌ها هنوز در ری‌اکت نیتیو پشتیبانی نشده باشند. در این مقاله با روش ایجاد یک پل ری‌اکت نیتیو جهت بهره‌گیری از کتابخانه‌های نیتیو اندروید و iOS آشنا می‌شویم. کد کامل این پروژه در این ریپوی گیت‌هاب (+) ارائه شده است.

در این مقاله به عنوان نمونه به بررسی شیوه استفاده از کتابخانه Helpshift (+) می‌پردازیم که یک پلتفرم پشتیبانی از مشتری است. اگر بررسی کنید متوجه می‌شوید که امکان پشتیبانی از ری‌اکت نیتیو به این کتابخانه اضافه نشده است و لذا باید خودمان دست به کار شویم. اگر زمان اندکی برای انجام این کار دارید، بهترین راهنما را برای مطالعه انتخاب کرده‌اید.

مقدمه

در این راهنما یک overlay صفحه بارگذاری نیتیو می‌سازیم که می‌توان از هر جایی در ری‌اکت نیتیو آن را فراخوانی کرد. برای iOS از JGProgressHUD و برای اندروید از KProgressHUD استفاده می‌کنیم. دلیل انتخاب این کتابخانه آن است که بسیار شبیه هم هستند و API کاملاً مشابهی دارند.

نام پروژه خود را ReactNativeLoadingSpinnerOverlayNativeTutorial انتخاب کرده‌ایم که از روی این پروژه موجود (+) ساخته شده است، اما به جای کامپوننت‌های ری‌اکت نیتیو از کتابخانه‌های iOS و اندروید استفاده می‌کند. ظاهر آن به صورت زیر است:

کتابخانه اندروید و iOS در ری اکت نیتیو

iOS

مراحل کار در سمت iOS به صورت زیر است:

نصب کتابخانه iOS

کد زیر را به فایل pod اضافه کنید:

pod ‘JGProgressHUD’

برای نصب pod دستور زیر را اجرا کنید:

cd ios && pod install

ساخت پل iOS

فایل‌های نیتیو را برای ماژول با باز کردن فایل workspace در Xcode آغاز می‌کنیم و سپس پروژه را انتخاب کرده و روی فایل جدید راست-کلیک می‌کنیم:

کتابخانه اندروید و iOS در ری اکت نیتیو

گزینه Cocoa Touch Class را انتخاب و روی Next کلیک می‌کنیم:

کتابخانه اندروید و iOS در ری اکت نیتیو

نام دلخواه را روی ماژول می‌گذاریم و روی Next کلیک می‌کنیم:

کتابخانه اندروید و iOS در ری اکت نیتیو

سپس روی Create کلیک می‌کنیم:

کتابخانه اندروید و iOS در ری اکت نیتیو

 

اکنون باید دو فایل داشته باشیم که در این مورد LoadingOverlay.h و LoadingOverlay.m نام دارند:

کتابخانه اندروید و iOS در ری اکت نیتیو

با کپی کردن کد زیر به فایل LoadingOverlay.h اقدام به ساخت پل می‌کنیم:

1//
2//  BridgeTemplate.h
3//  ReactNativeLoadingSpinnerOverlayNative
4//
5//  Created by Andre Pimenta on 11/07/2019.
6//  Copyright © 2019 Facebook. All rights reserved.
7//
8
9#import "React/RCTBridgeModule.h"
10
11// Instead of LoadingOverlay put the name of your module
12@interface LoadingOverlay : NSObject <RCTBridgeModule>
13@end

کد زیر را در نیز به فایل LoadingOverlay.m کپی می‌کنیم:

1//
2//  BridgeTemplate.m
3//  ReactNativeLoadingSpinnerOverlayNative
4//
5//  Created by Andre Pimenta on 11/07/2019.
6//  Copyright © 2019 Facebook. All rights reserved.
7//
8
9#import "React/RCTLog.h"
10#import "LoadingOverlay.h" // Here put the name of your module
11
12@implementation LoadingOverlay // Here put the name of your module
13
14// This RCT (React) "macro" exposes the current module to JavaScript
15RCT_EXPORT_MODULE();
16
17RCT_EXPORT_METHOD(toggle:(BOOL *)show
18                 resolver:(RCTPromiseResolveBlock)resolve
19                 rejecter:(RCTPromiseRejectBlock)reject)
20{
21  dispatch_async(dispatch_get_main_queue(), ^{
22    
23    @try{ 
24      resolve(@{ @"key": [NSNumber numberWithBool:1] });
25    }
26    @catch(NSException *exception){
27      reject(@"get_error",exception.reason, nil);
28    }
29  });
30}
31
32@end

بدین ترتیب پلی ساخته می‌شود که می‌توان از ری‌اکت نیتیو فراخوانی کرد.

چنان که می‌بینید نام تابع toggle است که یک مقدار بولی به نام show می‌گیرد. درون تابع می‌توان روی کد نیتیو کار کرد.

پیاده‌سازی کتابخانه بومی iOS

در این بخش به بررسی مثالی از JGProgressHUD (+) می‌پردازیم:

1JGProgressHUD *HUD = [JGProgressHUD progressHUDWithStyle:JGProgressHUDStyleDark];
2HUD.textLabel.text = @"Loading";
3[HUD showInView:self.view];
4[HUD dismissAfterDelay:3.0];

بدین ترتیب وهله‌ای از HUD با برخی گزینه‌ها ساخته می‌شود و در یک self.view نمایش می‌یابد. سپس در طی 3 ثانیه بسته می‌شود. اینک این وضعیت را در یک فایل LoadingOverlay.m پیاده‌سازی می‌کنیم.

می‌خواهیم زمانی که show مقدار true داشت نمایش یابد و در غیر این صورت پنهان شود:

1HUD = [JGProgressHUD progressHUDWithStyle:JGProgressHUDStyleDark];
2if(show){
3 UIWindow *window = [[UIApplication sharedApplication] keyWindow];
4 UIView *topView = window.rootViewController.view;
5 HUD.textLabel.text = @"Loading";
6 [HUD showInView:topView];
7}else{
8 [HUD dismiss];
9}

اکنون کل فایل به صورت زیر در آمده است:

1//
2//  LoadingOverlay.m
3//  ReactNativeLoadingSpinnerOverlayNative
4//
5//  Created by Andre Pimenta on 11/07/2019.
6//  Copyright © 2019 Facebook. All rights reserved.
7//
8
9#import "React/RCTLog.h"
10#import "LoadingOverlay.h"
11#import "JGProgressHUD.h"
12#import <UIKit/UIKit.h>
13@implementation LoadingOverlay
14
15// This RCT (React) "macro" exposes the current module to JavaScript
16RCT_EXPORT_MODULE();
17
18JGProgressHUD *HUD;
19
20RCT_EXPORT_METHOD(toggle:(BOOL *)show
21                 resolver:(RCTPromiseResolveBlock)resolve
22                 rejecter:(RCTPromiseRejectBlock)reject)
23{
24  dispatch_async(dispatch_get_main_queue(), ^{
25    
26    @try{
27      if(!HUD)
28        HUD = [JGProgressHUD progressHUDWithStyle:JGProgressHUDStyleDark];
29
30      if(show){
31        UIWindow *window = [[UIApplication sharedApplication] keyWindow];
32        UIView *topView = window.rootViewController.view;
33        HUD.textLabel.text = @"Loading";
34        [HUD showInView:topView];
35      }else{
36        [HUD dismiss];
37      }
38      
39      
40      resolve(@{ @"key": [NSNumber numberWithBool:1] });
41    }
42    @catch(NSException *exception){
43      reject(@"get_error",exception.reason, nil);
44    }
45  });
46}
47
48@end

توجه داشته باشید که JGProgressHUD *HUD را در ابتدای فایل وهله‌سازی کرده‌ایم. سپس از آن به صورت یک کتابخانه iOS نرمال با امکان فراخوانی از ری‌اکت نیتیو بهره گرفتیم.

ضمناً توجه کنید که پنجره اصلی را که HUD در آن نمایش می‌یابد به دست آوردیم. این وضعیت در مواردی که این پل‌ها را می‌سازیم بسیار ضروری است، چون غالباً باید پنجره اپلیکیشن اصلی را به دست آوریم.

این به بخش نیتیو مربوط بود. اینک می‌توانیم در سمت ری‌اکت نیتیو آن را در هر جا که دوست داریم فراخوانی کنیم:

1import { NativeModules } from 'react-native';
2var LoadingOverlay = NativeModules.LoadingOverlay;
3//Let's show it
4LoadingOverlay.toggle(true).then(result => {
5  console.log('show', result)
6})
7// And let's hide it after 3 seconds
8setTimeout(()=>{
9  LoadingOverlay.toggle(false).then(result=>{
10      console.log("hide", result)
11  })
12}, 3000)

 

کتابخانه اندروید و iOS در ری اکت نیتیو

اندروید

در این بخش مراحل کار را روی سیستم عامل اندروید توضیح می‌دهیم.

1. نصب کتابخانه اندروید

کد زیر را در بخش وابستگی‌های اپلیکیشن در فایل build.gradle درون پوشه android/app قرار دهید:

dependencies {
// Other dependencies
implementation 'com.kaopiz:kprogresshud:1.2.0'
}

2. ایجاد پل اندروید

دو فایل زیر را با نام‌های LoadingOverlay.java و LoadingOverlayPackager.java به پروژه خود و در کنار فایل MainActivity.java اضافه کنید:

کتابخانه اندروید و iOS در ری اکت نیتیو

با کپی کردن کد زیر به فایل LoadingOverlayPackager.java، پل را بسازید:

1//PUT YOUR PACKAGE HERE, IT'S THE SAME AS IN MainApplication.java
2package com.reatnativeloadingspinneroverlaynativetutorial;
3
4import com.facebook.react.ReactPackage;
5import com.facebook.react.bridge.JavaScriptModule;
6import com.facebook.react.bridge.NativeModule;
7import com.facebook.react.bridge.ReactApplicationContext;
8import com.facebook.react.uimanager.ViewManager;
9
10import java.util.ArrayList;
11import java.util.Collections;
12import java.util.List;
13
14//CHANGE LoadingOverlay WITH THE NAME OF YOUR CHOICE
15public class LoadingOverlayPackager implements ReactPackage {
16
17    @Override
18    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
19        return Collections.emptyList();
20    }
21
22    @Override
23    public List<NativeModule> createNativeModules(
24            ReactApplicationContext reactContext) {
25        List<NativeModule> modules = new ArrayList<>();
26
27        modules.add(new LoadingOverlay(reactContext));
28
29        return modules;
30    }
31
32}

نکته مهم: نام پکیج را در کد خودتان عوض کنید.

کد زیر را نیز به فایل LoadingOverlay.java اضافه کنید:

1//PUT YOUR PACKAGE HERE, IT'S THE SAME AS IN MainApplication.java
2package com.reatnativeloadingspinneroverlaynativetutorial;
3
4import com.facebook.react.ReactPackage;
5import com.facebook.react.bridge.JavaScriptModule;
6import com.facebook.react.bridge.NativeModule;
7import com.facebook.react.bridge.ReactApplicationContext;
8import com.facebook.react.uimanager.ViewManager;
9
10import java.util.ArrayList;
11import java.util.Collections;
12import java.util.List;
13
14//CHANGE LoadingOverlay WITH THE NAME OF YOUR CHOICE
15public class LoadingOverlayPackager implements ReactPackage {
16
17    @Override
18    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
19        return Collections.emptyList();
20    }
21
22    @Override
23    public List<NativeModule> createNativeModules(
24            ReactApplicationContext reactContext) {
25        List<NativeModule> modules = new ArrayList<>();
26
27        modules.add(new LoadingOverlay(reactContext));
28
29        return modules;
30    }
31
32}

نکته مهم: نام پکیج را در کد خود عوض کنید.

بدین ترتیب پلی ساخته می‌شود که می‌توانید از هر جایی در ری‌اکت نیتیو آن را فراخوانی کنید. چنان که می‌بینید، تابعی که toggle تام دارد یک مقدار بولی به نام show می‌گیرد. درون این تابع می‌توان با کد نیتیو کار کرد.

برای این که اندروید بداند ماژول ما وجود دارد باید آن را در لیست پکیج‌ها در فایل MainApplication.java اضافه کنیم:

new LoadingOverlayPackager()

3. پیاده‌سازی کتابخانه نیتیو اندروید

اینک به بررسی مثالی از KProgressHUD می‌پردازیم:

1KProgressHUD.create(MainActivity.this)
2	.setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
3	.setLabel("Please wait")
4	.setDetailsLabel("Downloading data")
5	.setCancellable(true)
6	.setAnimationSpeed(2)
7	.setDimAmount(0.5f)
8	.show();

بدین ترتیب HUD با برخی گزینه‌ها وهله‌سازی می‌شود و سپس HUD در یک اکتیویتی نمایش می‌یابد. اینک زمان آن رسیده که این مورد را در فایل LoadingOverlay.java پیاده‌سازی کنیم.

قصد ما این است که در صورت true بودن مقدار show آن را نمایش دهیم و در غیر این صورت آن را پنهان سازیم:

1KProgressHUD hud = KProgressHUD.create(activity);
2if(show){
3 hud.setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
4 .setLabel("Please wait")
5 .setAnimationSpeed(2)
6 .setDimAmount(0.1f)
7 .show();
8}else{
9 hud.dismiss();
10}

اینک کل فایل به صورت زیر در آمده است:

1//PUT YOUR PACKAGE HERE, IT'S THE SAME AS IN MainApplication.java
2package com.reatnativeloadingspinneroverlaynativetutorial;
3
4import com.facebook.react.bridge.NativeModule;
5import com.facebook.react.bridge.ReactApplicationContext;
6import com.facebook.react.bridge.ReactContext;
7import com.facebook.react.bridge.ReactContextBaseJavaModule;
8import com.facebook.react.bridge.ReactMethod;
9import android.app.Activity;
10
11import com.kaopiz.kprogresshud.KProgressHUD;
12
13//CHANGE LoadingOverlay WITH THE NAME OF YOUR CHOICE
14public class LoadingOverlay extends ReactContextBaseJavaModule {
15
16    KProgressHUD hud;
17
18    public LoadingOverlay(ReactApplicationContext reactContext) {
19        super(reactContext);
20    }
21
22    @Override
23    public String getName() {
24        return "LoadingOverlay";
25    }
26
27    @ReactMethod
28    public void toggle(Boolean show) {
29        final Activity activity = getCurrentActivity();
30        // PUT YOUR NATIVE CODE HERE
31
32        if (hud == null) {
33            hud = KProgressHUD.create(activity);
34        }
35
36        if (show) {
37            hud.setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
38                .setLabel("Please wait")
39                .setAnimationSpeed(2)
40                .setDimAmount(0.1f).show();
41        } else {
42            hud.dismiss();
43        }
44
45    }
46}

توجه کنید که KProgressHUD hud را در ابتدای فایل وهله‌سازی کرده‌ایم. می‌توانیم از آن مانند یک کتابخانه نرمال اندروید با امکان فراخوانی در هر جای ری‌اکت نیتیو استفاده کنیم.

ضمناً توجه کنید که اکتیویتی نمایش‌دهنده HUD را چطور به دست آورده‌ایم. همان طور که در بخش iOS اشاره شد، این کار در زمان ساخت این پل‌ها کاملاً رایج است، چون اغلب باید اکتیویتی اپلیکیشن اصلی را به دست آوریم.

به این ترتیب کار به پایان می‌رسد. در سمت ری‌اکت نیتیو می‌توان هر دو ماژول نیتیو اندروید و iOS را فراخوانی کرد. در ادامه مثال کاملی از فراخوانی ماژول نیتیو از سوی کامپوننت ری‌اکت نیتیو را می‌بینید:

1/**
2 * Sample React Native App
3 * https://github.com/facebook/react-native
4 *
5 * @format
6 * @flow
7 */
8
9import React, {Component} from 'react';
10import {
11  View,
12  StyleSheet
13} from 'react-native';
14import { NativeModules } from 'react-native';
15
16class App extends Component {
17
18  componentDidMount(){
19	var LoadingOverlay = NativeModules.LoadingOverlay;
20	//Let's show it
21	LoadingOverlay.toggle(true)
22	// And let's hide it after 3 seconds
23	setTimeout(()=>{
24		LoadingOverlay.toggle(false)
25	}, 3000)
26  }
27
28  render(){
29	return ( <View style={styles.background}></View>)
30  }
31};
32
33const styles = StyleSheet.create({
34  background: {
35	backgroundColor: '#6ce6cb',
36	flex: 1,
37  },
38});
39
40export default App

سخن پایانی

اینک کدنویسی به پایان رسیده و نتیجه کار به صورت زیر است:

کتابخانه اندروید و iOS در ری اکت نیتیو

امیدواریم از مطالعه این راهنما بهره‌مند شده باشید و بتوانید با دانشی که از مطالعه این راهنما به دست آورده‌اید ماژول‌های پیچیده‌تری را پیاده‌سازی کنید.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۱ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
better-programming
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *