We want to include zip file on react native project, for example in project/src/assets/zip
folder, include it in the build and extract it to local phone storage on initial App run.
What we want to achieve is, suppose we have a web page that we want to show on react native app. We can decrease the loading time by including the asset for the web page on the project, then told the web page to search for the assets file locally.
We have successfully showing web page with local assets downloaded from internet, in zip format. But We haven’t found on how to achieve the same using zip file on local project.
We have try to import the asset file, then unzip it directly like below with no luck
import zipFile from './assets/zip/file.zip'
import * as RNFS from 'react-native-fs'
import { unzip } from 'react-native-zip-archive'
...
componentDidMount() {
const destination = RNFS.DocumentDirectoryPath + '/'
unzip(zipFile, destination)
.then((result) => {
console.log(result)
})
.catch((error) => {
console.log(error)
})
}
We have try to use react-native-local-resource to get the file with several combinations without luck too
import zipFile from './assets/zip/file.zip'
import * as RNFS from 'react-native-fs'
import { unzip } from 'react-native-zip-archive'
import loadLocalResource from 'react-native-local-resource'
...
componentDidMount() {
const destination = RNFS.DocumentDirectoryPath + '/'
loadLocalResource(assetsZip)
.then((fileContent) => unzip(fileContent, destination))
.then((result) => {
console.log(result)
})
.catch((error) => {
console.log(error)
})
}
import zipFile from './assets/zip/file.zip'
import * as RNFS from 'react-native-fs'
import { unzip } from 'react-native-zip-archive'
import loadLocalResource from 'react-native-local-resource'
...
componentDidMount() {
const destination = RNFS.DocumentDirectoryPath + '/'
const fileName = 'file.zip'
loadLocalResource(assetsZip)
.then((fileContent) => RNFS.writeFile(destination + fileName, fileContent))
.then(() => unzip(destination + fileName, destination))
.then((result) => {
console.log(result)
})
.catch((error) => {
console.log(error)
})
}
How can We extract zip file on project folder into Phone Storage?
EDIT:
while the previous answer was working on debug version of the app, it seems to break on production, because on production resource.uri
return file://
uri instead of http://
as in debug version.
to fix the problem we need to check whether it was file
uri or http
url. then use copy function on react-native-fs instead of download function, if it was file
uri.
import zipFile from './assets/zip/file.zip'
import * as RNFS from 'react-native-fs'
import { unzip } from 'react-native-zip-archive'
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'
...
componentDidMount() {
const destination = RNFS.DocumentDirectoryPath + '/'
const filename = 'file.zip'
const resource = resolveAssetSource(zipFile)
const fileUri = resource.uri
this.loadZipFile(fileUri, destination + filename)
.then((result) => unzip(destination + filename, destination))
.then((result) => {
console.log(result)
})
.catch((error) => {
console.log(error)
})
}
}
loadZipFile = (fileUri, destinationFile) = {
if (fileUri.startWith('file://')) {
return RNFS.copyFile(fileUri, destinationFile)
} else {
const downloadOptions = {
fromUrl: fileUri,
toFile: destinationFile
}
return RNFS.downloadFile(downloadOptions).promise
}
}
this should work on both production and debug version, even sending zip file using code push was working fine on our case.
OLD ANSWER:
After looking on react-native-local-resource source code, We come up with some Idea.
The problem with react-native-local-resource in our case is, that the final result was text
, but zip file is not a text
. So we try to intercept the code in the middle to get zip file as we want.
After some experiment, we follow react-native-local-resource code until we got the uri
of the file, then use react-native-fs to download the file into local storage folder, then unzip those file.
Here is sample of working code on our case
import zipFile from './assets/zip/file.zip'
import * as RNFS from 'react-native-fs'
import { unzip } from 'react-native-zip-archive'
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'
...
componentDidMount() {
const destination = RNFS.DocumentDirectoryPath + '/'
const filename = 'file.zip'
const resource = resolveAssetSource(zipFile)
const fileUri = resource.uri
const downloadOptions = {
fromUrl: fileUri,
toFile: destination + filename
}
RNFS.downloadFile(downloadOptions).promise
.then((result) => unzip(destination + filename, destination))
.then((result) => {
console.log(result)
})
.catch((error) => {
console.log(error)
})
}
Hope it can help anyone who have meet the same problem