Giter Site home page Giter Site logo

wcandillon / react-native-img-cache Goto Github PK

View Code? Open in Web Editor NEW
729.0 14.0 143.0 65 KB

Image Cache for React Native

Home Page: https://hackernoon.com/image-caching-in-react-native-96d8df33ca84

License: Apache License 2.0

TypeScript 100.00%
react-native image cache

react-native-img-cache's Introduction

React Native Image Cache

CircleCI npm version

CachedImage component and Cache image manager for React Native.

Deprecated

I am no longer maintaining this library but react-native-expo-image-cache which depends on ExpoKit.

Checkout 5 things to know about Images in React Native

Why do I need this?

Starting version 0.43, the React Native Image component has now a cache property: cache: force-cache (iOS only). This is a major improvement but only for iOS and at this time, I wasn't able to use it in a way that provides a user experience as smooth as this module.

Installation

rn-fetch-blob

This package has a dependency with rn-fetch-blob. If your project doesn't have a dependency with this package already, please refer to their installation instructions.

npm install react-native-img-cache --save

Usage

CachedImage

The CachedImage component assumes that the image URI will never change. The image is stored and served from the application cache. This component accepts the same properties than Image except for a few difference:

  • source doesn't accept an array of image URIs like Image does. Please file an issue if that's something you would like to see supported.
  • The uri property in source is mandatory.
  • The body property in source is not supported. Please file an issue if that's something you would like to see supported.
import {CachedImage} from "react-native-img-cache";

<CachedImage source={{ uri: "https://i.ytimg.com/vi/yaqe1qesQ8c/maxresdefault.jpg" }} />

The mutable property implies assumes that the image URI can change over time. The lifetime of this cache is the one of the running application and it can be manually busted using ImageCache.

import {CachedImage} from "react-native-img-cache";

<CachedImage source={{ uri: "https://i.ytimg.com/vi/yaqe1qesQ8c/maxresdefault.jpg" }} mutable />

Custom Image Component

By default, the CachedImage component is using the standard RN Image component. It is possible however to use a different component via CustomCachedImage. In the example below, we use the Image component from react-native-image-progress.

import {CustomCachedImage} from "react-native-img-cache";

import Image from 'react-native-image-progress';
import ProgressBar from 'react-native-progress/Bar';

<CustomCachedImage
  component={Image}
  source={{ uri: 'http://loremflickr.com/640/480/dog' }} 
  indicator={ProgressBar} 
  style={{
    width: 320, 
    height: 240, 
  }}/>

ImageCache

clear()

Remove cache entries and all physical files.

ImageCache.get().clear();

bust(uri)

ImageCache can be used to bust an image from the local cache. This removes the cache entry but it does not remove any physical files.

ImageCache.get().bust("https://i.ytimg.com/vi/yaqe1qesQ8c/maxresdefault.jpg");

cancel(uri)

It can also be used to cancel the download of an image. This can be very useful when scrolling through images.

ImageCache.get().cancel("https://i.ytimg.com/vi/yaqe1qesQ8c/maxresdefault.jpg");

on(uri, observer, immutable)

The ImageCache class can register observers to the cache.

const immutable = true;
const observer = (path: string) => {
    console.log(`path of the image in the cache: ${path}`);
};
ImageCache.get().on(uri, observer, immutable);

We use the observer pattern instead of a promise because a mutable image might have different version with different paths in the cache.

dispose(uri, observer)

Observers can be deregistered using dispose:

ImageCache.get().dispose(uri, observer);

Testing with jest

Mocking CachedImage

With jest, testing a snapshot can generate errors. Jest doesn't know how to generate the component CachedImage. For fix this, you have to mock CachedImage with Image component.

jest.mock('react-native-img-cache', () => {
  const mockComponent = require('react-native/jest/mockComponent')
  return {
    CustomCachedImage: mockComponent('Image'),
    CachedImage: mockComponent('Image'),
  }
})

react-native-img-cache's People

Contributors

chmac avatar domben avatar gabriel-diez avatar wcandillon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-img-cache's Issues

Clear image cache at startup

correct me if I am wrong but the ImageCache is limited to the application runtime. However, downloaded files persist in the device filesystem even if you close the app. To prevent deprecated cache files to take disk space uselessly, you should call the "clear()" function in your ImageCache constructor (as there is only one instance of ImageCache per app anyway). I think CacheDir returned by react-native-fetch-blob is specific to each app. Else you would also need to include the appID into your BASE_DIR construcor so that cleaning the cache in one app do not clean it for every running app using react-native-img-cache.
Also, having a counter that autoincrement rather than generating random file names (with calls to your s4 function ) for mutable images would be more simple and prevent any unluky ovewrite (aditionnaly, it could be used to clean oldest cache files only based on their name if necessary).

