i have an issue on the file System on the actual device - ios

my problem is when i try to copy images from the photo library to the filesystem i get the error the error is
(Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_0926.JPG”
couldn’t be opened because you don’t have permission to view it."
UserInfo={NSFilePath=/var/mobile/Media/DCIM/100APPLE/IMG_0926.JPG,
NSUnderlyingError=0x15649630 {Error Domain=NSPOSIXErrorDomain Code=1
"Operation not permitted"}})
my code is :
let fileManager = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let document = fileManager[0]
var i = 0
for asset in arrayOfAssets {
let filePath = document.appendingPathComponent("image\(arrayOfAssets.count + i).png")
i += 1
PHImageManager.default().requestImageData(for: asset, options: nil) { (data, nil, _ , info) in
let url = info?["PHImageFileURLKey"] as! NSURL
do {
try FileManager.default.copyItem(at: url as URL, to: filePath)
}catch {
print(error)
}
// print(filePath)
}
}
please if anyone can help me
thanks all

It sounds like you're trying to open a file located here : NSFilePath=/var/mobile/Media/DCIM/100APPLE/IMG_0926.JPG
By default access to this directory is not permitted, you can only access files located in the document directory, for security reasons.
I don't find where this URL comes from in your code, but according to the NSError you are trying to access an image outside the permitted area of the file system.

Please check the permission option in plist for Photos Library in iOS 11.
Also you can save data in TEMP directory and fetch it when needed and after use
clean data in TEMP directory.

Related

How can I gzip a folder in Swift?

I have a set of files of different types(i.e. .m4a, .mov, .csv) which are saved inside a folder named Test. Now, I want to gzip the folder & send it to server (in order to avoid multiple API calls).
I tried the following (Using GzipSwift Framework) :
do {
let data = try Data(contentsOf: getFolderUrl())
let zippedData = try data.gzipped()
try zippedData.write(to: destinationUrl)
} catch {
print("Error: \(error)")
}
func getFolderUrl() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
let dataPath = documentsDirectory.appendingPathComponent("Test")
return dataPath
}
This gives the following error on first line:
Error Domain=NSCocoaErrorDomain Code=257 "The file “Test” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/Xx...xX/Documents/Test, NSUnderlyingError=0x283151500 {Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied"}}

Writing file to iCloud drive Error Domain=NSCocoaErrorDomain Code=256

I am trying to send a file from local storage of sandboxed app to icloud drive.
Unfortunately I am getting this error:
Error Domain=NSCocoaErrorDomain Code=256 "Soubor „About.txt" couldn't open." UserInfo={NSURL=file:///var/mobile/Containers/Data/Application/1626D575-64CF-4B61-B6B1-38F0B76ED135/Documents/path/path/About.txt, NSUserStringVariant=(
"Cannot disable syncing on a unsynced item."
), NSUnderlyingError=0x13d819630 {Error Domain=NSPOSIXErrorDomain Code=37 "Operation already in progress"}}
My code is as follows:
struct DocumentsDirectory {
static let localDocumentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
static let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
}
Copying function:
func copyFileFromLocacPathToIcloud (fileName:String, filePath:URL, folderName:String) {
let fileManager = FileManager.default
if (ICloudUtils.isiCloudEnabled(icloudURL: DocumentsDirectory.iCloudDocumentsURL)) {
let fileUrl = DocumentsDirectory.localDocumentsURL!.appendingPathComponent("path", isDirectory: true).appendingPathComponent("path", isDirectory:true).appendingPathComponent("About.txt")
if fileUrl.startAccessingSecurityScopedResource() {
}
Log.dbg(msg: "file exists at location \(fileManager.fileExists(atPath: fileUrl.path)) \(fileUrl)")
let iCLoudURL = DocumentsDirectory.iCloudDocumentsURL?.appendingPathComponent(fileName)
do {
try fileManager.setUbiquitous(false, itemAt: fileUrl, destinationURL: iCLoudURL!)
}catch {
Log.error(msg: "icloud save file \(error)")
fileUrl.stopAccessingSecurityScopedResource()
}
}
}
capabilities I have iCloud on. Somebody can help me with this issue ?
I know this question is old but shows up in google search so it may help others.
According to this doc when you try to send the file to iCloud you should set the flag to true. you where using false which is to remove the file from iCloud. Basically change the line from:
try fileManager.setUbiquitous(false, itemAt: fileUrl, destinationURL: iCLoudURL!)
to:
try fileManager.setUbiquitous(true, itemAt: fileUrl, destinationURL: iCLoudURL!)
Hope that helps.

Error when attempting to move item using FileManager

