【问题标题】:App cache iOS PhoneGap应用缓存 iOS PhoneGap
【发布时间】:2014-07-07 12:10:26
【问题描述】:

在安卓上我用过

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

下载 (FileTransfer) 一些图像,然后在我的 html 中显示它们。删除我的应用程序时,此文件夹中的图像和其他所有内容都会被删除,这正是我想要的。

如何在 iOS 上实现这一点?

我试过了

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

因为这是我在请求文件系统时得到的,但图像甚至不会下载(错误代码 1)。有任何想法吗?我发现了有关我的错误的更多信息:它与this 问题中所述的错误相同。 (无法创建保存下载文件的路径 - Cocoa 错误 512)

谢谢


更多信息: 我使用的相关插件是

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

和特点:

<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>

我在 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); 
            }  
        );

我在成功获得 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)
}

【问题讨论】:

  • 发布您正在使用的代码以及您使用的任何 PhoneGap 库。

标签: android ios cordova phonegap-build


【解决方案1】:

经过几天的努力,我找到了一个不太明显但非常简单的解决方案。

而不是使用

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

要在 iOS 上下载文件,我只用了普通的

cdvfile://localhost/persistent/ 

我从

那里得到的
fileSystem.root.toNativeURL(); // same for Android and iOS

这将我的文件成功下载到

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

这也是我用来在 HTML 中显示图像的 src 路径。


只是为了澄清我的情况:(使用 resolveLocalFileSystemURL() 时)

  • Android 上:

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

    我必须添加

    Android/com.my.appid/cache/
    

    如果我手动删除了应用程序,文件也会被删除 好的。

  • iOS 上:

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

    这里我不需要添加任何东西,持久化存储已经 指向我的应用程序自己的“缓存”,在这种情况下是在文档中 文件夹。这也被应用程序删除,这是正确的。

【讨论】:

    【解决方案2】:

    错误码1表示找不到文件。

    您需要获取存储应用程序的应用程序目录。例如,您的文件将存放在该目录中。

    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]);
                }
            );
        });
    };
    

    通过将UIFileSharingEnabled=“应用程序支持iTunes 文件共享”添加到您的项目plist,确保您可以访问iOS 上的Documents 文件夹。然后,您可以通过在设备上运行您的应用程序、将其连接到 iTunes 并在您设备的应用程序列表下找到您的应用程序来查看您应用程序的文档文件夹的内容。

    要将任何文件复制到 /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
    }
    

    【讨论】:

    • 这个的预期输出到底是什么?我知道我的应用程序 afaik 的目录(file:///var/mobile/Applications// 对吗?),但它不会将任何文件下载到 /Documents 子文件夹。关于错误1:找不到文件在哪里?在我提供的网址上?它在那里是因为 Android 找到了它,对吧?有关更多示例,请参阅我的代码
    • 如果下载在 Android 上运行,那么它不太可能是 URL。您是否已启用您的应用程序以使用文档文件夹? stackoverflow.com/questions/11546003/…
    • 我没有启用任何东西,但它确实在 Documents 文件夹中成功创建了一个文件。 (我用 iFunBox 进行检查)它只是不会在那里下载图像。我已经坚持了好几天了:D人们还说,如果保存到文档,他们的应用程序会被拒绝(但他们至少可以以某种方式明显地保存)。我仍然不知道在哪里以及如何在 iOS 上下载图像 aw
    • iOS 可能非常令人沮丧。 :-( 我认为您需要做的就是将其分为两个步骤。1) 下载图像 2) 将图像复制到文档目录中。我已经提出了一些关于如何将图像复制到文档目录的代码
    猜你喜欢
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多