每次启动/重新运行应用程序时,iOS文件路径都会更改 编辑1:原始答案

问题描述

在每次启动应用程序时更改文件路径时遇到问题。 我在应用程序捆绑包中有一个文件(“ AppConstant.json”),我需要将此文件复制到应用程序文档目录中。我已成功将“ AppConstant.json”文件保存在文档目录中创建的用户文件夹“ MyFolder”中。

但是问题是当我第二次重新启动应用程序时,它没有显示相同的路径。另外,我正在使用relativepath,但仍然没有得到。

这是代码 //调用目录

 <div v-if="condition=='true'> 
         <input :name="user.name" class="form-control input-md" type="text" :v-model="user.user_value" :v-validate="'required'" :class="['form-control',{'is-invalid': errors.has(user.name)}]"/>
                                <div :v-show="errors.has(user.name)" class="invalid-Feedback">
                                        {{ errors.first(user.name) }}
                                </div>
    </div>


export default {
  data() {
    return {
      user: {},form: new Form({
        contact: "",}),};
  },methods: {
 getvalues() {

  axios.get(APP_URL + `/api/get-values?Id=${id}`,{ headers: header })
        .then((response) => {

  for (var i = 0;i < response.data.list[0].student.length; i++) {
        var id = response.data.list[0].student[i].id;
        var name = response.data.list[0].student[i].name;
  }



    this.form.user.push({
                id: id,name: name,user_value: "",});

 }
   },

//保存或获取退出文件路径

let stringAppConstant = copyFileFromBundletoDocumentDirectory(resourceFile: "AppConstant",resourceExtension: "json")

请帮助我,我需要在SandBox中保存路径。我实施的方法正确吗?

我正在设备和模拟器中运行,重新启动时两条路径都不同 这是首次启动的路径: /var/mobile/Containers/Data/Application/81B568A7-0932-4C3E-91EB-9DD62416DFE8/Documents/MyFolder/AppConstant.json

重新启动我正在获取新路径的应用程序: /var/mobile/Containers/Data/Application/3DAABAC3-0DF5-415B-82A5-72B204311904/Documents/MyFolder/AppConstant.json

注意:我创建了一个示例项目,并且使用了相同的代码,并且可以正常工作。但是在现有项目中,它不起作用。我仅对示例和项目使用相同的捆绑软件ID和配置文件。检查添加文件的参考,设置,版本是否相同。

有什么主意吗?

解决方法

编辑1:

您好,我创建了新项目,并使用了与main中发布的相同的代码,并且可以正常工作。但是在实际项目中,它不起作用。

不确定项目中到底发生了什么,请尝试对其进行调试。这也是开发的一部分。 :)

如果您在本周末急于解决此问题,请尝试使用以下代码段。

#!/bin/bash

# exit on error
set -e
set -o pipefail

cleanup() {
    # make sure the temporary file is removed
    rm -f "$tmp"
}

trap cleanup EXIT

# create a temporary file in the home directory
tmp="$(mktemp -p ~)"
target="${HOME}/.profile"

# run your command and redirect the output to the temporary file
envconsul env | awk '{print "export " $0}' > "$tmp"

# set the same permissions as the current file has
chmod --reference="$target" "$tmp"

# move the temporary file into place
mv -f "$tmp" "$target"

原始答案

为什么不成功执行文件操作就只返回// collect data from bundle let constFileURL = Bundle.main.url(forResource: "AppConst",withExtension: "json")! let data = try! Data(contentsOf: constFileURL) // try to write data in document directory do { let constFileURL = try saveFileInDocumentDirectory(filePath: "MyFolder/AppConst.json",data: data) // use your `constFileURL` } catch (let error as FileOperationError) { switch error { case .fileAlreadyExists(let url): let data = try! Data(contentsOf: url) print(String(data: data,encoding: .utf8)) case .IOError(let error): print("IO Error \(error)") } } catch { print("Unknown Error \(error)") } // Helpers enum FileOperationError: Error { case fileAlreadyExists(url: URL) case IOError(Error) } func saveFileInDocumentDirectory(filePath: String,data: Data) throws -> URL { // final destination path let destURLPath = fullURLPathOf(filePath,relativeTo: .documentDirectory) // check for file's existance and throw error if found guard FileManager.default.fileExists(atPath: destURLPath.path) == false else { throw FileOperationError.fileAlreadyExists(url: destURLPath) } // Create Intermidiate Folders let intermidiateDicPath = destURLPath.deletingLastPathComponent() if FileManager.default.fileExists(atPath: intermidiateDicPath.path) == false { do { try FileManager.default.createDirectory(at: intermidiateDicPath,withIntermediateDirectories: true,attributes: nil) } catch { throw FileOperationError.IOError(error) } } // File Writing do { try data.write(to: destURLPath,options: .atomic) } catch { throw FileOperationError.IOError(error) } return destURLPath } func fullURLPathOf(_ relativePath: String,relativeTo dic:FileManager.SearchPathDirectory ) -> URL { return FileManager.default.urls(for: dic,in: .userDomainMask).first!.appendingPathComponent(relativePath) } ?如果以后需要访问路径,则始终可以使用"MyFolder/\(fileName)" API进行。

FileManager
,

容器路径定期更改的行为是正常的。

这些行

let destFolderPath = URL(string:docURL)?.appendingPathComponent("MyFolder")
let fileName = "\(resourceFile).\(resourceExtension)"
guard let newDestPath = destFolderPath,let sourcePath = Bundle.main.path(forResource: resourceFile,ofType: ".\(resourceExtension)"),let fullDestPath = NSURL(fileURLWithPath: newDestPath.absoluteString).appendingPathComponent(fileName) else {
    return stringURLPath
}

可以犯很多错误

  • URL(string是错误的文件路径API,它是URL(fileURLWithPath)
  • path(forResource:ofType:)的第二个参数不能有前导点。
  • API absoluteString作为URL(fileURLWithPath的参数是错误的
  • 这不是真正的错误,但不要在Swift中使用NSURL

强烈建议始终使用URL相关的API来连接路径并从FileManager获取document文件夹。此外,优良作法是使方法throw成为真正的错误,而不是返回无意义的文字字符串。并且NSSearchPathForDirectoriesInDomains已过时,不应在Swift中使用。

func copyFileFromBundleToDocumentDirectory(resourceFile: String,resourceExtension: String) throws -> URL
{
    let sourceURL = Bundle.main.url(forResource: resourceFile,withExtension: resourceExtension)!
    
    let fileManager = FileManager.default
    let destFolderURL = try fileManager.url(for: .documentDirectory,in: .userDomainMask,appropriateFor: nil,create: false).appendingPathComponent("MyFolder")
    let fullDestURL = destFolderURL.appendingPathComponent(resourceFile).appendingPathExtension(resourceExtension)
    
    if !fileManager.fileExists(atPath: destFolderURL.path) {
        try fileManager.createDirectory(at: destFolderURL,attributes: nil)
        print("Created folder successfully in :::",destFolderURL.path)
        try fileManager.copyItem(at: sourceURL,to: fullDestURL)
        print("Saved file successfully in :::",fullDestURL.path)
    } else {
        print("Folder already exists!")
        if fileManager.fileExists(atPath: fullDestURL.path) {
            print("File exists in ::: \(fullDestURL.path)")
        } else {
            try fileManager.copyItem(at: sourceURL,to: fullDestURL)
            print("Saved file successfully in :::",fullDestURL.path)
        }
    }
    return fullDestURL
}