I have a few items that are saved to the documents directory. I currently need those to be moved programmatically to another directory. I created the new directory successfully, but it doesn't seem to be looking at that when using FileManager.default.moveItem.
Code used to created directory.
let path = getDocumentsDirectory().appendingPathComponent("Media").path
do{
try FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: false, attributes: nil)
print("\nDIRECTORY 'Media' CREATED")
}catch {
print("\nDIRECTORY 'Media' WAS NOT ABLE TO BE CREATED")
print("ERROR - \(error)")
}
I use this code to check my URL.
let mediaURL = getDocumentsDirectory().appendingPathComponent("Media")
print("\nMEDIA URL: \(mediaURL)")
Which outputs this.
MEDIA URL:file:///Users/joseph/Library/Developer/CoreSimulator/Devices/552B72BF-8929-40EE-A75B-4574D3D2918A/data/Containers/Data/Application/E168B872-6A1D-4D78-B460-D45194088E5B/Documents/Media/
Here is the code I'm using to move the items.
do{
try FileManager.default.moveItem(at: url, to: mediaURL)
print("\nFILE MOVED TO NEW MEDIA PATH SUCCESSFULLY")
}catch {
print("\nCOULDN'T MOVE FILE TO NEW MEDIA PATH")
print("ERROR - \(error)")
}
Here is the error I'm receiving for each item that I try to move.
COULDN'T MOVE FILE TO NEW MEDIA PATH
ERROR - Error Domain=NSCocoaErrorDomain Code=516 "“image_5” couldn’t be moved to “Documents” because an item with the same name already exists." UserInfo= {NSSourceFilePathErrorKey=/Users/joseph/Library/Developer/CoreSimulator/Devices/552B72BF-8929-40EE-A75B-4574D3D2918A/data/Containers/Data/Application/E168B872-6A1D-4D78-B460-D45194088E5B/Documents/image_5, NSUserStringVariant=(
Move
), NSDestinationFilePath=/Users/joseph/Library/Developer/CoreSimulator/Devices/552B72BF-8929-40EE-A75B-4574D3D2918A/data/Containers/Data/Application/E168B872-6A1D-4D78-B460-D45194088E5B/Documents/Media, NSFilePath=/Users/joseph/Library/Developer/CoreSimulator/Devices/552B72BF-8929-40EE-A75B-4574D3D2918A/data/Containers/Data/Application/E168B872-6A1D-4D78-B460-D45194088E5B/Documents/image_5, NSUnderlyingError=0x60000024fff0 {Error Domain=NSPOSIXErrorDomain Code=17 "File exists"}}
The media directory should be empty, as it is newly created, so the error I'm receiving is a bit confusing. It's also saying it's trying to move it to 'Documents', but it should be moving to 'Media'.What is causing this issue, and how can I resolve it? I'm just trying to move the items saved in 'Documents' to the new directory, 'Media'.
You must append the file name to the destination URL. Per the docs:
The new location for the item in srcURL. The URL in this parameter must not be a file reference URL and must include the name of the file or directory in its new location. This parameter must not be nil.
Delete the old file if exist
let url = NSUrl(string: "...")
if NSFileManager.defaultManager().fileExistsAtPath(url.path!) {
try! NSFileManager.defaultManager().removeItemAtURL(url)
}
Update:
Swift 5.1.2
let url = URL(string: mp3FilePath)
if FileManager.default.fileExists(atPath: url!.path) {
try! FileManager.default.removeItem(at: url!)
}
This worked for me - Add the name of file too in destination path
let nameFile = (songPath as NSString).lastPathComponent
let fileDest = destinationDirectoryPath + "/" + nameFile
//Now move the song files
try fileManager.moveItem(atPath: sourceFilePath, toPath: fileDest)

Swift File Download Issue

