【问题标题】:saving document path in custom struct array in Userdefaults error swift在Userdefaults错误swift中将文档路径保存在自定义结构数组中
【发布时间】:2017-11-12 14:47:21
【问题描述】:

我有一个自定义结构信息。对于属性 image(string) 我想插入保存图像的文档目录的路径。当我尝试使用 UserDefaults 保存结构数组时,它已成功保存并被检索。但是当我使用路径从文档目录中检索图像时,它显示以下错误: 致命错误:在展开可选值时意外发现 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{ $0.dictionaryRepresentation }
    UserDefaults.standard.set(cfcpArray, forKey: "cfcpArray")
}

func loadDefaults()
{
    information = (UserDefaults.standard.object(forKey: "cfcpArray") as! [[String:String]]).map{ Information(dictionary:$0) }
    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
}

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

【问题讨论】:

    标签: swift nsdocumentdirectory userdefaults


    【解决方案1】:

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

    保存一个相对路径——或者只是文件名——在读取数据后获取当前文档的 URL 并附加路径。

    注意:NSSearchPathForDirectoriesInDomains 已过时。使用url(for:in:appropriateFor:create:)FileManager的URL相关API

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

    【讨论】:

    • 非常感谢。内容和 url 不应该是可选的。你能告诉我如何保存相对路径或只是文件名。我是 swift 新手,不想改变程序的概念。再次感谢
    • 你得到了imagesDirectoryPath"\(imagePath).png"。所以只保存imagePath 并在每次应用启动后创建imagesDirectoryPath。然后像在您的代码中那样连接两个部分路径。
    【解决方案2】:

    这是工作代码。经测试。 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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-07
      • 1970-01-01
      • 2014-12-15
      • 2018-05-30
      • 1970-01-01
      • 2017-12-06
      • 1970-01-01
      相关资源
      最近更新 更多