FileManager.default.fileExists(atPath:) showing nil after saving string to filepath - swift

When I create a filePath for an image then write it to the filePath, it doesn't load the image in the loadImageViewController
saveImageViewController:
let fileManager = FileManager.default
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
let documentPath = documentsURL.path
let filePath = documentsURL.appendingPathComponent("profile_image.png")
do {
let files = try fileManager.contentsOfDirectory(atPath: documentPath)
for file in files {
if "\(documentPath)/\(file)" == filePath.path {
try fileManager.removeItem(atPath: filePath.path)
}
}
} catch {
print("Could not add image from document directory: \(error)")
}
do {
if let pngImageData = profilePicImageView.image!.pngData() {
try pngImageData.write(to: filePath, options: .atomic)
}
} catch {
print("couldn't write image")
}
entity.profilePicPath = filePath.path
loadImageViewController:
if FileManager.default.fileExists(atPath: entity.profilePicPath!) {
let contentsOfFilePath = UIImage(contentsOfFile: entity.profilePicPath!)
cell.entityImage.image = contentsOfFilePath
}
I am saving the file path as a string through core data.

Related

How to save images in ascending order in swift?

I am building an application in which i am using FileManager to save some images using device camera. So for Now I am saving file name as Doc-Time.
I am using below code,
func saveImageToDocumentDirectory(image: UIImage ) {
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm:ss"
let fileName = "Doc-" + dateFormatter.string(from: Date())
let fileURL = documentsDirectory.appendingPathComponent(fileName
)
if let data = image.jpegData(compressionQuality: 1.0),!FileManager.default.fileExists(atPath: fileURL.path){
do {
try data.write(to: fileURL)
print("file saved")
} catch {
print("error saving file:", error)
}
}
}
But Here i want to as, Doc-1,Doc-2, Doc-3....
How can i do that?
You can achieve this by simply storing the next index of the image. Like first the index should be 1 when you used named the image as Doc-1 then the index has 2 in it and so on....
One way to store this index in UserDefaults like:
var nextImageIndex: Int {
UserDefaults.standard.integer(forKey: "NextImageIndex") + 1 //+1 if you want to start with 1
}
func incrementImageIndex() {
UserDefaults.standard.setValue(nextImageIndex, forKey: "NextImageIndex")
}
Put the above code somewhere in UIViewController to see it works.
Here is your updated method...
func saveImageToDocumentDirectory(image: UIImage ) {
guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
return
}
let fileName = "Doc-\(nextImageIndex)"
let fileURL = documentsDirectory.appendingPathComponent(fileName)
let fileAlreadyExists = FileManager.default.fileExists(atPath: fileURL.path)
if let data = image.jpegData(compressionQuality: 1.0), !fileAlreadyExists {
do {
try data.write(to: fileURL)
incrementImageIndex()
print("file saved")
} catch {
print("error saving file:", error)
}
}
}
Create a variable to store the document count and increment it every time your save to the document directory, then use that value in the string.
let documentKey = "documentIndex"
#objc var documentIndex: Int {
get { UserDefaults.value(forKey: documentKey) as? Int ?? 0 }
set { UserDefaults.setValue(newValue, forKey: documentKey) }
}
func saveImageToDocumentDirectory(image: UIImage ) {
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
documentIndex += 1
let fileName = "Doc-\(documentIndex)"
let fileURL = documentsDirectory.appendingPathComponent(fileName
)
if let data = image.jpegData(compressionQuality: 1.0),!FileManager.default.fileExists(atPath: fileURL.path){
do {
try data.write(to: fileURL)
print("file saved")
} catch {
print("error saving file:", error)
}
}
}

how to write data in the local json file iOS Swift?

