استفاده از کتابخانه اندروید و iOS در ری اکت نیتیو — راهنمای کاربردی
گاهی اوقات لازم است که اقدام به استفاده از کتابخانه اندروید و iOS در ری اکت نیتیو کنیم، اما ممکن است این کتابخانهها هنوز در ریاکت نیتیو پشتیبانی نشده باشند. در این مقاله با روش ایجاد یک پل ریاکت نیتیو جهت بهرهگیری از کتابخانههای نیتیو اندروید و iOS آشنا میشویم. کد کامل این پروژه در این ریپوی گیتهاب (+) ارائه شده است.
در این مقاله به عنوان نمونه به بررسی شیوه استفاده از کتابخانه Helpshift (+) میپردازیم که یک پلتفرم پشتیبانی از مشتری است. اگر بررسی کنید متوجه میشوید که امکان پشتیبانی از ریاکت نیتیو به این کتابخانه اضافه نشده است و لذا باید خودمان دست به کار شویم. اگر زمان اندکی برای انجام این کار دارید، بهترین راهنما را برای مطالعه انتخاب کردهاید.
مقدمه
در این راهنما یک overlay صفحه بارگذاری نیتیو میسازیم که میتوان از هر جایی در ریاکت نیتیو آن را فراخوانی کرد. برای iOS از JGProgressHUD و برای اندروید از KProgressHUD استفاده میکنیم. دلیل انتخاب این کتابخانه آن است که بسیار شبیه هم هستند و API کاملاً مشابهی دارند.
نام پروژه خود را ReactNativeLoadingSpinnerOverlayNativeTutorial انتخاب کردهایم که از روی این پروژه موجود (+) ساخته شده است، اما به جای کامپوننتهای ریاکت نیتیو از کتابخانههای iOS و اندروید استفاده میکند. ظاهر آن به صورت زیر است:
iOS
مراحل کار در سمت iOS به صورت زیر است:
نصب کتابخانه iOS
کد زیر را به فایل pod اضافه کنید:
pod ‘JGProgressHUD’
برای نصب pod دستور زیر را اجرا کنید:
cd ios && pod install
ساخت پل iOS
فایلهای نیتیو را برای ماژول با باز کردن فایل workspace در Xcode آغاز میکنیم و سپس پروژه را انتخاب کرده و روی فایل جدید راست-کلیک میکنیم:
گزینه Cocoa Touch Class را انتخاب و روی Next کلیک میکنیم:
نام دلخواه را روی ماژول میگذاریم و روی Next کلیک میکنیم:
سپس روی Create کلیک میکنیم:
اکنون باید دو فایل داشته باشیم که در این مورد LoadingOverlay.h و LoadingOverlay.m نام دارند:
با کپی کردن کد زیر به فایل 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)
اندروید
در این بخش مراحل کار را روی سیستم عامل اندروید توضیح میدهیم.
1. نصب کتابخانه اندروید
کد زیر را در بخش وابستگیهای اپلیکیشن در فایل build.gradle درون پوشه android/app قرار دهید:
dependencies { // Other dependencies implementation 'com.kaopiz:kprogresshud:1.2.0' }
2. ایجاد پل اندروید
دو فایل زیر را با نامهای LoadingOverlay.java و LoadingOverlayPackager.java به پروژه خود و در کنار فایل MainActivity.java اضافه کنید:
با کپی کردن کد زیر به فایل 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
سخن پایانی
اینک کدنویسی به پایان رسیده و نتیجه کار به صورت زیر است:
امیدواریم از مطالعه این راهنما بهرهمند شده باشید و بتوانید با دانشی که از مطالعه این راهنما به دست آوردهاید ماژولهای پیچیدهتری را پیادهسازی کنید.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- آموزش مقدماتی فریمورک React Native برای طراحی نرم افزارهای اندروید و iOS با زبان جاوااسکریپت
- چه زمانی از React Native برای توسعه اپلیکیشن موبایل استفاده کنیم؟
- افزودن صفحه آغازین (Splash Screen) به اپ React Native — از صفر تا صد
==