在 Userdefaults 错误 swift 中将文档路径保存在自定义结构数组中

saving document path in custom struct array in Userdefaults error swift

我有一个自定义结构信息。对于 属性 图像(字符串),我想插入保存图像的文档目录的路径。当我尝试使用 UserDefaults 保存结构数组时,它被成功保存并被检索。但是当我使用路径从文档目录中检索图像时,它显示以下错误: 致命错误:在展开 Optional 值时意外发现 nil。 当我使用 if-else 块捕获异常时,tableview 上没有显示图像。 下面是我的代码:

struct Information{

var image : String
var content : String?
var url : String?

init(image:String,content:String?,url:String?){
    self.image = image
    self.content = content
    self.url = url

}
init(dictionary : [String:String]) {
    self.image = dictionary["image"]!
    self.content = dictionary["content"]!
    self.url = dictionary["url"]!

}

var dictionaryRepresentation : [String:String] {
    return ["image" : image, "content" : content!, "url" : url!]
}

} 还有我的视图控制器:

 override func viewDidAppear(_ animated: Bool) {
    savePath()
    loadDefaults()
    tableView.reloadData()
}

func saveDefaults()
{
    let cfcpArray = information.map{ [=12=].dictionaryRepresentation }
    UserDefaults.standard.set(cfcpArray, forKey: "cfcpArray")
}

func loadDefaults()
{
    information = (UserDefaults.standard.object(forKey: "cfcpArray") as! [[String:String]]).map{ Information(dictionary:[=12=]) }
    for info in information{
        print(info)
    }
}

func savePath(){
    let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
    // Get the Document directory path
    let documentDirectorPath:String = paths[0]
    // Create a new path for the new images folder
    imagesDirectoryPath = documentDirectorPath + "/ImagePicker"
    var objcBool:ObjCBool = true
    let isExist = FileManager.default.fileExists(atPath: imagesDirectoryPath, isDirectory: &objcBool)
    // If the folder with the given path doesn't exist already, create it
    if isExist == false{
        do{
            try FileManager.default.createDirectory(atPath: imagesDirectoryPath, withIntermediateDirectories: true, attributes: nil)
        }catch{
            print("Something went wrong while creating a new folder")
        }
    }
    tableView.reloadData()
}
 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    // The info dictionary may contain multiple representations of the image. You want to use the edited.
            guard  let selectedImage = info[UIImagePickerControllerEditedImage] as? UIImage
                       else {
                    fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
                    }
      image = selectedImage
      dismiss(animated: true, completion: nil)
        saveImage()
}

func saveImage(){
    // Save image to Document directory
    var imagePath = Date().description
    imagePath = imagePath.replacingOccurrences(of: " ", with: "")
    imagePath = imagesDirectoryPath + "/\(imagePath).png"
    path = imagePath
 //   print(path!)
    let data = UIImagePNGRepresentation(image)
    let success = FileManager.default.createFile(atPath:path!, contents: data, attributes: nil)
    information.append(Information(image:path!, content:" ", url: " "))
    saveDefaults()
    tableView.reloadData()

}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cellIdentifier = "TableViewCell"
    /*Because you created a custom cell class that you want to use, downcast the type of the cell to your custom cell subclass, MealTableViewCell.*/
    guard  let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier , for: indexPath) as? TableViewCell
        else{
            fatalError("The dequeued cell is not an instance of MealTableViewCell.")
    }

    let info = information[indexPath.row]

   if let data = FileManager.default.contents(atPath: info.image)
   {
    let decodeimage = UIImage(data: data)
    cell.photos.image = decodeimage

    }
   else{
    print("Not displaying image")
    }
  //  cell.photos.image = UIImage(data: data!)

   return cell
}

非常感谢任何建议。谢谢。

不要那样做。出于安全原因,文档文件夹的 URL 会定期更改。

保存相对路径 - 或者只保存文件名 - 读取数据后获取当前文档 URL 并附加路径。

注意:NSSearchPathForDirectoriesInDomains 已过时。使用url(for:in:appropriateFor:create:)FileManager

的URL相关API

PS:为什么 contenturl 是可选的,尽管字典初始化程序总是传递非可选值?

这是工作代码。经过测试。 func getDocumentsURL() -> URL {

    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]

    return documentsURL

    }

func fileInDocumentsDirectory(filename: String) -> String {
    let fileURL = getDocumentsURL().appendingPathComponent(filename)
    return fileURL.path

}

并保存图像:

 // Save image to Document directory
            var imagePath = Date().description
            imagePath = imagePath.replacingOccurrences(of: " ", with: "")
            imagePath = "/\(imagePath).png"
            let relpath = getDocumentsURL()
            let relativepath = relpath.appendingPathComponent(imagePath)
            let data = UIImagePNGRepresentation(image)
    let success = FileManager.default.createFile(atPath: relativepath.path , contents: data, attributes: nil)