التتبع الجغرافي في React Native

يمكن أن يكون تطبيق الهاتف المحمول بمثابة "مكان عمل" الموظف ، بينما قد يكون من الضروري نقل الإحداثيات الجغرافية والبيانات الأخرى. في تطوير التطبيقات عبر الأنظمة الأساسية على نظامي iOS و Android ، غالبًا ما يتم استخدام أطر مثل Flutter أو React Native لهذه المهمة. في هذه المقالة ، نتحدث عن ميزات العمل مع تحديد الموقع الجغرافي في React Native باستخدام مثال حالتنا.



في بعض الأحيان ، يتم انتقاد موثوقية وسرعة ونضج React Native من قبل المطورين ، ومنذ ثلاث سنوات تقريبًا يمكن اعتبار هذه الشكوك مبررة. ومع ذلك ، خلال هذا الوقت ، أصبحت التكنولوجيا أكثر تقدمًا ، وتم الاعتراف بـ React Native كأداة عملية لإنشاء مجموعة واسعة من التطبيقات. على وجه الخصوص ، React Native مناسب للتطبيقات التي تستخدم الإحداثيات الجغرافية - على سبيل المثال ، أجهزة تتبع مختلفة ، تطبيقات للسعاة ، إلخ.

تحظى تطبيقات متاجر React Native المطورة عبر الإنترنت وقوائم المطاعم وخلاصات الأخبار وتطبيقات التسليم وعملاء الوسائط الاجتماعية بشعبية كبيرة أيضًا في المتاجر. وبالتالي ، تستخدم كمية كبيرة من React Native باستمرار دون التفكير في الأمر. الأمثلة البسيطة هي Facebook و Instagram و Skype و Uber Eats و Wallmart. وفقًا للتوقعات ، يمكن لشركة Microsoft تجديد هذه القائمة ونقل تطبيقاتها المحمولة إلى React Native ، خاصة بعد أن قامت بتطبيق دعم لنظام Windows الأساسي. هناك دعم React Native لتطبيقات Weechat Qt و macOS و "المضمنة" ، على الرغم من أن الدعم والتوثيق لهذه الأنظمة الأساسية لا يزالان نادرًا.

يمكن لـ React Native أن يفعل كل شيء تقريبًا مثل التطبيق الأصلي. على سبيل المثال ، تلقي معلومات من أجهزة استشعار الجهاز ، كما تفعل تطبيقات Java / Kotlin أو ObjC / Swift ، أو إرسال البيانات في الخلفية باستخدام خدمة المقدمة أو جلب الخلفية. الاختلاف الوحيد هو أنه في React Native تحتاج إلى تنفيذ واجهة للتفاعل بين الجزء الأصلي وجافا سكريبت. بالنسبة للمهام اليومية ، غالبًا ما يتم تنفيذ هذه الواجهات بالفعل. ينطبق هذا أيضًا على تتبع موقع جافا سكريبت وتشغيله في الخلفية: هناك بالفعل حلول في شكل مكتبات مفتوحة المصدر مستقلة. حدث ذلك أن المجتمع "يسحب" بشكل مستقل Javascript إلى الأمام ، يستخدم المبرمجون والشركات بنشاط حلول Open Source. تفتخر مجتمعات لغوية قليلة العدد نفسه من المكتبات والأطر ،مرافق الجودة. ومع ذلك ، في React Native ، لا تزال بعض الميزات الموجودة في التنمية المحلية محدودة ، ويجب تذكر ذلك.

العمل مع React Native


ضع في اعتبارك العديد من العوامل الرئيسية التي تضمن سرعة تطوير التطبيقات عبر الأنظمة الأساسية على React Native:

قاعدة التعليمات البرمجية المشتركة


بمجرد كتابة المنطق ، تعمل شاشات التخطيط والمكونات على منصات مختلفة وتبدو متشابهة قدر الإمكان (على سبيل المثال ، على Android ، بدلاً من الظلال المعتادة ، يستخدمون مفهوم ابتهاج). من الناحية العملية ، لا يوجد صداع أبدي لمطور لديه إصدارات قديمة - على سبيل المثال ، من السهل إضافة دعم حتى لنظام Android 4.4 ، على الرغم من أن تنفيذ هذه المهمة يعتمد عمليًا على استخدام وحدات أصلية إضافية.

سير العمل الأمثل


في كثير من الأحيان ، يوفر React سير عمل مثالي يجعل تطوير ميزات جديدة عدة مرات أسرع من اللغات الأصلية. ينطبق هذا على التخطيط ، ونهج المكون ، وتركيب التبعية ، والحلول المعمارية المشتركة لـ React.

إعادة تحميل ساخنة


لا يحتاج المطور إلى إعادة إنشاء التطبيق في كل مرة لرؤية التغييرات. بفضل Hot Reload ، يستغرق الأمر بضع ثوانٍ لتحديث التطبيق إلى الحالة الحالية. وفي الإصدار 0.61 Live Reload (الآن هو Fast Refresh) تم وضعه في الاعتبار أيضًا ، الآن عند سحب تغييرات تنضيد التنضيد "بسرعة" ، دون إعادة تعيين الحالة الحالية للمكونات.

عند إنشاء تطبيق ، تتطلب العديد من المجالات الرئيسية اهتمامًا خاصًا:

1) جافا سكريبت

يهدف React Native إلى العمل مع جافا سكريبت ، مما يتيح لك وصف المنطق والواجهات بسرعة. هناك العديد من الوحدات الجاهزة من عالم الويب و Node.js التي يمكن استخدامها بالطريقة المعتادة (بطبيعة الحال ، إذا لم تكن متصلة بـ DOM أو إلى جانب الخادم). على الرغم من سرعتها العالية ، إلا أن جافا سكريبت أقل من اللغات الأصلية في بعض الأحيان. لا يوجد multithreading. في React Native ، لا يمكننا الوصول مباشرة إلى Native API ، على الرغم من أنه قد تتم إزالة هذا التقييد قريبًا. يصف جافا سكريبت في المقام الأول ما يجب القيام به وتقديمه في الجزء الأصلي.

2) الجسر

ناقل يقبل مكالمات جافا سكريبت من خلال واجهات خاصة توفرها مكتبة التفاعل الأصلية. المكالمات هي رسائل متسلسلة منتظمة. لكل مكون - عرض بسيط أو حقل إدخال أو استدعاء لمربع حوار النظام - هناك واجهة موصوفة في جافا سكريبت مع المنطق المنطبق في الجزء الأصلي. الحافلة هي أبطأ جزء ، وهي غير متزامنة ، ونقل البيانات بين جافا سكريبت والمواطن الأصلي يستغرق وقتًا (على الأرجح ، يمكن لـ Facebook التخلص منه تمامًا). غالبًا ما تكون مشكلات أداء التطبيقات على React Native ناتجة بالضبط عن تشغيل الجسر ، ولكن إذا كنت تستخدمه بشكل صحيح (قلل من نقل البيانات ذهابًا وإيابًا إلى الحد الأدنى الضروري) ، فلن يختلف الأداء في تطبيقات React Native بشكل كبير.

3) الجزء الأصلي

التطبيق على React Native هو في البداية تطبيق أصلي عادي. تكمن الخصوصية في أن جميع المكتبات الضرورية متصلة بها بالفعل بحيث يمكنك كتابة كل المنطق في React JS. هنا يمكننا كتابة منطقنا الأصلي الخاص لاستخدامه (أو عدم استخدامه) في JS ، إضافة مكتبات محلية عادية (على سبيل المثال ، لدعم TLS v1.2 على KitKat والإصدارات السابقة). في التطبيقات الأصلية الجاهزة ، يمكنك إضافة دعم لـ React Native.

العمل مع التتبع الجغرافي في React Native


في أحد المشاريع ، كنا بحاجة إلى تطوير "مكان عمل متنقل" لموظفي عملائنا ، على وجه الخصوص ، لضمان نقل الإحداثيات الجغرافية الخاصة بهم في الخلفية.

هناك العديد من الأدوات للعمل مع تحديد الموقع الجغرافي في React Native. على سبيل المثال ، هذه حزمة من React Native @ response-original-community-community / geolocation community ، والتي تغطي معظم حالات الاستخدام ، ومع ذلك ، لا تعمل في الخلفية.