I am trying to download a plist file from a remote location and use it in the iOS app I am creating. The file is going to be used for calendar details within the app's calendar. The goal is obviously that I can update the remote file instead of having to push updates to the app itself every time we need to make changes to calendar details.
I started with the code used in this example: Download File From A Remote URL
Here is my modified version:
// Create destination URL
let documentsUrl:URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
let destinationFileUrl = documentsUrl.appendingPathComponent("2017.plist")
//let destinationFileUrl = URL(string: Bundle.main.path(forResource: String(currentYear), ofType: "plist")!)
//Create URL to the source file you want to download
let fileURL = URL(string: "https://drive.google.com/open?id=0BwHDQFwaL9DuLThNYWwtQ1VXblk")
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.removeItem(at: destinationFileUrl)
try FileManager.default.moveItem(at: tempLocalUrl, to: destinationFileUrl)
print("File was replaced")
print(NSArray(contentsOf: tempLocalUrl))
//print(tempLocalUrl)
} catch (let writeError) {
print("Error creating a file \(String(describing: destinationFileUrl)) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: %#", error?.localizedDescription as Any);
}
}
task.resume()
I originally tried to overwrite the file that is bundled with the app to being with, that resulted in errors. So I instead tried to just save it in the app's documents folder and that removed that error. I had to make sure and remove any previous version of the file because it was giving me a file already exists error after the first run.
While it says everything is working (The outputs for both successful download and replaced file happen) when I print the contents of the array from the downloaded URL it just gives me nil.
This is my first attempt to use any kind of external resources in an app. Before I have always kept everything internal, so I am sure there is something glaringly obvious I am missing.
Update 1:
I realized I didn't have the correct URL to use to download a file from a Google drive. That line of code has been changed to:
let fileURL = URL(string: "https://drive.google.com/uc?export=download&id=0BwHDQFwaL9DuLThNYWwtQ1VXblk")
So now I actually am downloading the plist like I originally thought I was. Even removing the deletion issue mentioned in the first comment, I still can't get the downloaded file to actually replace the existing one.
Update 2:
I have reduced the actual file manipulation down to the following:
do {
try FileManager.default.replaceItemAt(destinationFileUrl, withItemAt: tempLocalUrl)
print("File was replaced")
print(NSArray(contentsOf: destinationFileUrl))
} catch (let writeError) {
print("Error creating a file \(String(describing: destinationFileUrl)) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: %#", error?.localizedDescription as Any);
}
After the replacement is performed the output of the file shows the correct new contents that were downloaded from the internet.
Later in the code when I try and access the file it seems to be nil in content again.
Look at your download completion code. You:
Delete the file at the destination URL (in case there was one
leftover)
MOVE the temp file to the destination URL (removing it from the temp
URL)
Try to load the file from the temp URL.
What's wrong with this picture?
You are trying to get the contents of the moved file. You already moved the file to destination url and then you are trying to get the contents of the file from temporary location.
For getting file data, Please try the following :
let fileData = try! String(contentsOf: destinationFileUrl, encoding: String.Encoding.utf8)
print(fileData)

Firebase Storage download to local file error

I'm trying to download the image f5bd8360.jpeg from my Firebase Storage.When I download this image to memory using dataWithMaxSize:completion, I'm able to download it.
My problem comes when I try to download the image to a local file using the writeToFile: instance method. I'm getting the following error:
Optional(Error Domain=FIRStorageErrorDomain Code=-13000 "An unknown
error occurred, please check the server response."
UserInfo={object=images/f5bd8360.jpeg,
bucket=fir-test-3d9a6.appspot.com, NSLocalizedDescription=An unknown
error occurred, please check the server response.,
ResponseErrorDomain=NSCocoaErrorDomain, NSFilePath=/Documents/images,
NSUnderlyingError=0x1700562c0 {Error Domain=NSPOSIXErrorDomain Code=1
"Operation not permitted"}, ResponseErrorCode=513}"
Here is a snippet of my Swift code:
#IBAction func buttonClicked(_ sender: UIButton) {
// Get a reference to the storage service, using the default Firebase App
let storage = FIRStorage.storage()
// Get reference to the image on Firebase Storage
let imageRef = storage.reference(forURL: "gs://fir-test-3d9a6.appspot.com/images/f5bd8360.jpeg")
// Create local filesystem URL
let localURL: URL! = URL(string: "file:///Documents/images/f5bd8360.jpeg")
// Download to the local filesystem
let downloadTask = imageRef.write(toFile: localURL) { (URL, error) -> Void in
if (error != nil) {
print("Uh-oh, an error occurred!")
print(error)
} else {
print("Local file URL is returned")
}
}
}
I found another question with the same error I'm getting but it was never answered in full. I think the proposal is right. I don't have permissions to write in the file. However, I don't know how gain permissions. Any ideas?
The problem is that at the moment when you write this line:
let downloadTask = imageRef.write(toFile: localURL) { (URL, error) -> Void in
etc.
you don't yet have permission to write to that (localURL) location. To get the permission you need to write the following code before trying to write anything to localURL
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let localURL = documentsURL.appendingPathComponent("filename")
By doing it you will write the file into the following path on your device (if you are testing on the real device):
file:///var/mobile/Containers/Data/Application/XXXXXXXetc.etc./Documents/filename
If you are testing on the simulator, the path will obviously be somewhere on the computer.

Resources