Writing: Operation not permitted issue while working pdf - ios

i am working on PDF File to read and write using Core Text .
Below code is to draw content on the PDF file .
let fileName = "pdffilename.pdf"
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory = paths[0] as NSString
let pathForPDF = documentsDirectory.stringByAppendingString(fileName)
UIGraphicsBeginPDFContextToFile(pathForPDF, CGRectZero, nil)
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0,612,792), nil)
pagedataforPortaits()
UIGraphicsEndPDFContext()
This Code is working absolutely fine of simulator but when i am using a real device i am getting an Error
<Error>: CGDataConsumerCreateWithFilename: failed to open `/var/mobile/Containers/Data/Application/CADA69EB-8879-45EE-BBE0-477AC810BB86/Documentspdffilename.pdf' for writing: Operation not permitted.
deflateEnd: error -3: (null).
deflateEnd: error -3: (null).
<Error>: CGPDFContextCreate: failed to create PDF context delegate.
Any Suggestions ??

The path string needs a "/" separator between the documents directory and file name.
Swift 5.1:
let fileName = "pdffilename.pdf"
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let documentsDirectory = paths[0]
let pathForPDF = documentsDirectory + "/" + fileName

Related

URLResourceValues not working for renaming a file

I have to rename some files in a directory in the Documents directory. I'm trying with URLResourceValues:
let fileURLs = try! FileManager.default.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil)
fileURLS.forEach { fileURL in
// calculate newFileName
var resourceValues = URLResourceValues()
resourceValues.name = newFilename
var mutableFileURL = fileURL
try! mutableFileURL.setResourceValues(resourceValues)
}
After setting resourceValues.name I see this in the console...
key NSMutableString "NSURLNameKey" 0x00000001e7a8a368
value NSString "newName.jpg" 0x0000000283f61fe0
So that part is working. The try! completes without crashing so there were no errors thrown. But mutableFileURL is unchanged. It's got the old name, not the new name.
I see in the docs that setting read-only properties or setting properties not supported will be ignored and will not throw an error. But in my research I see this approach used commonly for renaming files. And I don't think it's a write access thing because if I use the old way it works fine:
try! FileManager.default.moveItem(at: fileURL, to: newFileURL)
What could I be missing here?
P.S. app targets iOS 14, running on a real device running iOS 16.1
You have not shown how you know things didn't work. But you say:
But mutableFileURL is unchanged
Your code isn't supposed to change mutableFileURL. If you're looking at mutableFileURL to see what happened, that's the problem.
The URL here is just a pointer to the file on disk. That's the whole point of the setResourceValues approach. Your code changes the name of the file on disk (and mutableFileURL, the pointer, is now invalid and should just be thrown away).
If you re-fetch the contents of the documents directory, you'll see that your code worked just fine.
Complete example, showing both what I think you are doing and how to do this correctly:
// --- create the file ---
let fm = FileManager.default
let docsurl = try fm.url(
for: .documentDirectory, in: .userDomainMask,
appropriateFor: nil, create: false
)
let newurl = docsurl.appending(path: "howdy.txt")
try "howdy".write(to: newurl, atomically: true, encoding: .utf8)
let arr = try fm.contentsOfDirectory(
at: docsurl, includingPropertiesForKeys: nil
)
arr.forEach { print($0.lastPathComponent) }
// howdy.txt
// --- rename the file ---
var values = URLResourceValues()
values.name = "hello.txt"
var mutableurl = newurl
try mutableurl.setResourceValues(values)
// --- how did we do? this is _not_ the way:
print(mutableurl)
// file:///.../Documents/howdy.txt
// --- how did we do? this _is_ the way
let arr2 = try fm.contentsOfDirectory(
at: docsurl, includingPropertiesForKeys: nil
)
arr2.forEach { print($0.lastPathComponent) }
// hello.txt

convert file from bytes in swift 4

Open byte values, that byte contains "textfile"
I have an android code for convert file from bytes values
String root = Environment.getExternalStorageDirectory().getAbsolutePath();
File myDir = new File(root);
File fileWithinMyDir = new File(myDir, filename);
FileOutputStream dest = new FileOutputStream(fileWithinMyDir);
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(dest));
ZipEntry entry = new ZipEntry(filename);
entry.setSize(input.length);
zos.putNextEntry(entry);
zos.write(input);
zos.closeEntry();
zos.close();
but I tried in swift 4
let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent("/download.zip")
print(fileURL)
if let outputStream = OutputStream(url: fileURL, append: true)
{
outputStream.open()
let bytesWritten = outputStream.write(bytes, maxLength: 1024)
if bytesWritten < 0
{
print("write failure")
}
outputStream.close().
}
I save to document directory and open the txt file it has following message displayed when open txt file
The document could not be opened.The file isn't in the correct format
how to open that bytes any one help me

File name that saved in document directory have space character

I want to download video file and save it in the document directory but when i try show that downloaded video, i can't create URL of that file.
i'm using this code for create path for save file. my file name have spacing : (mobileslider video.mp4), and i want to save this video with own name but i can't create url path that contain space. how can solve this problem?
if let url = URL(string:videoURL){
showVideoFromNib(nibURL:url)
}
when i try to remove space from videoURL, showVideoFromNib method called but don't show the video. and when use orginal url, showVideoFromNib method didn't call.
Edit 1:
i change destination path from :
let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)
to :
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
let pathComponent = "pack\(self.packID)-\(selectRow + 1).mp4"
let directoryURL: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let folderPath: URL = directoryURL.appendingPathComponent("Downloads", isDirectory: true)
let fileURL: URL = folderPath.appendingPathComponent(pathComponent)
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
now i can create URL and my show video method call but video don't show.
this is my new sample path:
/Users/MyUser/Library/Developer/CoreSimulator/Devices/2C2B6A39-5426-4E2C-B25A-CF64817AF26F/data/Containers/Data/Application/5A1BB109-D452-4F03-8820-EE1120E07C3D/Documents/Downloads/pack7-2.mp4
this file exist in this path but video player don't show this.
I solve problem. i'm using
let path = destinationUrl.absoluteString
instead of
let path = destinationUrl.path

Print all filenames in a folder in iOS application

I have a folder with 4 subfolders in my iOS application with each of these containing about 20 files each. I would like to be able to iterate through each folder and print out the filenames. I am not sure how to go about doing this.
Here is what I have tried:
let docsPath = NSBundle.mainBundle().resourcePath! + "/Samples";
let fileManager = NSFileManager.defaultManager()
var error: NSError?
let docsArray = fileManager.contentsOfDirectoryAtPath(docsPath, error:&error)
println(docsArray)
This prints out nil. I expect it to print out each of the filenames. How do I make this happen?
You have two problems here:
1)
Check your built app to see if "Samples" is really ending up in the built binary. From the error of "The operation couldn’t be completed", I'm thinking you aren't copying "Samples" into the compiled app bundle or at least into the place you're expecting it to be.
2)
The call you're doing will give you the contents of the folder, but not the contents of the subfolders which is what you really want to list.
Use NSDirectoryEnumerator instead to get the contents of that folder and subfolders. Here is a related question that might give you one direction to go.
You can use the NSFileManager's enumerator if you want to get all the files including inside subdirectories.
Simple example:
if let enumerator = fileManager.enumeratorAtURL(docsPath, includingPropertiesForKeys: nil, options: nil, errorHandler: nil) {
while let url = enumerator.nextObject() as? NSURL {
println(url)
}
}
Nevermind, I figured it out:
var docsPath = NSBundle.mainBundle().resourcePath! + "/Snare";
let fileManager = NSFileManager.defaultManager()
var error: NSError?
let docsArray = fileManager.contentsOfDirectoryAtPath(docsPath, error:&error)
//println(error!.localizedDescription)
println(docsArray)
for filename in docsArray!
{
let subfolderPath = docsPath + "/"+(filename as! String)
println(docsPath)
let subarray = fileManager.contentsOfDirectoryAtPath(subfolderPath, error: &error)
println(subarray)
}

Cannot download attachment in response from server

I have used post method in Alamofire to upload a file successfully, and I get the response from server, I can see the attachment hiding in response. When I'm trying to save the attachment in my computer, it doesn't work. Here is the code:
let urlRequest = urlRequestWithComponents(URL, parameters: parameters, imageData: fileData!)
Alamofire.upload(urlRequest.0, urlRequest.1)
.progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in
println("\(totalBytesWritten) / \(totalBytesExpectedToWrite)")
}
.response { (request, response, data, error) in
println("REQUEST \(request)")
println("RESPONSE \(response)")
println("JSON \(data)")
println("ERROR \(error)")
Here is the file in attachment I got from the server:
"Content-Disposition" = "attachment; filename=20150113171557120001.mid";
And the data shows exactly the right .mid file
JSON Optional(<4d546864 00000006 00000001 00044d54 726b0000 00540391 35350381 35350291 3a3a0281 3a3a0291 3c3c0381 3c3c0191 3e3e0381 3e3e0691 3e3e0381 3e3e0891 3e3e0381 3e3e0291 3c3c0381 3c3c0191 3d3d0381 3d3d0191 3a3a0381 3a3a0691 3a3a0381 3a3a00ff 2f00>)
ERROR nil
Here is the code I use to save the attachment in my computer:
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSArray
let documentsDirectory = paths.objectAtIndex(0) as NSString
let path = documentsDirectory.stringByAppendingPathComponent("file.mid")
(data as NSData).writeToFile(path, atomically:true)
After I add the code of saving the attachment, there are no errors or warnings, while on output except for a thread showing like this:
thread1 exc_breakpoint(code=exc_i386_BPT, subcode=0x0)
Am I using the wrong method to save the attachment?
Looking at your hex representation, that looks like a MIDI file (it starts with the right bytes).
The problem is:
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSArray
let documentsDirectory = paths.objectAtIndex(0) as NSString
You're getting the "first item" twice. That item you're trying to return as paths is not the paths array, but rather the first string in that array (because you included the [0] at the end). Thus, the attempt to cast that as an array will fail (much less the attempt to later grab the first item from it).
Simpler would be:
let documentsDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
You can use url instead of paths
let documentsUrl = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first as NSURL
let fileUrl = documentsUrl.URLByAppendingPathComponent("file.mid")
data.writeToURL(fileUrl, atomically:true)

Resources