Reacvt-Native 圖片下載使用介紹

蘆葦科技App技術團隊發表於2019-01-15

在 Reacvt-Native 的圖片下載上,有蠻多三方元件已經整合封裝,我們這裡來簡單介紹一下 RNFS 的使用

下載

首先貼上程式碼:

	// 圖片
    let downloadDest;
    if (Platform.OS === 'ios') {
    	 // iOS路徑
        downloadDest = `${RNFS.DocumentDirectoryPath}/${((Math.random() * 1000000) | 0)}.jpg`;
    } else {
        // 安卓存在掛載的外接儲存上
        downloadDest = `${RNFS.ExternalDirectoryPath}/${((Math.random() * 1000000) | 0)}.jpg`;
    }
    let formUrl = imageUrl;
    // 判斷有沒有這些字首,沒有的話下載會失敗
    if (formUrl.indexOf("https://") != -1 || formUrl.indexOf("http://") != -1) {
    } else {
        formUrl = 'http://' + formUrl;
    }
    console.log('下載的formUrl===', formUrl)
    const options = {
        fromUrl: formUrl,
        toFile: downloadDest,
        
    };
    try {
        const ret = RNFS.downloadFile(options);
        ret.promise.then(res => {
        		// 下載成功的回撥,例如儲存圖片
            successCallBack('file://' + downloadDest)
            
        }).catch(err => {
            console.log('下載圖片錯誤,錯誤提示:', err);
        });
    }
    catch (error) {
        console.log('下載失敗', error);
    }
複製程式碼

分析

首先使用 RNFS 下載圖片,流程是 設定圖片儲存路徑以及名稱 -> 判斷圖片是否為正常的連結(是否包含http/https開頭,沒有的話下載會失敗!)-> 配置必要的下載引數 -> 在回撥中實現對應邏輯

然後我們就開始從第一步開始說起,

設定圖片儲存路徑以及名稱

因為 iOS 跟安卓端路徑存在差異,因此需要分別對其設定相應路徑;

iOS 路徑使用 RNFS.DocumentDirectoryPath即獲取當前沙盒路徑,安卓端使用 RNFS.ExternalDirectoryPath。

對於圖片的命名,在這邊為了防止出現重名的情況,我們生成 UDID 來做圖片唯一識別,生成方式也很簡單:

export function  getUUID(){
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            var r = Math.random() * 16 | 0,
            v = c == 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        }).toUpperCase();
}
複製程式碼

合起來圖片路徑就可以根據系統分別為:

if (Platform.OS === 'ios') {
    	 // iOS路徑
        downloadDest = `${RNFS.DocumentDirectoryPath}/${( getUUID())}.jpg`;
    } else {
        // 安卓存在掛載的外接儲存上
        downloadDest = `${RNFS.ExternalDirectoryPath}/${( getUUID())}.jpg`;
    }
複製程式碼

判斷圖片是否為正常的連結

使用 RNFS 下載圖片預設不支援沒有包含http/https開頭的,因此我們需要對其連結做一個判斷:

let formUrl = imageUrl;
    // 判斷有沒有這些字首,沒有的話下載會失敗
    if (formUrl.indexOf("https://") != -1 || formUrl.indexOf("http://") != -1) {
    } else {
        formUrl = 'http://' + formUrl;
    }
複製程式碼

這樣就不會有問題了~

配置必要的下載引數

目前有以下這些引數,不過對我們來說只需要配置幾個必要的即可

type DownloadFileOptions = {
  fromUrl: string;          // 下載地址(必要)
  toFile: string;           // 下載到本地的路徑(必要)
  headers?: Headers;        // 通過伺服器的頭部資訊
  background?: boolean;     // 是否允許在後臺下載(只支援 iOS)
  discretionary?: boolean;  // 是否允許設定下載的時間和速度  (只支援 iOS)
  cacheable?: boolean;      // 是否允許 NSURLCache 獲取快取內容,預設允許(只支援 iOS)
  progressDivider?: number; // 設定下載進度回撥的次數,比如設定 progressDivider = 5,那在進度回撥中回回撥5次,分別為:0,20,40,60,80,100,下載完成100的回撥預設存在
  begin?: (res: DownloadBeginCallbackResult) => void;//開始下載
  progress?: (res: DownloadProgressCallbackResult) => void;///下載進度
  resumable?: () => void;    // 斷點續傳(只支援 iOS)
  connectionTimeout?: number // 設定連結超時時間(只支援安卓)
  readTimeout?: number       // 設定讀取資料超時時間,兩個端都是通用的
};
複製程式碼

如果只是簡簡單單想要下圖片的話,我們們只需要用前兩個就ok了~

const options = {
        fromUrl: formUrl,
        toFile: downloadDest,
        
    };
    //開始下載
    const ret = RNFS.downloadFile(options);
複製程式碼

在回撥中實現對應邏輯

接著下載成功後,圖片儲存的路徑就是我們之前設定的檔案路徑,然後還需要在前面新增上 file:// 才能檢視圖片

	try {
        
        ret.promise.then(res => {
        		// 下載成功的回撥,例如儲存圖片
            successCallBack('file://' + downloadDest)
            
        }).catch(err => {
            console.log('下載圖片錯誤,錯誤提示:', err);
        });
    }
    catch (error) {
        console.log('下載失敗', error);
    }
複製程式碼

拷貝

拷貝功能使用起來就比較簡單,不過需要注意的是使用 RNFS 拷貝圖片之後,其實嚴格意義上說這個是剪下,並且需要重新對圖片命名;

首先,設定拷貝檔案的路徑,也是按照上面的方法:

let imageUrl =Platform.OS === 'ios'?('file://'+ `${RNFS.DocumentDirectoryPath}/${(getUUID())}.jpg`)
    :('file://'+ `${RNFS.ExternalDirectoryPath}/${(getUUID())}.jpg`);
複製程式碼

接著呼叫拷貝的方法

RNFS.copyFile(url,imageUrl)
                    .then(()=>{
                        console.log('copy成功~',imageUrl)
                        
                    })
                    .catch((error)=>{
                        LWToast.hide()
                        console.log('error:',error)
                    });

複製程式碼

url 為原圖片路徑,這裡還有一個地方值得注意的是,原圖片如果是把路徑做了持久化儲存,在第二次開啟 app 的時候,你會發現再次開啟圖片時是無法獲取到圖片的,對於 iOS 來說,因為 app 是在沙盒中執行,而每次執行的沙盒地址不一樣,因此我們只需要對圖片名稱做持久化儲存即可,然後通過 RNFS.DocumentDirectoryPath 這個方法來拼接真實路徑就可以了。

相關文章