رد فعل الأصلية للصغار. تجربة تطوير المحمول

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


صورة من وصف الأداة: www.semrush.com/news/position-tracking-on-the-go .

هذا وصف موجز لتاريخ فريق Artyom Lashevsky، التي أصبحت لمدة ثلاثة أشهر من المطور الأمامي المحمول. لمزيد من التفاصيل حول كيفية حدوث ذلك ، اقرأ فك تشفير تقرير Artyom على FrontendConf 2019: ما هو React Native ، لماذا هو ، تعليمات خطوة بخطوة لإنشاء تطبيق واختيار المكتبات والمكونات المناسبة.

Artyom Lashevsky هي شركة رائدة في تطوير الواجهة الأمامية في SEMrush ومتخصصة في مجال أمن المعلومات للأنظمة الآلية.


لماذا نحتاج إلى تطبيق


SEMrush هي شركة تكنولوجيا معلومات دولية تقوم بتطوير منصة كبيرة عبر الإنترنت للمسوقين. المدرجة في أفضل 3 منصات للتسويق وتحسين محركات البحث. لدى الشركة 5 ملايين مستخدم و 7 مكاتب في قارتين و 800 موظف و 30 فريق تطوير.

يتعامل كل فريق تطوير مع أداته الخاصة داخل النظام الأساسي. أنا أعمل في أحد هذه الفرق المكونة من 8 أشخاص: اثنان في الواجهة الأمامية ، وثلاثة في الواجهة الخلفية ، QA ، DevOps engineer و PO. تسمح الأداة التي يعمل عليها فريقنا للمستخدمين بالتحقق من موضع صفحات مواقعهم لإجراء عمليات بحث معينة في Google. تساعد الأداة على التحقق من موضع الكلمات الرئيسية ليس فقط في موقعك ، ولكن أيضًا المنافسين والتحليل والمقارنة.

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

بالنسبة للمستخدمين ، يعمل التطبيق على تحسين قابلية استخدام النظام الأساسي. من خلال الهاتف ، يمكن للعميل استخدام SEMrush حيث كانت هناك حاجة لجهاز كمبيوتر سابقًا. انتقل إلى التطبيق ، وتحقق مما إذا كان موقعه قد انخفض في Google SERP أو ارتفع - المقاييس الرئيسية في متناول اليد دائمًا . إذا تراجعت ، يمكنك مشاهدة التفاصيل في إصدار الويب وفهم كيفية إصلاح الموقف.

شاهد فريقنا إمكانات تطبيق الهاتف المحمول وقرر محاولة تطويره ، ولكن لم يكن هناك مطورون متنقلون بيننا. بدأنا في دراسة الأدوات والتقنيات لتطوير التطبيقات بأنفسنا.

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



انتقلنا من التطوير الأصلي إلى دراسة WebView (Apache Cordova). كان لدى زميل أمامي خبرة في التطوير على Cordova ، لذلك في أول سباق لدراسة التقنيات والحلول ، تم تطوير أحد النماذج الأولية على Cordova.



لكننا أردنا شيئًا أكثر حداثة - "شباب عصريون" ، لذلك انتقلنا إلى حلول عبر الأنظمة الأساسية.

تطوير عبر المنصات. تم النظر في العديد من الخيارات: Flutter و Xamarin و Native Script و React Native. بالنسبة لنا ، كان لكل من الخيارات ناقص خاص به ، لأننا أردنا البدء في أقرب وقت ممكن:

  • Flutter يتطلب معرفة Dart (بديل لجافا سكريبت). لم يكن هناك وقت لدراسة التقنيات ذات الصلة - أردت أن أطير بسرعة لاختبار الفرضية.
  • Xamarin يتطلب معرفة C #. لدينا مطورين خلفية ، لكن iOS و Android يتطلبان واجهات مختلفة. على أي حال ، عليك تكرار التعليمات البرمجية والتطبيقات.
  • تم تصميم البرنامج النصي الأصلي ليتم تجميعه مع الزاوي. يستخدم مشروعنا ReactJS و Redux ، لذلك لا.
  • بدا رد فعل السكان الأصليين رائعًا ، واختاروه. بالإضافة إلى ذلك ، أردنا فقط تجربتها ، على الرغم من سلبيات ومزايا الحلول الأخرى.