if let path = Bundle.main.path(forResource: "domaines", ofType: "json") {
if JSONSerialization.isValidJSONObject(dict){
do{
let rawData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
try rawData.write(to: URL(fileURLWithPath: path))
}catch{
}
}else{
}
}else{
print("file not present")
}
This is the code used by me but I'm not able to save the data to the local JSON file.
well, I created a class by which you can create a JSON file then add data to bypassing an array to it and you can update it by replacing data with the new data. check out my code and comment if you don’t understand anything.
it's easy to understand,
it's easy to implement.
// offlineJsonFileManager.swift
// BuzCard
//
// Created by ap00724 on 06/02/20.
// Copyright © 2020 ap00724. All rights reserved.
//
import Foundation
import UIKit
class offlineJsonFileManager: NSObject {
static let sharedManager = offlineJsonFileManager()
func saveToJsonFile(fileName:String,dict:[[String:Any]]) {
guard let documentDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
let fileUrl = documentDirectoryUrl.appendingPathComponent("\(fileName).json")
let personArray = dict
// Transform array into data and save it into file
do {
let data = try JSONSerialization.data(withJSONObject: personArray, options: [])
try data.write(to: fileUrl, options: [])
} catch {
print(error)
}
}
func retrieveFromJsonFile(fileName:String,completion:(Bool,[[String:Any]])->()) {
// Get the url of Persons.json in document directory
guard let documentsDirectoryUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
completion(false,[["error":"file does not exist."]]);return }
let fileUrl = documentsDirectoryUrl.appendingPathComponent("\(fileName).json")
// Read data from .json file and transform data into an array
do {
let data = try Data(contentsOf: fileUrl, options: [])
guard let personArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String:Any]] else { return }
completion(true,personArray)
} catch {
print(error)
completion(false,[["error":"\(error)"]])
}
}
}
private func saveDomaines(json: [[String: Any]]) {
if let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last {
let fileURL = documentsDirectory.appendingPathComponent("domaines.json")
print("File exists")
writeFile(fileURL: fileURL, json: json)
} else {
print("Shouldn't reach here")
}
}
private func writeFile(fileURL: URL, json: [[String: Any]]) {
do {
if let jsonData = try JSONSerialization.data(withJSONObject: json, options: .init(rawValue: 0)) as? Data {
try jsonData.write(to: fileURL)
}
} catch {
print(error.localizedDescription)
}
}

Save file to custom folder