ReactNative ImageBackground

As of ReactNative 0.46 using, it's recommended to use ImageBackground component whenever Image has children. This is possible using CustomImageCache component as follow:

<CustomCachedImage
    component={ImageBackground}
    source={{ uri: 'http://loremflickr.com/640/480/dog' }} 
/>

Although if there is a directly available component name CachedImageBackground to import then it would be great.

progress indicator is not work

When i use CustomCachedImage, the progress indicator is not work; if i use Image instead of CustomCachedImage, indicator progress is ok.
image

Image doesn't show when the imageName contain spaces [IOS ONLY]

Sample code,

      <CachedImage
        source={{uri: `https://${address}/House Clean.jpg`}} // doesn't work, when "Drinks.jpg" it works
       style={{width:190,height:130}}
       resizeMode={"cover"}
      />

When the image name contains spaces, the image won't show on IOS. It's working fine in Android.
This is not a styling issue, I'm certain of it, and also when using default Image component it works fine.
Any Idea why it happens?

will open source ?

Hey, i just came across from medium, your article is useful for me, thanks a lot.
Would this be an open source project, then we can use <CacheImage /> instead of <Image />?

Thank you

This worked out of the box and even allows for my app to work offline. Just wanted to send some positive vibes your way. Thanks again.

React-Native-Fetch-Blob is NOT being maintained

Hi guys,
I have used this library(React-Native-Img-Cache) in my project and it's working well. However, this library has a dependency to React-Native-Fetch-Blob and that is a concern for me. React-Native-Fetch-Blob is NOT being maintained. They have issued RNFB MAINTAINER GONE MISSING notice. The reason this concerns me is because, I am facing a very critical bug, that causes my app crash as soon as the user opens the app (seen in few phones). This is fixed with this PR, but there is no one to merge this into master.
Can you guys step in and help them? Or do you have other suggestions?

Progress indicator on downloading

How can I get the image upload process?
or
Could you add props progress indicator if image download?
as like indicator={`Platform.OS === 'ios' ? Circle : Pie`}

iOS refresh UI must on main thread.

=================================================================
Main Thread Checker: UI API called on a background thread: -[UIApplication setNetworkActivityIndicatorVisible:]
PID: 17639, TID: 8871768, Thread name: (none), Queue name: NSOperationQueue 0x1c4434440 (QOS: UNSPECIFIED), QoS: 0
Backtrace:
4 Traveller 0x0000000104a1a198 -[RNFetchBlobNetwork URLSession:task:didCompleteWithError:] + 236
5 CFNetwork 0x0000000185942694 + 76
6 Foundation 0x0000000185bd6310 + 16
7 Foundation 0x0000000185b169e4 + 72
8 Foundation 0x0000000185b06620 + 848
9 libdispatch.dylib 0x0000000105e7545c _dispatch_client_callout + 16

Android still cannot read file from cache.

Hello!
I tried using CachedImage but it won't show the image. It shows the Image tag, but with a blank view. I checked whether the file exists, and it exists (checked in the avd shell and also with fs.exists).
It works perfectly with iOS. If I use fileCache instead of path it works without problems.

Maybe it is because of the Firebase Storage, that the link has some end to it. "http://firebase..../2F5F4SaNi6oPe0gW6MXvyU4jC0LPq1%2F49s3efwPUGRT8lB9RTRBYyy8Lpm2%2F1489646918723.jpg?alt=media&token=08e6fe22-9a8c-4455-9b8a-ca4b10828a0b"


The problem was the URL, you need a clean filename like 'esgeahr25awrga.jpg'

architecture design enhancement

i have a question. Can I can an notification when the all the images are cached hit in the local storage?

assume i have

images = [
uri1, uri2, uri3, ...
]
should be better when all of these paths are cached successfully and have the final notification. Can I also have the size dimension of each image in return automatically?

How to handle network error and re-fetch from remote uri

Hi, I would like to know how to deal with network error when I am loading images from remote uri. In my case, I have an infinite list to show all images in a listview.
Somehow there may be some network errors:

  1. timeout
  2. no network connection
  3. ssl failed

I know I need to handle them inside the onError() callback, but I want to implement a retry function. Something like retry 10 times, if the failed image is loaded successfully, then stop retrying. However, what annoys me is that I am not sure how to refetch the image from remote uri. What I can think is to set the CachedImage to be null and remount it to make it re-render.

Do you have any clue to implement this or add a new feature for us to set props like: timeout, retryNums?

Custom ImageCache entries

