supergravity

리뷰 - How To Cache Images in an Expo Managed React Native App - expo android에서 Cache image 다루는법 본문

개발중 기억해야 할만한 것들/엑스포, 리액트 네이티브

리뷰 - How To Cache Images in an Expo Managed React Native App - expo android에서 Cache image 다루는법

supergravity 2021. 1. 21. 06:41

hackernoon.com/how-to-cache-images-in-an-expo-managed-react-native-app-5q9m3z6s

 

How To Cache Images in an Expo Managed React Native App | Hacker Noon

Caching images in React Native can be easy, even if you are using Expo's managed workflow. The problem many devs run into is that React Native only supports caching images on IOS out of the box.

hackernoon.com

 

Introduction

 

캐시 이미지를 다루는 패지키를 위의 사이트를 운영하는 분이 개발하여 오픈 소스로 배포를 하였다. 위의 사이트를 읽어 보면 expo를 이용하여 안드로이드 앱을 개발할때 캐쉬 이미지를 다루는데 어려움이 있어 개발하였다고 한다. 

 

사용법

 

npm install react-natice-expo-cached-image 로 설치를 해준다

 

import CachedImage from 'react-native-expo-cached-image'; 임포트 해준다.

 

그런 후 아래와 같이 사용할 수 있다.

<CachedImage isBackground

source={{ uri: 'https://qvault.io/wp-content/uploads/2019/05/QVault-app.png' }} />

 

제공하는 probs는 expo api image와 같다고 한다.

 

CachedImage는 image를 다운로드하고 유저의 로컬 저장소에 sha-256 해쉬를 이용하여 uri를 저장한다.

그러고 나서 render가 되거나 app을 사용할 때 이미지를 로드한다. 만약 expo-file-system 상에 cache가 존재

한다면 읽어온다. 

 

코드 리뷰

 

import React, { Component } from 'react';

import { View, Image, ImageBackground } from 'react-native';

import * as FileSystem from 'expo-file-system';

import * as Crypto from 'expo-crypto';

 

캐시로 저장하기 위해 엑스포 파일 시스템을 임포트시킨다. 또한 캐쉬로 저장할 때 SHA-256 hash를 이용하기

위해 expo-crypto를 임포트 시킨다.

 

async getImageFilesystemKey(remoteURI)

{ const hashed = await Crypto.digestStringAsync( Crypto.CryptoDigestAlgorithm.SHA256, remoteURI );

return `${FileSystem.cacheDirectory}${hashed}`; }

 

SHA-256을 이용하여 파일 시스템의 hash를 생성하는 함수를 만든다.

 

async loadImage(filesystemURI, remoteURI) {

try {

// Use the cached image if it exists

const metadata = await FileSystem.getInfoAsync(filesystemURI);

 

if (metadata.exists) { this.setState({ imgURI: filesystemURI });

return; }

 

const imageObject = await FileSystem.downloadAsync( remoteURI, filesystemURI );

this.setState({ imgURI: imageObject.uri }); }

 

catch (err) { console.log('Image loading error:', err);

this.setState({ imgURI: remoteURI }); } }

 

파일을 로드하기 위한 함수이다. 먼저 엑스포 파일 시스템의 getinfoAsync()를 이용하여 파일시스템의 매타 데이터를

확인한다. 만약에 매타 데이터가 존재하면( 캐시 ) uri를 state에 저장한다. 매타 데이터가 존재하지 않는 경우 외부에서

파일을 받아온다. 함수의 argument 중 filesystemUrI는 위에서 정의한 getImageFilesystemKey() 함수의 hashed 변수에 

해당된다.

 

async componentDidMount()

{

const filesystemURI = await this.getImageFilesystemKey(this.props.source.uri);

await this.loadImage(filesystemURI, this.props.source.uri);

}

 

async componentDidUpdate() {

const filesystemURI = await this.getImageFilesystemKey(this.props.source.uri);

if (this.props.source.uri === this.state.imgURI || filesystemURI === this.state.imgURI)

{ return null; }

await this.loadImage(filesystemURI, this.props.source.uri); }

 

앱이 실행될 때와 render 될 때 이미지를 로드시키기 위해서 코드를 작성한다.

Comments