Bygg en Instagram-flödesapp med bara javascript (med Expo & React Native)

Jag har velat gå in på mobilutveckling ett tag nu, men varje gång jag börjar bygga något på sidan, hanterar jag samma irriterande problem:

  • Jag slösar bort tid på att göra tråkiga saker. Att göra en hej världsapp kräver massor av pannplattkod och slumpmässiga installationer
  • Ingen av mina webkunskapsöverföringar. Android skiljer sig helt från iOS och båda skiljer sig helt från webben.

Efter en del surfning på internet verkade det som om Facebook löste problemet med React Native (ett bibliotek för att skapa inbyggda appar baserade på React.js), men efter att ha provat det så hittade jag att installationen var lika tråkig som tidigare. Det huvudsakliga problemet var fortfarande där: Jag behövde skriva en massa pannplatta Java / C # -kod.

Jag var redo att medge byggandet på mobilen, men jag hittade något som heter Expo. Expo har några bibliotek och verktyg som bygger på framgången för React Native på några meningsfulla sätt:

  • Du kan komma igång direkt utan att ladda ner något
  • Fristående appar kan göras 100% i javascript
  • Det levereras med apis som förenklar vanliga uppgifter i appar

Min senaste skapelse är en Instagram-flödesapp, som vi kommer att göra. Du kan följa med på exposnack (ett webbgränssnitt för att leka med expo). Du kan också kolla källan på github eller titta på min videohandledning. Låt oss börja.

Färdig app

Från en hög nivå kan vi se att appen består av en lista med inlägg, metadata om inlägget och slutligen inläggets kommentarer. Vi måste använda Instagram-api för att få den här informationen och sedan visa den i ett listformat.

Låt oss skapa en Instagram-klientapp så att vi kan göra api-förfrågningar.

När du har fyllt i informationen för att skapa en klientapp ska du avmarkera rutan för att inaktivera implicita OAuth. För att underlätta vår demo-app får vi vår åtkomsttoken utan någon sidkod på servern.

Klicka nu på hantera klienter och hantera på din nyskapade klient. Klicka på säkerhet och ange valfri url i fältet "giltig omdirigering" (jag gjorde http://www.google.com).

Nästan klar. För att få vår åtkomsttoken ringer vi ett api-samtal med Instagrams autentiserings-api. Api kommer att omdirigera oss till den angivna url, men med vår åtkomsttoken som en url-parameter. Här är vad du behöver klistra in i din webbläsare:

https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token&scope=public_content

Där CLIENT-ID och REDIRECT-URI är respektive värden. När du har godkänt appens åtkomst till ditt Instagram-konto bör du omdirigeras. Här tar jag min åtkomsttoken (skapa ett unikt för din app).

Trevlig. Vi kan äntligen börja kodningen.

Här är skelettet för alla Expo-projekt:

importera React, {Component} från 'react'; importera {Text, Visa, StyleSheet} från 'react-native';
exportera standardklass App utvidgar komponent {render () {return ( Hej )}}
const styles = StyleSheet.create ({})

HTML-taggarna kallas JSX, en funktion i React. Vi kan använda den för att definiera vår layout och bädda in JavaScript-logik inuti.

Låter importera några komponenter till från React Native och Expo.

  • FlatList-komponenten kommer att vara det viktigaste byggstenet för vårt användargränssnitt, eftersom det återger varje objekt i en lista genom att kalla sin renderItem-funktion.
  • AppLoading används för att visa användaren en lastningsikon medan vi återger delar av vår app (annars skulle de se en tom skärm, som skulle blinka och visa vårt innehåll när den laddats)
  • StyleSheet fungerar som en css-fil, där vi kan tillämpa stilar på appvyer

Vi kommer också att behöva vår åtkomsttoken och någonstans för att lagra data om varje inlägg. I React Native görs detta med något som kallas tillstånd. All information som UI kommer att behöva komma åt bör lagras här. Det är praktiskt eftersom vår app återges närhelst staten ändras.

importera React, {Component} från 'react' import {Text, View, StyleSheet, Image, Dimensions, FlatList,} from 'react-native' import {Constants, AppLoading} från 'expo'
access_token = '6626870867.cbba754.83fa37c865314df8be5c52347e3e4987'
status = {laddat: falsk, data: null, kommentarer: [],}
exportera standardklass App utvidgar komponent {render () {return ( this.createPost (artikel, index)} keyExtractor = {(item) => item.id} /> )}}
const styles = StyleSheet.create ({container: {flex: 1, alignItems: 'center', paddingTop: Constants.statusBarHeight, backgroundColor: '# ecf0f1',}})