أثناء الاختيار ، لم نواجه أيوني. ربما كانوا سيفكرون في الأمر أيضًا ، لكنهم اختاروا React Native على أي حال.

رد فعل الأم


هذا هو إطار Facebook لتطوير التطبيقات الأصلية عبر الأنظمة الأساسية. بنيت على أساس ReactJS ، تحت غطاء محرك السيارة لا يستخدم WebView ، لذلك ليس هناك DOM API. لا يحتوي React Native على HTML و CSS ، ولكن هناك بعض مكونات النظام الأساسي في ملفات متعددة مثل JSX و CSS.

يحتوي React Native على بعض JavaScript API على المكونات الأصلية. هذا يعني أن المكونات الأصلية لها نوع من "الارتباط" بمكونات JavaScript على ReactJS. تتم العلاقة بين الحزم الأصلية وحزم JavaScript من خلال الجسر باستخدام واجهة برمجة تطبيقات JavaScript. بشكل سطحي ، هذا كله هندسة معمارية.



رد فعل الايجابيات الأصلية:

  • عبر منصة . أردنا كتابة التطبيق في البداية في نظام iOS ، ولكن الإطلاق الإضافي في Android هو إضافة ضخمة.
  • . , . React Native , 80% .
  • . Telegram React Native 3000 . , , , .
  • . — , . , ReactJS React Native.


مع React Native ، هناك طريقتان لتطوير تطبيق: استخدام Expo أو React Native CLI.

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

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

الإقلاع في إكسبو سريع وسريع. مع Expo و Xcode و Android Studio ليست هناك حاجة. نكتب في بيئة التطوير الخاصة بنا ، وجمع التطبيق باستخدام خدمة المعرض ، والتوقيع والتحديث على الطاير.

ولكن هناك أيضًا عيوب.

  • لا يمكنك إضافة وحدات مخصصة أصلية.
  • Expo عبارة عن طبقة تجريدية على React Native. لا يمكنك الترقية إلى إصدار جديد من إطار العمل حتى يتم تحديث Expo.

تفاعل CLI الأصلي . ميزتها هي إمكانية التخصيص ، وإضافة الوحدات الأصلية.

ولكن للتوقيع وإنشاء التطبيق (والنشر) ، تحتاج إلى Xcode أو Android Studio. لاختبار التطبيق ، تحتاج إلى إنشائه وتنزيله على هاتفك ، على سبيل المثال ، باستخدام TestFlight لنظام iOS أو التثبيت المباشر من الكمبيوتر إلى الهاتف. مخطط قياسي ، ولكنه غير مريح وطويل.



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

واجه العديد من الزملاء ، باستخدام React Native ، الحاجة إلى التخصيص ، وكان لديهم فرق خاصة للقيام بالإخراج مع Expo على React Native CLI. يتم نقل بنية الدليل لملفات تطبيق بسيط من مجموعة ملفات JavaScript المعتادة إلى مجلدات Android و iOS و JavaScript. ولكن مع التطبيق المعقد ستكون هناك صعوبات.

نحن نكتب طلبًا


في المعتاد رد فعل CSS الأصلية ، DOM وعناصر الويب: div، span، li، button. ولكن هناك نوعان من مكونات النظام الأساسي في React Native.

  • عبر منصة : View، Text، Imageوغيرها.
  • خاص بكل منصة ، على سبيل المثال ، DatePickerIOSأو DatePickerAndroid.

