简体   繁体   English

应用缓存iOS PhoneGap

[英]App cache iOS PhoneGap

On Android I used 在我使用的Android上

file:///storage/sdcard0/Android/data/my.app.id/cache/

to download ( FileTransfer ) some images and then show them in my html. 下载( FileTransfer )一些图像,然后在我的HTML中显示它们。 Images and everything else inside this folder gets removed when deleting my app, which is exactly what I want. 删除我的应用时,图像和此文件夹中的所有内容都会被删除,这正是我想要的。

How to achieve this on iOS? 如何在iOS上实现这一目标?

I tried with 我试过了

file:///var/mobile/Applications/<GUID of app>/Documents/

since this is what I got when requesting file system, but the images won't even download (error code 1). 因为这是我在请求文件系统时得到的,但图像甚至不会下载(错误代码1)。 Any ideas? 有任何想法吗? I found out more about my error: it's the same error as stated in this question. 我发现了更多关于我的错误:这是与问题中所述相同的错误。 (Could not create path to save downloaded file - Cocoa Error 512) (无法创建保存下载文件的路径 - Cocoa Error 512)

Thanks 谢谢


More info: Relevant plugins I use are 更多信息:我使用的相关插件是

<gap:plugin name="org.apache.cordova.file" />
<gap:plugin name="org.apache.cordova.file-transfer" />

and features: 和功能:

<feature name="File">
    <param name="android-package" value="org.apache.cordova.file.FileUtils" />
</feature>
<feature name="File">
    <param name="ios-package" value="CDVFile" />
</feature>
<feature name="FileTransfer">
    <param name="ios-package" value="CDVFileTransfer" />
</feature>

I download images successfully in Android with: 我在Android中成功下载图片:

var fileTransfer = new FileTransfer();    
var uri = encodeURI("myserverurl/"+fileName); 
var filePath = appCachePath+fileName;  
        fileTransfer.download(
            uri,
            filePath,
            function(entry) {
                alert("download complete: " + entry.fullPath); 
            },
            function(error) {  
                alert("download error source/target/code:\n" + error.source +" \n||| "+error.target+" \n||| "+error.code); 
            }  
        );

I download them AFTER I successfully get FS with 我成功获得FS之后下载它们

function onDeviceReady() { 
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail); 
    if(device.platform === 'Android'){
        cacheFolderSubPath = "Android/data/id.app.my/cache/";  
    }
    else{
        cacheFolderSubPath =  ""; //  for iOS what ??   
    }  
}

function gotFS(fileSystem) {    
    var nturl = fileSystem.root.toNativeURL();  // returns cdvfile://localhost/persistent/ for both iOS and Android 
    window.resolveLocalFileSystemURL(nturl+cacheFolderSubPath, onResolveSuccess, onResolveFail);  
}

function onResolveSuccess(fileEntry) { 
     // this is "file:///..." string mentioned in the question above.
    appCachePath = fileEntry.toNativeURL()+"/";  
    // etc etc etc ... (use this appCachePath with download code above)
}

After days of struggling with this I found the not-so-obvious but very easy solution. 经过几天的努力,我找到了不那么明显但非常简单的解决方案。

Instead of using 而不是使用

file:///var/mobile/Applications/<GUID of app>/Documents/

to download files on iOS, I used just plain 要在iOS上下载文件,我只是简单地使用了

cdvfile://localhost/persistent/ 

that I got from 我来自

fileSystem.root.toNativeURL(); // same for Android and iOS

This downloaded my file successfully to 这成功下载了我的文件

file:///var/mobile/Applications/<GUID of app>/Documents/

and this is also the src path I used to display images in HTML. 这也是我用来在HTML中显示图像的src路径。


Just to clarify what happened in my case: ( when using resolveLocalFileSystemURL() ) 只是为了澄清我的情况:(使用resolveLocalFileSystemURL()时)

  • On Android : Android上

     cdvfile://localhost/persistent/ -> file:///storage/sdcard0/ 

    I had to add 我不得不补充一下

     Android/com.my.appid/cache/ 

    manually and if I removed the app, files got removed as well which is OK. 手动,如果我删除了应用程序,文件也被删除,这是好的。

  • On iOS : iOS上

     cdvfile://localhost/persistent/ -> file:///var/mobile/Applications/<GUID of app>/Documents/ 

    Here I didn't need to add anything, persistent storage was already pointing to my app's own 'cache' which is in this case in Documents folder. 在这里我不需要添加任何东西,持久存储已经指向我的应用程序自己的'缓存',在本例中是在Documents文件夹中。 This gets removed with the app as well which is correct. 这也可以通过应用程序删除,这是正确的。

Error code 1 means that the file was not found. 错误代码1表示找不到该文件。

You need to get the application directory that your app is stored in. That is where your files will be eg 您需要获取存储应用程序的应用程序目录。这就是您的文件所在的位置

var imagePath = 'file:///var/mobile/Applications/E50F2661-798B-4F7D-9E6D- BCC266286934/tmp/cdv_photo_011.jpg'