لتنفيذ مهمتنا ، استخدمنا العديد من الحلول ، بما في ذلك مكتبة تحمل الاسم الناطق @ mauron85 / reader-original-background-geolocation. في البداية ، كانت هذه المكتبة مكونًا إضافيًا لـ Cordova ، ولكن في وقت لاحق فصل المؤلف القاعدة وقام بعمل أغلفة منفصلة لـ React Native. هناك أيضًا مكتبة مدفوعة تحمل نفس الاسم من Transistorsoft ، ولكن في وقت عملنا على المشروع ، فازت فقط بوثائقها.

سمحت لنا المكتبة بتعيين إعدادات مرنة لتتبع الموقع. على سبيل المثال ، مع أي تردد لاستجواب خدمة نظام ، وكيف تعمل بالضبط في الخلفية ، في أي نصف قطر سيعتبر الموضع غير متحرك. يمكن استخدام الإعدادات والأساليب لإرسال هذه الإحداثيات إلى الخادم "خارج الصندوق" ، لكننا قررنا عدم إرسال الرسائل غير المرغوب فيها ، ولكن لتجميع الإحداثيات المستلمة في المستودع وإرسالها بفاصل زمني كبير. في الوقت نفسه ، سمحت لنا المكتبة بإطلاق تطبيقنا كطريقة أمامية ، مما وفرنا من الصداع غير الضروري ، لأنه في العديد من تطبيقات أجهزة Android في الخلفية يمكن أن تعمل فقط مع إعدادات إضافية ( Huawei ، MIUI ، Samsung مؤخرًا ).

بعد التثبيت ، يمكنك إنشاء مكون أو مجرد مساعد يدير الخدمة. قررنا استخدام المكون لتثبيته مع الظروف في جهاز التوجيه وتوصيله بسهولة بمراجعة. إعداد خدمتنا:

import BackgroundGeolocation, {
  Location,
} from '@mauron85/react-native-background-geolocation';
 
class ForegroundService extends PureComponent<Props> {
//...
startBackgroundService = (config: GeotrackerConfig) => {
     //    
	BackgroundGeolocation.configure({
  	desiredAccuracy: BackgroundGeolocation.HIGH_ACCURACY,
  	stationaryRadius: 50,
  	distanceFilter: config.distance,
  	notificationTitle: Strings.Geolocation.NOTIFICATION_TITLE,
  	notificationText: Strings.Geolocation.NOTIFICATION_DESCRIPTION,
  	debug: false,
  	startOnBoot: false,
  	stopOnTerminate: true,
  	locationProvider: BackgroundGeolocation.ACTIVITY_PROVIDER,
  	interval: this.runnerInterval,
  	fastestInterval: 10000,
  	activitiesInterval: 30000,
  	stopOnStillActivity: false,
  	notificationIconColor: Colors.primary,
  	notificationIconSmall: 'notification_icon',
	});
 
     //    start()      
                    	BackgroundGeolocation.on('authorization', status => {
  	if (status !== BackgroundGeolocation.AUTHORIZED) {
    	//   
  	} else if (status.hasPermissions) {
        // hasPermission -  ,    
  	}
	});
 
     //  
                    	BackgroundGeolocation.start();
};


نرى أنه هنا يمكنك أيضًا تعيين إعدادات الإخطار ، وهو رمز (من الأصول الأصلية). ماذا عن الأذونات؟ بالنسبة لنظام Android ، بعد تثبيت الحزمة ، لا يوجد شيء مطلوب ، ستتولى المكتبة طلبات الوصول إلى الموقع الجغرافي للنظام. ولكن للتشغيل العادي على iOS في Xcode ، تحتاج أيضًا إلى تمكين معالجة الخلفية وتحديثات الموقع في علامة التبويب Signing & Capabilities في المشروع.



ننفذ الطريقة الرئيسية لحفظ الإحداثيات وإرسالها في حدث on ('location') بنفس الطريقة. ستعمل مع التطبيق النشط وفي الحالة المصغرة:

BackgroundGeolocation.on('location', location => {
    BackgroundGeolocation.startTask(async taskKey => {
     //       ,
     //     iOS-
      const batteryLevel = this.isSimulator
        ? 100
        : (await DeviceInfo.getBatteryLevel()) * 100;
      const updateDelta = location.time - this.lastUpdateAt;

     //      
      this.props.locationUpdate(location);
      this.props.locationAddTrackerData({
        altitude: location.altitude,
        batteryChargeLevel: batteryLevel,
        latitude: location.latitude,
        longitude: location.longitude,
        course: location.bearing,
        accuracy: location.accuracy,
        speed: location.speed,
        timestamp: Number(String(location.time).substr(0, 10)),
        isAlertOn: false,
      });

     //  ?
      if (updateDelta / 1000 > config.sendInterval) {
        this.syncDataWithInterval();
        this.lastUpdateAt = location.time;
      }

     //    AsyncStorage,    
      Storage.setLastKnownLocation(location);
      BackgroundGeolocation.endTask(taskKey);  //   !
    });
});


هنا نستدعي إجراء من المتجر ، حيث ننقل بيانات الإحداثيات بتنسيق مخصص ، بالإضافة إلى تخزين البيانات على قراءات البطارية ، باستخدام مكتبة معلومات الجهاز المتفاعل. كل هذا يعمل بشكل جيد على قدم المساواة على Android و iOS عندما يكون التطبيق نشطًا أو في الخلفية.

بالإضافة إلى ذلك ، هناك طرق للحصول على الموقع الحالي (ولكن هذا لا يعمل إلا عند تشغيل الخدمة) ، والاشتراك في انتقالات حالة التطبيق من نشطة إلى الخلفية ، والتحول إلى إعدادات النظام للتطبيق. ومع ذلك ، على العموم ، يتم توفير الأكثر ضرورة في هذه الأمثلة.

والنتيجة هي مكون يمكن تركيبه ، على سبيل المثال ، فقط للجزء المصرح به:

class ForegroundService extends PureComponent<Props> {
	//...
	componentDidMount() {
		this.startBackgroundService(this.props.config);
	}