الانتقال من ردة الفعل إلى رد فعل الأصلية بسيط: فهو يمنع divذلك View، فإنه يمنع spanذلك Text، والقوائم التي liأو ul- FlatList. لكل عنصر هناك مراسلات.

ملحوظة. لنقل مكونات الويب الجاهزة إلى غير الويب ، يمكنك كتابة ناقل ، ولكن عادة ما يكون من الأسهل إعادة كتابته مرة أخرى.

يمكنك البدء في كتابة React Native بسرعة كبيرة.

import React, {Component} from 'react';
import {Text, View, StyleSheet} from 'react-native';

export default class App extends Component {
    render() {
        return (
            <View style={styles.container}>
                <Image style={styles.image} source={require('./img/main.png')}/>
                <Text style={styles.welcome}>Hello, SEMrush!</Text>
            </View>
        );
    }
}

هناك بعض الفئات App(حاوية التطبيق). يحتوي على طريقة renderيتم فيها رسم الجزء المرئي. أنه يحتوي على الحاوية Viewالتي تذهب Imageو Text.

يحتوي كل عنصر ، على سبيل المثال ، Viewعلى سمة styleيتم تحديد قيمتها من خلال الكائن styles. يتم إنشاء

كائن stylesباستخدام الوحدة النمطية StyleSheetلأسلوب createReact Native. هذا الكائن هو ترميز كائن CSS ، وهو نموذج CSS مبسط يكفي. يتم استخدام Flexbox أيضًا لتخطيط الواجهة ، كما يتم تبسيطها ، ولكنها كافية لمحاذاةها أفقيًا وعموديًا.

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },
    image: {
        marginBottom: 20,
    },
});

تم - لقد كتبنا تطبيقًا لنظام iOS. في المستقبل ، سأوضح أنه يعمل أيضًا مع Android.


التطبيق الأول هو "Hello، World!".

عبر منصة


أردنا أن يعمل تطبيقنا على كل من Android و iOS. في الوقت نفسه ، أردنا أن نكون قادرين على تنفيذ العديد من التطبيقات اعتمادًا على النظام الأساسي. هناك طريقتان للقيام بذلك في React Native.

الطريقة الأولى هي استخدام وحدة النظام الأساسي . على سبيل المثال ، نقوم بإنشاء تطبيق وتعيين الارتفاع حسب النظام الأساسي. بالنسبة لنظام التشغيل iOS ، يبلغ الارتفاع 200 ؛ أما بالنسبة إلى Android ، فهو 100. وباستخدام الطريقة ، Platform.OSنحدد النظام الأساسي الذي يستخدمه المستخدم.

import {Platform, StyleSheet} from 'react-native';

const styles = StyleSheet.create({
    height: Platform.OS === 'ios' & 200 : 100,
});

إذا كان لدينا 40 من هذه السمات ، فلا حاجة لتكرار الرمز. هناك طريقة Platform.selectمن نفس الوحدة النمطية لهذا الغرض. تقوم بإرجاع مجموعة من الخصائص من خلال مفتاح النظام الأساسي: تحت iOS يعود backgroundColor = 'red'، تحت Android - backgroundColor = 'blue'. ونتيجة لذلك ، يمكننا إرجاع مجموعة سماتنا لنظام التشغيل iOS (يمكن أن يكون هناك 20 على الأقل ، 40 منهم على الأقل) لنظام Android - مجموعة مختلفة تمامًا.

import {Platform, StyleSheet} from 'react-native';

const styles = StyleSheet.create({
    container: {
        flex: 1,
        ...Platform.select({
            ios: {
                backgroundColor: 'red',
            },
            android: {
                backgroundColor: 'blue',
            },
        }),
    },
});

Platform.selectتسمح لك الطريقة بكتابة مكونات عبر النظام الأساسي.

const Component = Platform.select({
    ios: () => require('ComponentIOS'),
    android: () => require('ComponentAndroid'),
})();

<Component />;

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