FileErrors = {
    1:   'File not found',
    2:   'Security error',
    3:   'Action Aborted',
    4:   'File not readable',
    5:   'Encoding error',
    6:   'No modification allowed',
    7:   'Invalid state error',
    8:   'Syntax error',
    9:   'Invalid modification error',
    10:   'Quota Exceeded',
    11:   'Type mismatch',
    12:  'Path exists'
};

// extract the application directory from the full path
findApplicationDirectory = function (imagePath) {
  var dir
      , index = fullPath.indexOf('file:///') > -1 ? 6 : 4

  if(fullPath.indexOf('/') > -1){
    fullPath = fullPath.split('/')

    if(fullPath[index]){
      dir = fullPath[index]
    }
  }

  return dir
}

// downloads a file from the server
// @param {string} url
// @param {string} filePath
// @param {function} callback
downloadFile = function (url, fileName, callback){

    getApplicationDirectory(function (applicationDirectory){

        var downloader = new FileTransfer()
                , fileLocation =  findApplicationDirectory(imagePath) + '/' + fileName;

        downloader.download(
            url,
            fileLocation,
            function(entry) {
                console.log("-- downloadFile: download complete: " + entry.fullPath);

                if(typeof callback == 'function'){
                    console.log('-- getFile: calling back');
                    callback.call(this, entry.fullPath);
                }
            },
            function(error) {
                console.log("-- downloadFile: fileLocation " + fileLocation);
                console.log("-- downloadFile: download error source " + error.source);
                console.log("-- downloadFile: download error target " + error.target);
                console.log("-- downloadFile: download error code " + FileErrors[error.code]);
            }
        );
    });
};

Make sure you have access to the Documents folder on iOS by adding UIFileSharingEnabled = "Application supports iTunes file sharing" to your project plist. 通过将UIFileSharingEnabled =“应用程序支持iTunes文件共享”添加到项目plist,确保您可以访问iOS上的Documents文件夹。 Then you can see the contents of your App's documents folder by running your app on a device, connecting it to iTunes and under you device's list of apps finding your app. 然后,您可以通过在设备上运行应用程序,将其连接到iTunes以及设备列表中找到应用程序的应用程序列表来查看应用程序文档文件夹的内容。

To copy any file into the /Documents directory you can use the following 要将任何文件复制到/ Documents目录,您可以使用以下内容

// move photo to documents directory
// @param {string} imagePath
// @return {string} newImagePath
// usage savePhotoToDocuments(imagePath).done(function (newImagePath) { }).fail(function () { })
savePhotoToDocuments = function (imagePath){

    function onFileSystemSuccess(fileSystem) {
        console.log('onFileSystemSuccess: fileSystem.name ' + fileSystem.name);

        window.resolveLocalFileSystemURI(directoryPath, onGetDocumentDirectorySuccess, onGetDocumentDirectoryFail)
    }

    function onFileSystemFail(error){
        console.log('onFileSystemFail: ' + FileErrors[error.code])

        promise.reject(error)
    }

    function onResolveSuccess(fileEntry) {
        imageFileEntry = fileEntry

        imageFileEntry.copyTo(documentDirectory, newImageName, onCopyToSuccess, onCopyToFailed)
        console.log('onResolveSuccess: ' + fileEntry);
    }

    function onResolveFail(error) {
        console.log('onResolveFail: ' + FileErrors[error.code]);

        promise.reject(error)
    }

    function onGetDocumentDirectoryFail (error){
        console.log('onGetDocumentDirectoryFail: ' + FileErrors[error.code]);

        promise.reject(error)
    }

    function onGetDocumentDirectorySuccess (directoryEntry){
        documentDirectory = directoryEntry

        console.log('onGetDocumentDirectorySuccess')

        window.resolveLocalFileSystemURI(imagePath, onResolveSuccess, onResolveFail)
    }

    function onCopyToSuccess (fileEntry) {
        console.log('-- savePhotoToDocuments: onCopyToSuccess')

        promise.resolve(newImagePath)
    }

    function onCopyToFailed (error){
        console.log('-- savePhotoToDocuments: onCopyToFailed - ' + FileErrors[error.code])

        // invalid modification error
        // meaning the file already exists
        if(error.code != 9){
            promise.reject(error)
        } else {
            promise.resolve(newImagePath)
        }
    }

    var imageFileEntry
            , documentDirectory
            , promise = $.Deferred()
            //, imagePath = 'file:///var/mobile/Applications/E50F2651-798B-4F7D-9E6D-BCC266286934/tmp/cdv_photo_011.jpg'
            , imageName = imagePath.substring(imagePath.lastIndexOf('/')+1)
            , newImageName = Date.now() + '_' + imageName
            , directoryPath = 'file:///var/mobile/Applications/' + findApplicationDirectory(imagePath) + '/Documents'
            , newImagePath = directoryPath + '/' + newImageName

    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, onFileSystemFail)

    return promise
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM