ساخت اپلیکیشن موبایل بدون سرور با React Native و AWS – راهنمای پیشرفته


در این مقاله با شیوه ساخت اپلیکیشنهای موبایل با استفاده از AWS Amplify و React Native که کلاً فاقد سرور و بکاند هستند آشنا خواهیم شد. این اپلیکیشنها شامل قابلیتهایی از جمله احراز هویت، analytics، یک لایه داده مدیریتشده، ذخیرهسازی و پوش نوتیفیکیشن خواهند بود. برای خوانندگان داخل ایران باید توضیح دهیم که سرویسهای AWS در ایران تحریم شده است و شما برای استفاده از این خدمات باید به نحوی این تحریمها را دور بزنید. با ما همراه باشید تا با روش ساخت اپلیکیشن موبایل بدون سرور آشنا شوید.
الزامات مختلف ساخت اپلیکیشن موبایل
زمانی که میخواهیم یک اپلیکیشن موبایل واقعی بسازیم، الزامات زیادی وجود دارند که باید رعایت شوند. ما به روشی برای احراز هویت کاربران نیاز داریم. باید میزان engagement و مصرف هر کاربر را اندازهگیری کنیم و احتمالاً باید بتوانیم پوش نوتیفیکیشن ارسال کنیم و این پیامها باید بر مبنای رویدادها یا رفتار کاربر باشند. همچنین باید بتوانیم دادههای اپلیکیشن را مدیریت کنیم و احتمالاً با نقاط انتهایی REST متعددی سروکار داشته باشیم. معمولاً لازم است با رسانههایی از جمله تصاویر و ویدئوها نیز کار بکنیم و بتوانیم کاربردهای آفلاین را نیز مدیریت کنیم تا اپلیکیشن در صورت دسترسی به شبکه یا عدم دسترسی بتواند کار بکند.
با توجه به توصیفهای فوق، هر روز شاهد کاربرد فزاینده توسعهدهندگان و شرکتها از مزیت سرویسهای مدیریتشده برای کاهش وابستگی به ساخت و مدیریت زیرساخت مستقل و الزام به ساخت همه این کارکردها از صفر و لذا کاهش هزینه و پیچیدگی کار بکاند هستیم.
در عصر حاضر این امکان فراهم شده است که یک توسعهدهنده منفرد بدون تجربه بکاند زیاد بتواند اپلیکیشنهایی با امکانات کامل ساخته و عرضه کند و این کار با استفاده از مزیت سرویسهای مدیریتشده بکاند فراهم شده است. این امکان زمینه انقلاب مهم بعدی در صنعت نرمافزار یعنی توسعه اپلیکیشن بدون بکاند را آماده کرده است.
برخی از کاربردهای محبوبتر این فناوری شامل سرویسهای پوش نوتیفیکیشن، ارائهدهندگان خدمات احراز هویت، و سرویسهای آنالیتیکس هستند. همچنین امروزه سرویسهایی مانند AWS AppSync وجود دارند که لایههای داده کاملاً مدیریتشده ارائه میکنند و از این رو میتوانیم پیچیدگی کار و ساخت و نگهداری بکاند و API را به سرویس مدیریتشده با یک نقطه انتهایی منفرد GraphQL بسپاریم.
در این راهنما به بررسی شیوه بهرهگیری از AWS Mobile CLI برای ثبت نام سریع در این سرویسها و افزودن این کارکردهای جدید به اپلیکیشن ریاکت نیتیو با استفاده از SDK جاوا اسکریپت AWS Amplify میپردازیم.
SDK جاوا اسکریپت AWS Amplify یک API منسجم روی همه سرویسهای AWS و سرویسهای مدیریتشده ارائه و عرضه کرده است. بدین ترتیب امکان پشتیبانی کامل از فریمورکهای جاوا اسکریپت از قبیل React Native ،React و Angular فراهم شده است.
پروژههایی که در این راهنما ایجاد میکنیم، با استفاده از AWS Mobile CLI ساخته میشوند، اما از طریق کنسول AWS Mobile Hub نیز قابل مشاهده هستند که در ادامه این موضوع را نیز توضیح خواهیم داد.
در این مقاله نه تنها به بررسی شیوه ایجاد سرویسها از طریق AWS Mobile CLI میپردازیم، بلکه شیوه ادغام آنها در یک اپلیکیشن ریاکت نیتیو با استفاده از AWS Amplify را نیز توضیح میدهیم.
شروع
توضیحات تئوریک کافی است و از اینجا به بعد شروع به کار عملی میکنیم.
ایجاد اپلیکیشن ریاکت نیتیو
قبل از هر چیز باید یک پروژه ریاکت نیتیو با استفاده از React Native CLI یا Create React Native App CLI ایجاد کنیم:
react-native init ServerlessProject
سپس به دایرکتوری مربوطه میرویم:
cd ServerlessProject
نصب AWS Mobile CLI
AWS Mobile CLI یک روش سریع و آسان برای راهاندازی پروژههای جدید AWS Mobile Hub از خط فرمان ارائه میکند.
برای شروع اگر AWS Mobile CLI را نصب نکردهاید، باید آن را نصب و پیکربندی کنید:
npm i -g awsmobile-cli awsmobile configure
زمانی که CLI نصب و پیکربندی شد، باید در ادامه یک پروژه جدید AWS Mobile ایجاد کنیم. در دایرکتوری ریشه پروژه React Native یک پروژه جدید AWS Mobile به صورت زیر ایجاد کنید:
awsmobile init
در اینجا به همه سؤالهای دستور فوق به صورت پیشفرض پاسخ دهید.
به این ترتیب چندین وابستگی نیز در پروژه نصب میشوند. اینک باید aws-amplify و aws-amplify-react-native را نیز در فایل package.json خود ببینید.
اکنون به یک لینک به وابستگی نیتیو aws-amplify نیاز داریم:
react-native link amazon-cognito-identity-js
بدین ترتیب پروژه Mobile Hub جدید در داشبورد AWS ایجاد میشود. اینک میتوانید پروژه و پیکربندی آن را هر زمان با اجرای دستور awsmobile console از ریشه دایرکتوری ریاکت نیتیو ببینید.
پیکربندی اپلیکیشن با پروژه AWS Mobile Hub جدید
اکنون که پروژه AWS Mobile Hub ایجاد شده و وابستگیها نصب شدهاند باید به پیکربندی پروژه ریاکت نیتیو بپردازیم.
در فایل index.js کدهای زیر را اضافه کنید:
import { AppRegistry } from 'react-native'; import App from './App'; import Amplify from 'aws-amplify' // NEW import config from './aws-exports' // NEW Amplify.configure(config) // NEW AppRegistry.registerComponent('ServerlessProject', () => App);
ثبت نام و ورود کاربر
نخستین چیزی که باید بررسی کنیم شیوه افزودن امکان ثبت نام و ورود کاربر در اپلیکیشن است. به این منظور باید این امکان را در Mobile Hub Project فعال کنیم:
awsmobile user-signin enable awsmobile push
اکنون امکان ثبت نام و ورود کاربر از طریق Amazon Cognito فراهم شده است و میتوانیم بیدرنگ شروع به ثبت نام از کاربران کرده و اجازه ورود به آنها بدهیم. اگر به مستندات نگاه کنید، میبینید که دو روش متمایز برای انجام این کار وجود دارد:
میتوانیم از کامپوننتهای ریاکت و کامپوننتهای مرتبه بالا برای کارکرد و UI از پیش پیکربندیشده استفاده کنیم. میتوانیم این کارکرد را از صفر با استفاده از کلاس Auth بنویسیم که متدهایی از قبیل Auth.signUp() و Auth.signIn() دارد.
کامپوننتهای ریاکت نیتیو
ابتدا باید شیوه استفاده از کامپوننت مرتبه بالای withAuthenticator از aws-amplify-react-native را ببینیم. در App.js زیر ایمپورتهای ریاکت نیتیو اقدم به ایمپورت withAuthenticator میکنیم.
import { withAuthenticator } from 'aws-amplify-react-native'
سپس به جای این که در این کلاس از default export استفاده کنیم، از این HOC به عنوان اکسپورت پیشفرض بهره میگیریم:
class App extends Component { // all of this code stays the same } export default withAuthenticator(App)
سپس اپلیکیشن را اجرا میکنیم:
react-native run-ios // or react-native run-android
اکنون یک کارکرد کامل برای ثبت نام و ورود در بخش فرانت اپلیکیشن داریم. برای به دست آوردن کارکرد مشابه، میتوانید از کامپوننت <Authenticator /> برای قرار دادن همه چیز درون کامپوننت صلی که باید احراز هویت شود استفاده کنید:
<Authenticator> <App /> </Authenticator>
در کامپوننتی که درون احراز هویت قرار گرفته یعنی App باید به یک prop دسترسی داشته باشیم که برای رندر مشروط استفاده میشود. authState دارای مقادیر مختلفی از جمله signIn ،signUp و signedIn است تا حالت احراز هویت کنونی را به درستی شناسایی کند.
کلاس Auth
از کلاس Auth نیز میتوان برای احراز هویت کاربران استفاده کرد:
import { Auth } from 'aws-amplify' // in your component Auth.signIn('myusername', 'mYC0MP13xP@55w0r8')
کلاس Auth بیش از 30 متد از جمله signUp،confirmSignUp ،signIn ،confirmSignIn و changePassword است. میتوان کارهایی مانند تغییر نوع MFA به TOTP و بهروزرسانی خصوصیتهای کاربر را نیز با استفاده از این کلاس انجام داد.
زمانی که کاربر با استفاده از Auth.signIn وارد شد، دادههای «نشست» (Session) حفظ میشوند و هر زمان با استفاده از متد Auth.currentauthenticateduser قابل دسترسی هستند.
1import { Auth } from 'aws-amplify'
2
3class App extends React.Component {
4 state = {
5 username: '',
6 password: '',
7 phone_number: '',
8 email: '',
9 authCode: '',
10 user: {}
11 }
12 async signUp() {
13 const { username, password, email, phone_number } = this.state
14 await Auth.signUp({
15 username,
16 password,
17 attributes: { email, phone_number }
18 })
19 console.log('sign up successful!')
20 }
21 async confirmSignUp() {
22 const { username, authCode } = this.state
23 await Auth.configSignignUp(username, authCode)
24 console.log('confirm sign up successful!')
25 }
26 async signIn() {
27 const { username, password } = this.state
28 const user = await Auth.signIn(username, password)
29 this.setState({ user })
30 console.log('sign in successful!')
31 }
32 async confirmSignIn() {
33 const { user, authCode } = this.state
34 await Auth.configSignignIn(user, authCode)
35 console.log('user now successfully signed in to the app!!')
36 }
37 render() {
38 // render method
39 }
40}
زمانی که کاربران جدید، وارد میشوند، میتوانید پیکربندی را در AWS Mobile Hub ببینید، یا به آدرس https://console.aws.amazon.com/cognito بروید و کاربران و پیکربندی Amazon cognito اپلیکیشن را ببینید.
برای دیدن پیکربندی پروژه جاری باید همواره عبارت زیر را وارد کنید:
awsmobile console
سپس روی Resources در گوشه راست کلیک کنید و در ادامه روی منبعی که میخواهید ببینید، کلیک نمایید.


Analytics
رویدادهای Analytics را میتوان با استفاده از کلاس Analytics ردگیری کرد:
Analytics.record('sale price section viewed')
همچنین میتوانیم رویدادها را با خصوصیتهای دقیقتری فراخوانی کنیم:
Analytics.record('sale price item viewed', { itemName: 'USA Socks', timestamp: 'June 13 2018 4:03pm ET' })
برای دیدن دادههای تحلیلی میتوانید به پروژه AWS Mobile Hub در کنسول بروید و دوباره روی Resources در گوشه راست-بالا کلیک کرده و گزینه Pinpoint را کلیک کرده و سپس روی سرویس کلیک کنید:
awsmobile console // Click on Resources, then Pinpoint

Storage
Amplify یک کلاس Storage دارد که امکان ادغام با ریاکت نیتیو دارد و موجب میشود که رسانههایی مانند تصاویر و ویدئوها بسیار آسانتر ذخیره شده و مورد دسترسی قرار گیرند. این سرویس با Amazon S3 پیوسته است.
میتوانیم storage را در پروژه AWS Mobile Hub از طریق خط فرمان به صورت زیر فعال کنیم:
awsmobile user-files enable awsmobile push
اکنون میتوانیم از کلاس Storage در اپلیکیشن خود استفاده کنیم:
import { Storage } from 'aws-amplify'
میتوانیم از Storage برای قرار دادن آیتمها در فضای ذخیرهسازی استفاده کنیم:
Storage.put('test.txt', 'Hello') .then (result => console.log(result)) .catch(err => console.log(err));
و آنها را از فضای ذخیرهسازی بخوانیم:
Storage.get('test.txt') .then(result => console.log(result)) .catch(err => console.log(err));
همچنین میتوانیم با فرض نصب و پیکربندی react-native-fetch-blob، رسانهها را به سادگی در فضای ذخیرهسازی قرار دهیم:
import RNFetchBlob from 'react-native-fetch-blob'; readFile(filePath) { return RNFetchBlob.fs.readFile(filePath, 'base64').then(data => new Buffer(data, 'base64')); } readFile(imagePath).then(buffer => { Storage.put('MYKEY', buffer, { contentType: 'image/jpeg' }) }).catch(e => { console.log(e); });
برای دیدن S3 bucket میتوانیم دستور awsmobile console را از خط فرمان اجرا کرده و روی Resources کلیک کنیم و سپس زیر Amazon S3 Buckets روی باکت userfiles کلیک کنیم.
تابعهای لامبدا
زمانی که از کلمه «بدون سرور» استفاده میکنیم، معمولاً تابع لامبدا به ذهن میآید. میتوانیم یکی از اینها را به صورت دستی تنظیم کنیم و به منابع موجود AWS Amplify وصل کنیم. همچنین میتوانیم از AWS Mobile CLI برای راهاندازی این مورد برای خودمان استفاده کنیم. در ادامه از CLI برای ایجاد تابع لامبدا بهره میگیریم.
برای افزودن یک تابع لامبدا و همچنین پیکربندی آن با برخی تنظیمات ساده باید دستور زیر را اجرا کنیم:
awsmobile cloud-api enable
همچنین در صورتی که بخواهید پیکربندی را پیرامون تابع لامبدا تعیین کنید، میتوانید از فلگ –prompt استفاده کنید، اما در این مورد صرفاً از مقادیر پیشفرض استفاده میکنیم. دستور زیر به صورت خودکار یک API در API Gateway ایجاد میکند و همچنین یک تابع لامبدا ساخته و آنها را به هم مربوط میسازد:
awsmobile cloud-api enable
اکنون میتوانیم در مسیر awsmobilejs/backend/cloud-api به بررسی پروژه خود بپردازیم و پیکربندیهای جدید را ببینیم. در اینجا میبینیم که یک پوشه جدید دیگر به نام sampleLambda وجود دارد که تابع لامبدای سادهای را برای ما توزیع کرده است.
تابع لامبدایی که برای ما ایجاد شده است، با استفاده از پکیج AWS Serverless Express اقدام به راهاندازی یک سرور اکسپرس با برخی نقاط انتهایی از پیش پیکربندیشده میکند. این نقاط انتهایی میتوانند در کد لوکال بهروزرسانی شوند و چنان که در ادامه خواهیم دید، با استفاده از دستور awsmobile push به سرور ارسال گردند. همچنین میتوانیم نقاط انتهایی را با پیکربندی کد لوکال و همچنین پیکربندی منطق کلود در پروژه AWS Mobile Hub در کنسول اضافه کنیم.
در ادامه متد app.get را روی مسیر /items در awsmobilejs/backend/cloud-api/sampleLambda بهروزرسانی میکنیم:
/// rest of file omitted app.get('/items', function(req, res) { res.json({ body: "HELLO WORLD" }); });
سپس باید این API جدید و پیکربندی را به پروژه AWS Mobile Hub ارسال کنیم:
awsmobile push
اکنون کنسول AWS Mobile Hub را باز میکنیم و نام API را به دست میآوریم:
awsmobile console
روی منطق Cloud کلیک کنید و نام API را کپی نمایید. در این مورد نام مربوطه به صورت sampleCloudApi است.
اکنون میتوانید تابع لامبدا را تست کنید. در فایل App.js یک متد چرخه عمری جدید به نام componentDidMount بسازید:
1async componentDidMount() {
2 const data = await API.get('sampleCloudApi', '/items')
3 console.log('data: ', data)
4}
API مدیریت شده و لایه دادهها
AWS Amplify یک کلاینت GraphQL ارائه میکند که با هر API مربوط به GraphQL کار میکند. در این مورد از AWS AppSync استفاده میکنیم که یک سرویس کاملاً مدیریتشده GraphQL است.
با استفاده از AWS AppSync میتوانید یک API برای GraphQL داشته باشید که با هر منبع داده مورد نیاز تعامل پیدا میکند. منابع داده درونی از قبیل Amazon DynamoDB، AWS Lambda Function یا Amazon Elasticsearch وجود دارند و با یک تابع لامبدا میتوانید به هر سرویس یا پایگاه داده که دوست دارید به صورت یکپارچه از طریق یک لایه API منفرد ارتباط بگیرید. این لایه منفرد در GraphQL به شکل AppSync API است.
چندین کلاینت GraphQL وجود دارند که با AWS AppSync کار میکنند. AWS Amplify یک دسته API دارد که به طور یکپارچه با هر GraphQL API شامل AWS AppSync کار میکنند.
AWS AppSync را میتوان از AWS Mobile CLI فعال کرد، اما با انجام این کار یک اسکیما و دیتاسورس خودکار تولید میشود. به جای آن میتوانیم به کنسول سر بزنیم تا یک API و پیکربندی سفارشی را به صورت دستی از کنسول بسازیم.
در این مثال یک اپلیکیشن ساده ToDo را بررسی میکنیم. برای شروع به نشانی https://console.aws.amazon.com/appsync بروید و روی CREATE API کلیک کنید. در اینجا یک نام به API بدهید و گزینه Custom Schema را انتخاب کرده و روی Create کلیک کنید.
اکنون API ایجاد شده است و برخی اطلاعات شامل API URL و API Key ارائه میشود. روی Schema در منوی چپ کلیک کرده و یک اسکیمای پایه با نوع و یک کوئری ایجاد کنید:
1type Todo {
2 id: ID!
3 name: String!
4 completed: Boolean!
5}
6type Query {
7 fetchTodos(id: ID!): Todo
8}
روی Save کلیک کنید و سپس دکمه Create Resources را بزنید.
مقادیر پیشفرض را انتخاب کرده و روی Create در انتهای صفحه کلیک کنید.
Create Resources به صورت خودکار یک پایگاه داده DynamoDB، اسکیمای اضافی GraphQL برای چند عملیات شامل کوئریها، جهشها و اشتراکها و resolver-ها ارائه میکند که عملیات GraphQL را به منبع داده وصل میکند.
سپس روی Queries در منوی چپ کلیک کنید و mutation و query را تست کنید تا مطمئن شوید که همه چیز به درستی کار میکند:
1mutation add {
2 createTodo(input: {
3 name: "Get groceries"
4 completed: false
5 }) { id }
6}
7query list {
8 listTodos {
9 items {
10 id
11 name
12 completed
13 }
14 }
15}
اکنون میتوانیم API را از اپلیکیشن سمت کلاینت تست کنیم. ابتدا باید پیکربندی سمت کلاینت را بهروزرسانی کنیم تا AppSync API را شناسایی کند.
یک فایل جدید به نام appsync-config.js در ریشه پروژه میسازیم.
1export default {
2 'aws_appsync_graphqlEndpoint': 'https://*******.appsync-api.us-east-1.amazonaws.com/graphql',
3 'aws_appsync_region': 'us-east-1',
4 'aws_appsync_authenticationType': 'API_KEY',
5 'aws_appsync_apiKey': 'da2-*************',
6}
سپس کلاینت Amplify را پیکربندی میکنیم تا پیکربندی AppSync را شناسایی کند:
1import { AppRegistry } from 'react-native';
2import App from './App';
3import Amplify from 'aws-amplify'
4import config from './aws-exports'
5import AppSyncConfig from './appsync-config' // NEW
6Amplify.configure({ ...config, ...AppSyncConfig }) // UPDATED
7AppRegistry.registerComponent('ServerlessProject', () => App);
اکنون میتوانیم عملیات مختلف را با استفاده از دستهبندی API و تابع کمکی graphqlOperation از سوی AWS Amplify به سادگی ایجاد و روی API اجرا کنیم. در فایل App.js کوئری زیر را اضافه میکنیم:
1import React, { Component } from 'react';
2import {
3 StyleSheet,
4 Text,
5 View
6} from 'react-native';
7
8import { withAuthenticator } from 'aws-amplify-react-native'
9import { API, graphqlOperation } from 'aws-amplify'
10
11const query = `
12 query list {
13 listTodos {
14 items {
15 id
16 name
17 completed
18 }
19 }
20 }
21`
22
23class App extends Component {
24 state = { todos: [] }
25 async componentDidMount() {
26 const todos = await API.graphql(graphqlOperation(query))
27 this.setState({ todos: todos.data.listTodos.items })
28 }
29 render() {
30 return (
31 <View style={styles.container}>
32 <Text style={styles.welcome}>
33 Todos
34 </Text>
35 {
36 this.state.todos.map((todo, index) => (
37 <Text key={index}>{todo.name}</Text>
38 ))
39 }
40 </View>
41 );
42 }
43}
44
45export default withAuthenticator(App)
46
47const styles = StyleSheet.create({
48 container: {
49 flex: 1,
50 justifyContent: 'center',
51 alignItems: 'center',
52 backgroundColor: '#F5FCFF',
53 },
54 welcome: {
55 fontSize: 20,
56 textAlign: 'center',
57 margin: 10,
58 }
59});
پوش نوتیفیکیشن
در AWS Amplify پوش نوتیفیکیشنها برای هر دو سیستم اندروید و iOS ارائه شدهاند. برای فعالسازی سرویس Push Notification باید با اجرای دستور awsmobile console به کنسول Pinpoint بروید و روی Resources و سپس زیر Amazon Pinpoint روی لینک سرویس خودتان کلیک کنید.
پیکربندی اولیه برای پوش نوتیفیکیشن به زمان زیادی نسبت به موارد دیگر نیاز دارد، زیرا نه تنها باید برخی پیکربندیها را برای ریاکت نیتیو بهروزرسانی کنیم، بلکه باید سرویسهای واقعی را نیز از طریق اپل و گوگل راهاندازی کنیم.
توضیح مراحل این کار از حوصله این مقاله خارج است. برای کسب اطلاعات بیشتر در مورد iOS به این صفحه (+) و در مورد اندروید به این ریپوی گیتهاب (+) مراجعه کنید.
زمانی که پروژه پیکربندی شد، میتوانید پوش نوتیفیکیشنها را از اپلیکیشن خودتان مدیریت کنید:
1import { PushNotification } from 'aws-amplify-react-native';
2
3// get the registration token
4PushNotification.onRegister((token) => {
5 console.log('in app registration', token);
6});
7
8PushNotification.onNotification((notification) => {
9 // Note that the notification object structure is different from Android and IOS
10 console.log('in app notification', notification);
11
12 // required on iOS only (see fetchCompletionHandler docs: https://facebook.github.io/react-native/docs/pushnotificationios.html)
13 notification.finish(PushNotificationIOS.FetchResult.NoData);
14});
بدین ترتیب به پایان این مقاله میرسیم.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای جاوا اسکریپت
- مجموعه آموزشهای برنامهنویسی
- آموزش مقدماتی فریمورک React Native
- چه زمانی از React Native برای توسعه اپلیکیشن موبایل استفاده کنیم؟
- ساخت ویجت با React Native برای iOS و اندروید — از صفر تا صد
==