Datastödet från FlatList är en matris där varje objekt skickas som en parameter till renderItem-funktionen. Vi kommer att lagra våra Instagram-inlägg i den här matrisen.

Så låt oss använda vår access_token för att få våra inläggsdata. Vi använder hämta api för att göra en GET-begäran till Instagram: s api-slutpunkt. Sedan lagrar vi värdena i våra apparstillstånd.

async fetchFeed () {let response = vänta på hämta ('https://api.instagram.com/v1/users/self' + '/ media / recent /? access_token =' + this.access_token) låt inlägg = vänta på svar. json () låt kommentarer = vänta på detta.makeCommentsList (posts.data)
this.setState ({data: posts.data, kommentarer: kommentarer, laddat: true})}

Vi har listan över våra senaste inlägg, men för varje inlägg måste vi få en lista med kommentarer och tillhörande metadata. Det betyder att vi gör en serie nätverksförfrågningar som kan komma tillbaka i fel ordning. Planen är att hantera detta genom att returnera en rad löften som kommer att lösa när inläggets kommentarer hämtas. Vi sparar också lite laddningstid genom att inte göra en förfrågan när inlägget inte har några kommentarer, och helt enkelt visa en vy som säger 'Inga kommentarer!'

async makeCommentsList (inlägg) {let postsArray = posts.map (async (post) => {let postId = post.id
if (post.comments.count === 0) {return ( Inga kommentarer! )} annat {
        låt svar = vänta på hämta ('https://api.instagram.com/v1/media/' + postId + '/ comments? access_token =' + this.access_token)
låt kommentarer = vänta på svar.json () låt commentsArray = comments.data låt commentsList = commentsArray.map (commentInfo => {return ( {CommentInfo.from.username} {CommentInfo.text} )})
        return commentsList}
    })
    postsArray = vänta på Promise.all (postsArray) return postsArray}

Vi har lagt till lite styling för att kommentarerna ska se bra ut:

const styles = StyleSheet.create ({container: {flex: 1, alignItems: 'center', paddingTop: Constants.statusBarHeight, backgroundColor: '# ecf0f1',}, kommentar: {flexDirection: 'row', padding: 10, paddingLeft : 15, borderBottomWidth: 1, borderColor: '# d8d8d8',}, commentText: {paddingRight: 15, fontWeight: 'bold',}})

Nu när vi har alla våra kommentarer och publicerar data måste vi skapa tidslinjen och fylla den med de data vi fick. CreatePost-funktionen använder dessa värden för att visa inlägg, metadata och kommentarer.

createPost (postInfo, index) {let imageUri = postInfo.images.standard_resolution.url let username = postInfo.user.username let numLikes = postInfo.likes.count
lämna tillbaka ( 
{Användarnamn} {numLikes + (numLikes! == 1? 'likes': 'like')}
        
{This.state.comments [index]} )}

imageUri, användarnamn och numLikes hämtas alla från den returnerade JSON från vår hämtningsbegäran till Instagram-api. Exempel på returneringsvärden finns i Instagram-utvecklardokumenten.

Återigen lägger vi till lite styling i vårt StyleSheet för att våra inlägg ska bli snygga.

  bild: {bredd: Mått.get ('fönster'). bredd, höjd: Mått.get ('fönster'). bredd,}, info: {flexDirection: 'rad', justifyInnehåll: 'mellanslag mellan', stoppning: 10, paddingLeft: 15, paddingRight: 15, borderBottomWidth: 1, borderColor: '# d8d8d8',}, infoText: {fontSize: 16, fontWeight: 'bold',}

För att lägga till några finpussningar kan vi hämta vår Instagram-information när appen startar och visa en lastningsikon för optimal användarupplevelse.

componentDidMount () {this.fetchFeed ()}
render () {if (! this.state.loaded) {return ( )}
lämna tillbaka ( this.createPost (artikel, index)} keyExtractor = {(item) => item.id} /> )}

Och precis så är du klar! En mobil Instagram-feedvisare i ~ 150 rader. Du kan kolla in det fullständiga, fungerande mellanmålsexemplet här.

Eftersom denna tutorial var tänkt att göra utan några installationer, har vi inte slutfört processen för att skapa en fristående Android- eller iOS-app. Lyckligtvis är du bara några steg bort.

  1. Se till att du har ett Apple Developer-konto och Google Play-konto.
  2. Ladda ner Expos verktyg XDE och klicka på 'exportera till XDE' i Snack.
  3. Följ bygginstruktionerna på Expos fristående app-sida (lägger huvudsakligen till metadata till din app)
  4. Grattis! Du har byggt en inbyggd app för iOS och Android