react-native-async-cache
Getting started
$ npm install react-native-async-cache --save
Mostly automatic installation
$ react-native link react-native-async-cache
API
Promise select(options)
The only method need to know, return a promise resolves an object containing url.
If the file downloaded, resolve the url as local path, otherwise resolve the request given.
Option | Optional | Type | Description |
---|
url | NO | String | the network resource url |
headers | YES | Map<String,String> | http request headers |
subDir | YES | String | name of directory where the file save to |
extension | YES | String | file extension (e.g ''.jpg" or "jpg") |
id | YES | String | file unique identification, advance usage |
data | YES | String | binary custom data |
dataType | YES | String | type of custom data, "text", "base64" or "base64Url" |
sign | YES | String | file identification obfuscation |
Param | Type | Description |
---|
success | Boolean | whether the file is cached |
url | String | the url from given request or the file path prefix with file:// that been cached |
statusCode | Integer | it's nonzero and nonnull if request failed |
message | String | the failure description |
import React from "react";
import RNAsyncCache from 'react-native-async-cache';
export default class extends React.Component
{
componentDidMount(){
RNAsyncCache.select({
url: "https://static.zerochan.net/Kouyafu.full.2927619.jpg"
}).then((res) => {
const {url, statusCode, message} = res;
this.setState(
{img: url, statusCode, message}
);
});
}
// Component initial state
state = {
img:"",
statusCode: 0,
message:""
};
// Component render
render()
{
const {img, statusCode, message} = this.state;
if(statusCode || message){
// request failed
return <Text>{statusCode} {message}</Text>;
}
return img ? <Text>Loading...</Text>: <Image source={{uri: img}}/>;
}
}
Promise trash(options)
Empty the cache directory.
Option | Optional | Type | Description |
---|
subDir | YES | String | name of directory be emptied |
Promise accessible(options)
Try to check http status code of the url is 200 OK.
Option | Optional | Type | Description |
---|
url | NO | String | network resource url |
statusCodeLeft | YES | Integer | min valid status code |
statusCodeRight | YES | Integer | max valid status code |
accessibleMethod | YES | String | http method, default "HEAD" |
headers | YES | Map<String,String> | request headers |
Param | Type | Description |
---|
accessible | Boolean | whether the file is cached |
statusCode | String | http status code or -1 if runtime exception occurred |
message | String | description of failure |
size | Number | total bytes of resource, may be -1 if server not support Content-Length |
url | String | request url |
import React from "react";
import RNAsyncCache from 'react-native-async-cache';
import {Image, Text} from "react-native";
export default class extends React.Component {
state = {
error:""
};
render(){
const {error} = this.state;
const img = "https://i.pximg.net/img-master/img/2020/04/04/00/10/00/80545109_p0_master1200.jpg";
return error ? (<Text>{error}</Text>) : <Image source={{uri:img}} onError={()=>{
RNAsyncCache.accessible({
url:img
}).then(({statusCode, message})=>{
this.setState({
error: statusCode + "\n" + message
});
});
}} />
}
}
Promise check(options)
Confirm whether the cache file exists.
Option | Optional | Type |
---|
url | NO | String |
subDir | YES | String |
extension | YES | String |
Param | Type | Description |
---|
path | String | not empty if the file exists |
exists | Boolean | whether the file exists |
url | String | request url |
Promise remove(options)
Delete the cache file specified.
Option | Optional | Type |
---|
url | NO | String |
subDir | YES | String |
extension | YES | String |
Param | Type | Description |
---|
success | String | whether the file was deleted successfully |
path | Boolean | path of the file be deleted, it's not empty if successfully removed |
url | String | request url |
Promise download(options, onProgress)
Cache a file manually.
Option | Optional | Type |
---|
url | NO | String |
subDir | YES | String |
extension | YES | String |
headers | YES | Map<String,String> | request headers |
Param | Type | Description |
---|
progress | Number | less than 1, always 0 if total is -1 |
total | Boolean | -1 if server not support Content-Length |
current | String | bytes of written |
url | String | request url |
Param | Type | Description |
---|
size | Number | the size of the file been downloaded |
path | Boolean | path of the file |
url | String | request url |
void post(options)
delegate a background download task or create a cache with url and exists data.
Option | Optional | Type |
---|
url | NO | String |
headers | YES | Map<String,String> |
subDir | YES | String |
extension | YES | String |
headers | YES | Map<String,String> | request headers |
data | YES | String | custom data |
dataType | YES | String | "text", bianary use "base64" or "base64Url" |
Cache Component
Option | Optional | Type | Description |
---|
Component | NO | Component | render component with url |
PendingComponent | YES | Component | render component during select() execution |
mapToRequestOptions | YES | Function | map component props to request options |
mapToComponentProperties | YES | Function | map select() result to component props |
sourceProperty | YES | String | name of the component property, default 'source' |
invokeOnComponentErrorProperty | YES | String | name of the callback function invoked on load error |
invokeOnComponentLoadProperty | YES | String | name of the callback function invoked on load success |
sourceMapper | YES | Function | map url to local path |
onSourceMapped | YES | Function | invoked on url accepted |
onRequestError | YES | Function | invoked on url has been checked not accessible |
cacheValidator | YES | Function | confirm the cache is valid, usually not need it |
Usage
import {CacheComponent} from 'react-native-async-cache';
import {Image,View} from 'react-native';
const CacheImage = CacheComponent(
{
Component: Image,
PendingComponent: Image,
invokeOnComponentErrorProperty: 'onError',
invokeOnComponentLoadProperty: 'onLoad',
mapToRequestOptions: () => {
return {
subDir: 'images'
};
},
mapToComponentProperties: (props) => {
return {
source: typeof props.source === 'number' ? props.source : {uri: props.source},
errorMessage: (props.statusCode || props.message) ? props.statusCode + ' ' + (props.message || '') : null
};
}
}
);
// render component
export default class extends React.Component
{
render(){
return (
<View style={{flex: 1, alignItems: "center"}}>
<CacheImage source={"https://static.zerochan.net/Kouyafu.full.2792022.jpg"}
style={{
width : Dimensions.get("window").width - 30,
height : Dimensions.get("window").height
}}
/>
</View>
);
}
}
CacheStoreComponent
create a CacheComponent
with a memory store to reduce select()
calls.
import {CacheStoreComponent} from 'react-native-async-cache';
import {Text,View,Image} from "react-native";
const CacheStoreImage = CacheStoreComponent(
{
Component: Image,
PendingComponent: ()=>{
return <View><Text>Loading...</Text></View>;
},
invokeOnComponentErrorProperty: 'onError',
invokeOnComponentLoadProperty: 'onLoad',
mapToRequestOptions: () => {
return {
subDir: 'images'
};
},
mapToComponentProperties: (props) => {
return {
source: typeof props.source === 'number' ? props.source : {uri: props.source},
errorMessage: (props.statusCode || props.message) ? props.statusCode + ' ' + (props.message || '') : null
};
}
}
);
// render component
export default ()=>{
return (
<View style={{flex: 1, alignItems: "center"}}>
<CacheStoreImage source={"https://static.zerochan.net/Fuji.Choko.full.2920380.jpg"} style={{
width : Dimensions.get("window").width - 30,
height : Dimensions.get("window").height
}}/>
</View>
);
}
- Custom StoreProvider Example
import {CacheStoreComponent, StoreProvider} from 'react-native-async-cache';
import AsyncStorage from 'react-native-async-storage';
// extend default StoreProvider
class PersistenceStoreProvider extends StoreProvider {
access_time = 0;
constructor(props) {
super(props);
AsyncStorage.getItem('caches').then(str=>{
this.caches=JSON.parse(str);
});
}
get(url){
++this.access_time;
if(this.access_time > 100){
this.access_time = 0;
this.serialize();
}
return super.get(url);
}
serialize(){
// call it at the right time
AsyncStorage.setItem('caches',JSON.stringify(caches));
}
clear(){
// optional, call it when local file not found
this.caches = [];
AsyncStorage.setItem('caches',JSON.stringify([]));
}
}
// create CacheStoreComponent
export default CacheStoreComponent({
store: new PersistenceStoreProvider(),
// ...
});
// improt fs from "react-native-fs";
// config
const config = {
store: new PersistenceStoreProvider(),
// ...
cacheValidator:(cache,callback)=>{
if(cache && !cache.local){
callback(cache);
}
else {
fs.exists(cache).then(exists=>{
callback(exists ? cache : null);
if(!exists)
{
config.store.clear();
}
});
}
}
}
export default CacheStoreComponent(config);
- Advanced usage, StoreProvider interface
interface StoreProvider {
get(url: string): string;
set(url: string, local: string): void;
error(url: string, code: number, message: string): void
}
Callback Method | Description |
---|
get | return nullable cache file path with url |
set | associate local path to url |
error | invoked if resource is inaccessible |