As a user, I'd like to be able to manipulate the image cache with locally captured data.

Currently building an app where the user can submit images to a server, and we display the image back to the users. Instead of waiting for the round trip (upload, get the property from the server, download via cache) and caching by the URL, I'd like to cache the local image path. Any tips?

Question - Comment

Hi what happens if the cache gets full? It will start overriding content in sequence?

Another thing, is there a way to pre fetch images before showing the component?

Use with Local Images

Is there a way to make this work with local uri s that works like phcachingimagemanager from native iOS? I think I have not had luck because your fetch is not done through the image component. Is it possible to use Image and onLoad of the Image to perform the same task that your download method handles now? Thanks for any insight. I struggle with some of the javascript compared to native code.

defaultSource prop not working

for profile page in my app i pass a default empty profile prop as follows
<CachedImage source={imageSrc} style={styles.profileImage} defaultSource={theme.emptyProfile} />
my empty profile image does not show when its loading the real uri image.
is this behaviour right or should i use customImageComponent?

before first load of uri image, nothing gets shown. after that if the image uri changes , the default source is shown correctly. as nothing is shown during the first load my view gets broken and it pops when image gets loaded.
any help would be appreciated.

when loading for first time...see how no default image is not shown
screenshot_2017-06-21-03-04-43
after first load
screenshot_2017-06-21-03-04-46
when i fetch second time default prop is shown correctly
screenshot_2017-06-21-03-05-16

RNFetchBlob does not respect the http status

Hi there,

i cloned your project down and im trying to modify one file so that i can publish a local copy. Sorry im not really good at this yet, but i would like to make some change to your file to handle the http status code due to the issue of RNFetchBlob does not cater for.

I do not believe i have the right setup to compile the code, but would love to share my idea anyway

I made change to the file new code to basically bubble up the event to the image container (custom image) (sorry i hardcode to status 401 for now)

I'll do some research over the weekend on how to do this, but now i just need to get things working.
Would love to help

The latest version 1.3.1 cannot run on RN 0.42

Hi, thanks for your awesome module. I am currently using react-native v0.42.3. After I updated to react-native-img-cache v1.3.1, it encountered error, but v1.3.0 is perfect for react-native < 0.43. Please noted and if you can tag your release version, that would be nice. ^_^

ImageCache does not behave well

this code :

const immutable = true;
const observer = (path: string) => {
    console.log(`path of the image in the cache: ${path}`);
};
ImageCache.get().on(uri, observer, immutable);

many copies of each image..is it a known issue ?

Evaluating RNFetchBlob.DocumentDir error

I have installed react-native-img-cache and react-native-fetch-blob. After starting the app I get an error. Haven't tried it on iOS, this happens on Android 7.1.1 emulator.
blob-error

"react": "16.0.0-alpha.12"
"react-native-fetch-blob": "^0.10.8"
"react-native-img-cache": "1.5.0"

Any ideas how to solve this?

Cannot use with `react-native-fit-image`

The react-native-fit-image is a very handy component, where the image loaded from the source.uri is directly made to fit the size of the parent component.
<CustomCachedImage component={FitImage} source={{ uri }} indicator={true} style={{}} />
Does not render an image even-though the purpose of FitImage is that

ImageCache.get().clear() is not working on CustomCachedImage

CustomCachedImage always show first user image
Image url like {DOMAIN_NAME}/api/profile/images/cropped

<CustomCachedImage
     component={Thumbnail}
     large
     source={{
     uri: profileImage(),
     headers: {
        Authorization: oauth.token_type + ' ' + oauth.access_token
     },
}}/>
ImageCache.get().clear().done(() => {
    // some code
});

Android FlatList Full-Screen View: Flickering and Z-Fighting

Hey dude,

thanks for your great work. The package is working very well on iOS but we have some problem when running under some very specific circumstances on Android.

I don't know how to describe in brief. If you need any other information, please don't hesitate to ask. I am more than willing to provide any additional context.

We make use of two scene with respectively one FlatList. The first scene is an overview of images. We show images on a 3x3 grid. Everything works fine. In the second scene, we show exactly the same images but in a full-screen view. Here are some strange problems. When we swipe through the images, we get like randomly images overlapping each other for some seconds. It looks like some Z-Fighting/Flickering. I am not sure if it has something to do with the FlatList, but when we switch to <Image> everything is working fine. If you want, I can upload a GIF.

I use React-Native v0.43.0

Thanks for your help.

Jest throws React.createElement: type is invalid when using CachedImage in any List component

Ran into this issue when trying to test a component that is implementing CachedImage

Example list component:
ListComponent.js