	componentWillUnmount() {
    BackgroundGeolocation.stop();
    BackgroundGeolocation.removeAllListeners();
  }

	startBackgroundService = (config: GeotrackerConfig) => {
    BackgroundGeolocation.configure({
		// ...
	};

	render() {
    return null;
  }
} 


إذا تم استخدام الملاحة التفاعلية ، يمكنك إنشاء التنقل للجزء المصرح به على النحو التالي:

//  StackNavigator   
const Navigator = createStackNavigator(RouteConfigs, NavigatorConfig);


class AppNavigator extends PureComponent<Props> {
  static router: NavigationRouter = Navigator.router;

  componentDidMount(): void {
    SplashScreen && SplashScreen.hide();
  }

  render() {
    return (
      <>
        <ForegroundService navigation={this.props.navigation} />
        <Navigator {...this.props} />
      </>
    );
  }
}

export default AppNavigator;


علاوة على ذلك ، يمكن استخدام هذا المستكشف بالطريقة المعتادة في متصفح الجذر:

const RootNavigator = createSwitchNavigator(
  {
    Auth: AuthNavigator,
    App: AppNavigator,
  },
  {
    initialRouteName: 'Auth',
  },
);

export default createAppContainer(RootNavigator);


وبالتالي ، فإن خدمة تحديد الموقع الجغرافي وتبادل البيانات ستعمل فقط في الجزء المصرح به من التطبيق.

كي تختصر


في هذه المقالة ، درسنا ميزات استخدام React Native في تطبيقات تحديد الموقع الجغرافي. كما اكتشفنا ، باستخدام هذا الإطار ، يمكن للمطورين الآن تتبع الإحداثيات الجغرافية للجهاز بسهولة - على سبيل المثال ، في تعقب الدراجات ، وتطبيقات السعاة ووكلاء الشحن ، وتطبيقات اختيار العقارات ، إلخ. تغطي المكتبة معظم الحالات المتعلقة بالتكسير الجغرافي ، على وجه الخصوص ، تسمح لك بتعديل الفواصل الزمنية وحفظ شحن الجهاز ، وهي تعمل بثبات في الخلفية على كلا النظامين الأساسيين ، وتدعم التشغيل التلقائي على Android. في الوقت نفسه ، بالنسبة للتطبيقات المعقدة ، كقاعدة عامة ، يكون التطوير الأصلي أكثر ملاءمة (على سبيل المثال ، للعمل مع الحسابات والأدوات ، كما كتبنا بالفعل في المقالة السابقة ).

نشكرك على اهتمامك ، نأمل أن تكون المقالة مفيدة لك!

All Articles