In AppDelegate I create hidden folder in .documents if it doesn't exist:
let fileManager = FileManager.default
let path = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
let audioKitFilesFolder = path.appendingPathComponent(".AudioKitFilesFolder")
var isDir : ObjCBool = false
if fileManager.fileExists(atPath: audioKitFilesFolder.absoluteString, isDirectory:&isDir) {
if isDir.boolValue {
print("file exists and is a directory")
} else {
print("file exists and is not a directory")
}
} else {
do {
try fileManager.createDirectory(at: audioKitFilesFolder, withIntermediateDirectories: true, attributes: nil)
} catch {
print("Can't Create Folder \(error)")
}
}
In my Networking API I have func that save file from web to .documents. But I need save this file to the my hidden Folder. How I can get path for this folder for my copyItem method?
Newtwork API func:
func downloadFile(id: Int, url: URL, fileName: String) {
var request = URLRequest(url: url)
URLSession.shared.downloadTask(with: url, completionHandler: { location, response, error in
guard let location = location, error == nil else { return }
do {
let fileManager = FileManager.default
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documentsURL.appendingPathComponent(fileName)
try fileManager.copyItem(at: location, to: fileURL)
try self.router.configureParameters(bodyParameters: ["uuid": UserDefaultsHelper.uuid], urlParameters: nil, request: &request)
} catch {
print(error)
}
}).resume()
URLSession.shared.dataTask(with: request) { data, response, error in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
}
What happens if you change
do {
let fileManager = FileManager.default
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documentsURL.appendingPathComponent(fileName)
try fileManager.copyItem(at: location, to: fileURL)
try self.router.configureParameters(bodyParameters: ["uuid": UserDefaultsHelper.uuid], urlParameters: nil, request: &request)
} catch {
to
do {
let fileManager = FileManager.default
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let audioKitFilesFolder = documentsURL.appendingPathComponent(".AudioKitFilesFolder")
let fileURL = audioKitFilesFolder.appendingPathComponent(fileName)
try fileManager.copyItem(at: location, to: fileURL)
try self.router.configureParameters(bodyParameters: ["uuid": UserDefaultsHelper.uuid], urlParameters: nil, request: &request)
} catch {
and perhaps remove the . from . AudioKitFilesFolder in all places

Swift FileManager - no such file

I am trying to upload videos. I get true for fileExists but in the logs I see -
Body file is unreachable:
/private/var/mobile/Containers/Data/Application/BE71B534-5051-4552-8491-30E1FE34E128/Documents/upload/306A4291-5E5A-467E-B2F7-8FFCA5BFFC1D1520419887-676644831.mp4
Error Domain=NSCocoaErrorDomain Code=260 "The file
“306A4291-5E5A-467E-B2F7-8FFCA5BFFC1D1520419887-676644831.mp4”
couldn’t be opened because there is no such file."
let dir = "/upload/"
let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let path = documentsUrl.appendingPathComponent(dir)
do {
if let urlArray = try? FileManager.default.contentsOfDirectory(at: path,
includingPropertiesForKeys: [.contentModificationDateKey],
options:.skipsHiddenFiles) {
let mp4Files = urlArray.filter{ $0.pathExtension == "mp4" }
for videoFile in urlArray {
let fileExists = FileManager().fileExists(atPath: videoFile.path)
if fileExists {
let url = URL.init(fileURLWithPath: videoFile.path)
self.uploadVideo(url: url)
}
}
}
} catch {
print(error.localizedDescription)
}
To save the video I use -
let urlData = NSData(contentsOf: videoUrl)
if((urlData) != nil) {
DispatchQueue.main.async(execute: { () -> Void in
urlData?.write(toFile: path, atomically: true)
})
}
Try this one,
create Directory using this code
var nextItemDirUrl : URL!
func createDownloadSongDirIfNotForNextItem() {
let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let logsPath = documentsDirectoryURL.appendingPathComponent("upload")
nextItemDirUrl = logsPath
do {
try FileManager.default.createDirectory(atPath: logsPath.path, withIntermediateDirectories: true, attributes: nil)
print("Directory created at:",logsPath)
} catch let error as NSError {
NSLog("Unable to create directory \(error.debugDescription)")
}
}
After save your file using nextItemDirUrl in DocumentDirectory
let destinationUrl = nextItemDirUrl.appendingPathComponent("yourView.mp4")
yourVideoData.write(to: destinationUrl, atomically: true)
I managed to fix this by doing -
let urlData = NSData(contentsOf: videoFile)
if((urlData) != nil) {
let lastPath = "/videos/" + "temp.mp4"
let path = documentDirectory.appending(lastPath)
urlData?.write(toFile: path, atomically: true)
let fileURL = URL.init(fileURLWithPath: path)
self.uploadVideo(url: url)
}

Trying to clear document folder Swift

I use following method to add file (download) to document directory:
static func downloadFileWithLink(linkString : String){
// Create destination URL
let documentsUrl:URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
let destinationFileUrl = documentsUrl.appendingPathComponent("downloadedFile")
//Create URL to the source file you want to download
let fileURL = URL(string: linkString)
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:fileURL!)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
} catch (let writeError) {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: %#", error?.localizedDescription);
}
}
task.resume()
}
It simply download file to document folder in sandbox. I looked for method that delete files in documents folder, and tried following:
static func deleteFiledInDocDirectory(){
let fileManager = FileManager.default
let tempFolderPath = NSTemporaryDirectory()
do {
let filePaths = try fileManager.contentsOfDirectory(atPath: tempFolderPath)
for filePath in filePaths {
try fileManager.removeItem(atPath: tempFolderPath + filePath)
}
} catch {
print("Could not clear temp folder: \(error)")
}
}
However, when i inspect sandbox, downloaded file is still here. How to delete it?
In deleteFiledInDocDirectory() you're using NSTemporaryDirectory instead of the documents directory that you originally saved the file to.
Change tempFolderPath to be set using following:
guard let tempFolderPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
return // documents directory not found for some reason
}
The full method:
static func deleteFiledInDocDirectory(){
guard let tempFolderPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first?.absoluteString else {
return // documents directory not found for some reason
}
let fileManager = FileManager.default
do {
let filePaths = try fileManager.contentsOfDirectory(atPath: tempFolderPath)
for filePath in filePaths {
try fileManager.removeItem(atPath: tempFolderPath + filePath)
}
} catch {
print("Could not clear temp folder: \(error)")
}
}