إذا كان هناك أي حلول أو قيود مخصصة على نظام التشغيل ، يمكننا تحديد إصدار نظام التشغيل.

import {Platform} from 'react-native';

if (Platform.Version ===25) {
    console.log('Running on Nougat!');
}

import {Platform} from 'react-native';

const majorVersionIOS = parceInt(platform.Version, 10);
if (majorVersionIOS <= 9) {
    console.log('Work around a change in behavior');
}

الطريقة الثانية - استخدم امتداد الملف الخاص بالنظام الأساسي ( *.android.jsو *.ios.js). يسمح لك هذا بتطوير تطبيقات عبر الأنظمة الأساسية للحصول على كود أكبر ومنطق معقد. ثم نقوم بتقسيم جميع التعليمات البرمجية إلى ملفين ، على سبيل المثال ، BigButton.ios.jsو BigButton.android.js. في الكود حيث نريد استخدامه ، نستخدم الواجهة ونستوردها BigButton. سوف تتولى شركة React Native عمليات الاستيراد الضرورية اعتمادًا على النظام الأساسي.

مكونات


يمكننا تنفيذ حلول عبر الأنظمة الأساسية ، ولكن السرعة مهمة. لذلك ، انتقلنا نحو حلول جاهزة - مكتبات المكونات. بحث ، وسلط الضوء على الكثير من الحلول الرائعة (مجموعة واجهة المستخدم) واختر NativeBase . هذه مكتبة ضخمة تحتوي على اثني عشر مكونًا ، 12000 نجمة على GitHub ، والتي تسمح لك بحل معظم المشاكل.

   
مثال لواجهة المستخدم لنظام iOS على اليسار ، لنظام Android على اليمين.

في مشروعنا ، نستخدم هذه المكتبة جزئيًا ، ونخصص العناصر ونعين أنماطنا الخاصة. على سبيل المثال ، لدينا Buttonأو مكونات Headerنستوردها من مكتبة NativeBase.



نكتب الرمز مرة واحدة ، بينما يبدو على كل منصة مختلفة.

import React, { Component } from 'react';
import { Container, Header, Content, Button, Text } from 'native-base';
export default class ButtonThemeExample extends Component {
    render() {
        return (
            <Container>
                <Header />
                <Content>
                    <Button light><Text> Light </Text></Button>
                    <Button primary><Text> Primary </Text></Button>
                    <Button success><Text> Success </Text></Button>
                    <Button info><Text> Info </Text></Button>
                    <Button warning><Text> Warning </Text></Button>
                    <Button danger><Text> Danger </Text></Button>
                    <Button dark><Text> Dark </Text></Button>
                </Content>
            </Container>
        );
    }
}

التنقل


بالنسبة للملاحة ، قارنا أيضًا العديد من الحلول الممكنة.

  • react-navigation Facebook React Native.
  • wix/react-native-navigation — Wix. , , -, — .
  • react-router — react-router ReactJS . , .
  • airbnb/native-navigation — - Airbnb. , .

لقد اخترنا الحل الأول - الملاحة التفاعلية . إنه جافا سكريبت بالكامل ، لذلك لا داعي للقلق بشأن الملفات الأصلية. ولكن من ناحية أخرى ، فإن الأداء موضع تساؤل.

ناقشنا مع الزملاء من مجتمع React Native ، ودرسنا المقالات ، وأدركنا أن أداء التنقل التفاعلي و wix / response-original-navigation يتشابه تقريبًا. لذلك ، اختاروا الحل الأول ، وأكدت تجربة الاستخدام فقط صحة الاختيار.

   

إيجابيات الملاحة التفاعلية:

  • حل مرن عبر الأنظمة الأساسية.
  • واجهة مستخدم أصلية لكل نظام أساسي والانتقالات الأصلية بين الشاشات. لم نرغب في إنشاء تطبيق يشبه نظام التشغيل Android على نظام iOS.
  • يوفر جميع أنواع التحولات الأساسية: علامات التبويب السفلية ، والتمرير السريع بين الشاشات ، والنوافذ المشروطة SwitchNavigator.