import React, { PureComponent } from 'react'
import { FlatList } from 'react-native'
import { CachedImage } from 'react-native-img-cache'


export default class ListComponent extends PureComponent {
  renderItem = ({ item }) => {
    return (
      <CachedImage
        source={{ uri: item.url }}
        resizeMode="cover"
      />
    )
  }
  render() {
    return (
     <FlatList
       numColumns={4}
       horizontal={false}
       data={this.props.images}
       renderItem={this.renderItem}
       keyExtractor={(item) => item.id}
     />
    )
  }
}

ListComponent.test.js

import 'react-native'
import React from 'react'
import renderer from 'react-test-renderer'
import ListComponent from '@components/ListComponent'

 it('renders list of images with CachedImage component', () => {
    const images: [
            { id: 1, url: 'https://via.placeholder.com/80x80' },
            { id: 2, url: 'https://via.placeholder.com/80x80' },
            { id: 3, url: 'https://via.placeholder.com/80x80' },
            { id: 4, url: 'https://via.placeholder.com/80x80' },
      ],

    const component = renderer.create(<ListComponent images={images} />)

    expect(component).toMatchSnapshot()
  })

Resulting Error:

 FAIL  src/components/ListComponent/__tests__/ListComponent.test.js
  ● Console

    console.error node_modules/react-native/Libraries/Core/ExceptionsManager.js:71
      Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the fil
e it's defined in.

      Check the render method of `CellRenderer`.
          in CellRenderer (created by VirtualizedList)
          in View (created by View)
          in View (created by ScrollViewMock)
          in RCTScrollView (created by Unknown)
          in Unknown (created by ScrollViewMock)
          in ScrollViewMock (created by VirtualizedList)
          in VirtualizedList (created by FlatList)
          in FlatList (created by ListComponent)
          in View (created by View)
          in View (created by ListComponent)
          in ListComponent

It renders just fine on the device both Android and iOS but fails in a test. Looks like CellRenderer from VirtualizedList is expecting a component at mount time but CachedImage does not return a valid component? The test will pass if native Image component is used instead of CachedImage.

Thoughts?


Stack:
"react-native": "0.44.0",
"react": "16.0.0-alpha.6",
"jest": "^20.0.0",
"react-test-renderer": "^15.6.1",

Need support require from local

thank for lib, but it still run uri image link, dont run with require source.
i hope lib support require: source={require('../Images/no-avatar.png')}

Android didn't load the image

everything seems nicely on IOS but android is when I didn't connect to the internet. it shows a blank image.
here's my code
example url is below
screen shot 2017-07-12 at 2 29 17 pm

ImageCache.get() is throwing an error

I have been trying to clear the cached entries and physical files but getting an error. Recently when I call ImageCache.get() or ImageCache.get().clear() I get this error... (_reactNativeImgCache.ImageCache.get is not a function). It looks like some recent updates may have broken this behavior but any advice would be greatly appreciated.

How to get image size from cache ?

Hi !

I need to know the size of an image to resize it by width and preserve ratio.
I've tried to use react-native-auto-height-image, but it doesn't support source prop,
the displayed image it gets from cache and the size from URL... It's not the behavior that I expect.

So, How can I get image size from cache with react-native-img-cache ?

thank you in advance 😃

Cannot show Pictures after certain number of pics on Android

This is my environment:
React-native 0.43.4
React-native-img-cache 1.3.0
Android 6.0 +

As shown in the screenshots below, after certain numbers of pics, it just shows blank, rather than the picture itself.
I can confirm that the pics have been successfully saved in the cache. This problem only occurs in Android, it works fine in iOS devices.
Please help me solve this issue, thank you!

0-ea-d1-bf030ed18c46286e09d375be8b96c8ed

0-ea-d2-696666538740c8c7c74cb64d84d40853

0-ea-d1-2404a4be4fafa3a332086e1f37eecaa6

Local image support broken in 1.5.x

I noticed that support for local images, which had been added by #51, is broken in newer versions starting from NPM release 1.5.0. On those versions, the library again throws an error when passing a source of type number to the CachedImage component.

Apparently the error-throwing source check was re-introduced by this commit: 8d5c073#comments

Was this on purpose or by accident? Unfortunately I couldn't find any changelog or release notes that would explain how different versions are intended to behave.

Images are not displaying correctly...

screenshot_20170719-133316

This does not occur all the time, but happens every once in a while....
Any ideas what the issue could be?
This issue only occurs on android, and does not occur on iOS

[Request] - Please add TTL for cache

It would be nice to cache an image for a longer time than an application lifetime. For example, add a property with TTL (number of seconds) where a user can specify that image will stay in cache for max 2 weeks (no matter if user kill the app or not)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.