هيكل تطبيق مثال باستخدام التنقل التفاعلي. الكود أكثر ملاءمة للقراءة من الأسفل إلى الأعلى.

const HomeStack = createStackNavigator({
    Home: { screen: HomeScreen },
    Details: {screen: DetailsScreen },
});

const SettingsStack = createStackNavigator({
    Settings: { screen: SettingsScreen },
    Details: { screen: DetailsScreen },
});

const TabNavigator = createBottomTabNavigator({
    Home: { screen: HomeStack },
    Settings: { screen: SettingsStack },
});

export default createAppContainer(TabNavigator);

createAppContainerيحتوي بعضها على createBottomTabNavigatorمكدسين. كل مجموعة لها مجموعتها الخاصة من الشاشات.


لدينا زرين - Homeو Settings. هذان هما مكدستان - HomeStackو SettingsStack. يوجد داخل كل مجموعة شاشتان: HomeScreenو DetailsScreen، SettingsScreenو ، DetailsScreenعلى التوالي. يستخدم كلا الرزمين مكونًا مشتركًا DetailsScreen. نكتب مكونًا (شاشة) ونعيد استخدامه على أكوام مختلفة.

يبدو رمز الشاشات الثلاث بسيطًا قدر الإمكان.

class HomeScreen extends React.Component {
    static navigationOptions = { title: 'Home' };

    render() {
        return (
            <View style={styles.container}>
                <Text>Home!</Text>
                <Button title="Go to Details" onPress={() => this.props.navigate('Details')}/>
            </View>
        );
    }
}

class SettingsScreen extends React.Component {
    static navigationOptions = { title: 'Settings' };

    render() {
        return (
            <View style={styles.container}>
                <Text>Settings!</Text>
                <Button title="Go to Details" onPress={() => this.props.navigate('Details')}/>
            </View>
        );
    }
}

class DetailsScreen extends React.Component {
    static navigationOptions = { title: 'Details' };

    render() {
        return (
            <View style={styles.container}>
                <Text>Details!</Text>
                <Button title="Go to Details" onPress={() => this.props.navigate('Details')}/>
            </View>
        );
    }
}

هذا هو نفس "مرحبا ، العالم!" الذي بدأنا به - لا أكثر.

أضف Redux . نلف متصفح الجذر في Provider، نلفه store. بعد ذلك، الكتابة reducer، actions، actionTypesوالباقي - كل ما هو مألوف.

const Navigation = createAppContainer(TabNavigator);

//Render the app container component with the provider around it
export default class App extends React.Component {
    render() {
        return (
            <Provider store={store}>
                <Navigation />
            </Provider>
        );
    }
}

تحتاج إلى المزيد من المكونات


عند اختيار مجموعة واجهة المستخدم النهائية ، نظرنا في العديد من الحلول الممكنة: React Native Elements ، UI Kitten ، React Native Material UI ، React Native Material Kit ، React Native Library UI Library ، React Native Paper ، Shoutem UI Toolkit ، Nachos UI ، Teaset. نتيجة لذلك ، نستخدم بعض مكونات هذه المكتبات.



يحتوي React Native أيضًا على مكونات موجهة للمنصة. ومن الأمثلة الصارخة على DatePickerAndroidو DatePickerIOS. وهي تختلف بصريًا وواجهة ، لذا يجب عليك تكرار الرمز لحل مشكلة واحدة لكلا النظامين الأساسيين.

  
على اليسار هو DatePickerAndroid ، على اليمين هو DatePickerIOS.

على سبيل المثال ، في طلبنا ، يمكنك طلب تقرير أو رسم بياني لفترة زمنية معينة. يوفر المستخدم تاريخين لتحديد فترة. ولكن على نظام التشغيل iOS ، فإن اختيار التاريخ الأصلي غير مريح ، خاصةً مقارنةً بإصدار الويب من أداتنا.



سيتعين علينا عمل حقلين: لتاريخي البدء والانتهاء. من الأنسب تحديد التواريخ في حقل واحد مثل Android ، ولكننا لن نتمكن من إعداد كل شيء أيضًا - التخصيص ضئيل .

وجدنا حلاً - wix / reader - original-calendars .
     
على اليمين مثال لتقويم من تطبيقنا بألوان الشركة.

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

تخزين


في مرحلة ما ، احتجنا إلى تخزين البيانات لعرضها في وضع عدم الاتصال أو عند استئناف العمل. للقيام بذلك ، استخدم مكتبة Async Storage (تخزين القيمة الرئيسية). يعمل مع المفاتيح والمفاتيح المتعددة (الكتابة والقراءة والحذف) ، ويوفر واجهة برمجة تطبيقات JavaScript للتفاعل مع الجزء الأصلي.

يتم تخزين بيانات IOS في شكل متسلسل. ضمن Android - على سبيل المثال ، في SQLite. كمطورين ، لا داعي للقلق بشأن هذا: هناك واجهة برمجة تطبيقات ، نقوم بتخزين البيانات ، كل شيء على ما يرام.

الرسوم المتحركة


لا يستخدم React Native تقنيات WebView المستندة إلى HTML ، لذلك ليس لدينا رسوم متحركة. هنا يساعدنا المكون المتحرك . وهو يدعم بعض مغلفة عناصر أساسية هي: View، Image، Text، ScrollView. يذهب في موضوع منفصل ولا يبطئ التطبيق ، ولكن هناك ناقص - نوع "غير إنساني" من التعليمات البرمجية.

فيما يلي مثال لشاشة تطبيقنا مع قائمة بمشاريع المستخدمين.


أعلاه Headerباسم "المشاريع" ، وهو SearchBarتصفية المشاريع. يبدو أنه SearchBarتحت Header، ولكن في الواقع هو في التيار العام للكتل التي تأتي أدناه مع قائمة المشاريع. بفضل مكون الرسوم المتحركة ، يتم تنفيذ هذه الرسوم المتحركة التي SearchBar"تختفي".

نسخة مختصرة من التنفيذ.

export default class ProjectsScreen extends Component {

    state = {
        scrollY: new Animated.Value(
            Platform.OS === 'ios' ? -HEADER_MAX_HEIGHT : 0,
        ),
    };

    render() {
        const scrollY = Animated.add(
            this.state.scrollY,
            Platform.OS === 'ios' & HEADER_MAX_HEIGHT : 0,
        );
        const headerTranslate = scrollY.interpolate({
            inputRange: [0, HEADER_SCROLL_DISTANCE],
            outputRange: [0, -HEADER_SCROLL_DISTANCE],
            extrapolate: 'clamp',
        });

        return (
            <View>
                <Animated.View style={{ translform: [{ translatY: headerTranslate }] }}>
                    <SearchBar/>
                </Animated.View>
                <Animated.ScrollView
                    onScroll={Animated.event(
                        [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
                        { useNativeDriver: true },
                    )} contentInset={{
                        top: HEADER_MAX_HEIGHT,
                    }}
                    contentOffset={{
                        y: -HEADER_MAX_HEIGHT,
                    }}
                >
                    {this._renderScrollViewContent()}
                </Animated.ScrollView>
            </View>
        );
    }
}    

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

مشكلة "الخفقان" للشاشة في البداية


كتبنا التطبيق وقررنا إضافة رمز التطبيق وشاشة البداية (أو شاشة التشغيل) - شاشة التطبيق التي تظهر عند التشغيل الأول إذا تم تفريغها من الذاكرة. لدينا شاشة باللون البرتقالي ومع شعار SEMrush في المنتصف.



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

تم حل مشكلة الوميض باستخدام مكتبة الشاشة المتفاعلة الأصلية. يوفر واجهة برمجة تطبيقات JavaScript API لإظهار شاشة تشغيل التطبيق أو إخفائها برمجيًا. من خلال واجهة برمجة التطبيقات هذه ، أزلنا شاشة Splash الأصلية في المكون مع قائمة المشاريع في الطريقة componentDidMount(). لقد وضعوا سبينر بين الشاشتين كمكافأة لجعلها تبدو أجمل.

فقدان الاتصال


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

ساعدت مكتبة Netinfo في العمل دون اتصال . إنه الآن في حزمة منفصلة ، حيث يقوم Facebook بإلغاء تحميل React Native لجعله أخف.



يتيح لك Netinfo:

  • اشترك في الأحداث ، وعند تغيير الاتصال بالإنترنت ، اعرض الرسائل للمستخدم ؛
  • تحقق من جودة الاتصال ؛
  • تحقق من نوع الاتصال (LTE ، WiFi ، 3G) للتطبيقات المعقدة ؛
  • استخدم طلب للتحقق من اتصالك بالإنترنت.

تصحيح التطبيق


لكي لا تحصل على أخطاء بعد إضافة تبعيات جديدة ، خاصة تلك التي تستخدم كود أصلي ، تحتاج إلى مصحح أخطاء. في React Native ، يتم عرضه في صورة محاكي iPhone.


بالنسبة لنظام iOS ، استخدمنا محاكيًا من Xcode ، حيث يمكنك اختيار إصدار نظام التشغيل والجهاز. محاكي Android - Android Studio.

تحتوي قائمة محاكي المحاكي على وضعين Debug JS عن بعد و Live Reload. يتيح لك رؤية خصائص المكونات ، على سبيل المثال ، الأنماط الشبيهة بـ CSS وعرض التداخل.

في التنمية المحلية ، تحتاج إلى كتابة التعليمات البرمجية وإرسالها إلى الجمعية والتشغيل - إنها فترة طويلة. في المصحح ، كل شيء هو نفسه كما في ReactJS على الويب: نقوم بتشغيل إعادة التحميل المباشر ونرى إعادة البناء في الوقت الحقيقي في المحاكي دون إعادة التشغيل.

بالإضافة إلى ذلك ، نستخدم أيضًا أدوات مطوري التفاعل لفحص المكونات وعرض التسلسلات الهيكلية وتغيير خصائصها وأنماطها.



ولكن حتى هذا لا يكفي ، هناك حل أفضل - React Native Debugger .



يحتوي على مفتش تفاعل ، Redux DevTools ، تفاعل الإنترنت ، تسجيل وحدة التحكم ، ملف تعريف الذاكرة والتطبيق ، عرض جميع الإجراءات. على عكس أول حلين ، يمكنك تغيير النمط في React Native Debugger نفسه.

ربط الوحدات الأصلية


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

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

نتيجة


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

التوقيت: استغرق تطوير التطبيق ثلاثة أشهر من شخصين. منذ أبريل 2019 ، أصدروا العديد من التحديثات بوظائف جديدة ، والتطبيق قيد التطوير ، وتريد فرق من المشاريع الأخرى تنفيذ أدواتهم فيه.

أداء React Native مرضٍ تمامًا بالنسبة لنا ، لأننا لم نكن بحاجة إلى منطق معقد وليس لدينا حمل كبير.

ردود الفعل:من الجيد تلقي تعليقات المستخدمين على التطبيق.

React Native مناسب لتطوير تطبيقات الجوال وفرضيات الاختبار بسرعة ، حتى إذا لم تكن مطورًا للجوال. إنها تتطور باستمرار ، وتظهر وظائف ومكتبات جديدة. على سبيل المثال ، قبل عام لم يكن هناك دعم للهياكل 32 و 64 بت - الآن لا توجد مشاكل مع هذا.

, , -, . , , « », . ++ 2020 — .

, , , , , — - , 5900.

All Articles