Cannot download attachment in response from server - ios

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)

Related

Swift 4 How do I write/read dictionaries to/from the document directory?

I have encryptions in the form of dictionaries that I want to save to the document directory. I also want to be able to retrieve these dictionaries from the document directory to decrypt within the app. How can I write/read dictionaries to/from the document directory?
Dictionary has its own write method which writes a property list representation of the contents of the dictionary to a given URL. You can do it using below code:
Write
// Get application document directory path array
let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.allDomainsMask, true)
let fileName = "users"
if let documentPath = paths.first {
let filePath = NSMutableString(string: documentPath).appendingPathComponent(fileName)
let URL = NSURL.fileURL(withPath: filePath)
let dictionary = NSMutableDictionary(capacity: 0)
dictionary.setValue("valu1", forKey: "key1")
dictionary.setValue("valu2", forKey: "key2")
let success = dictionary.write(to: URL, atomically: true)
print("write: ", success)
}
Read
if let dictionary = NSMutableDictionary(contentsOf: URL){
print(dictionary)
}
Hope, it will work.
Steps include
Get Document URL
Write Date to File
Saving to Disk
Make use of syntax from here:
https://stackoverflow.com/a/26557965/6342609

Userdefault Save and Read URL FilePath [duplicate]

This question already has an answer here:
NSArrayURL , userDefault filePath and URL
(1 answer)
Closed 5 years ago.
I Download pdf file Like This And Saved the Path in Userdefault
var documents = PDFDocument
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let fileName = urlString as NSString;
var arrayUrl = [String]()
arrayUrl.append(filePath)
self.defaults.set(arrayUrl, forKey: Constants.myKeyURL)
The First Time when App Run This documents get Value Well But Next Time When I don't need to Download Again documents it's Null but The ArrayURL ints same Value !!
var arrayUrl = [String]()
self.defaults.stringArray(forKey: Constants.myKeyURL)
arrayUrl = self.defaults.stringArray(forKey: Constants.myKeyURL)!
self.documents = arrayUrl.flatMap { PDFDocument(url: URL(fileURLWithPath: $0) ) }
print(self.documents)
DispatchQueue.main.async {
self.tableView.reloadData()
}
You shouldn't save the file's fullpath, for security reasons your app's container name gets changed, so the document directory would also changed every time your app gets launched/reloaded.
Instead, save only the file's name along its extension (use the property lastPathComponent from the downloaded url), and whenever you want to load these files just append the name to the document directory.

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

Issue getting URL from String for use with AVPlayer

I have constructed a string that is the directory path and file name of file i would like to play in AVPlayer. But I'm struggling to convert this to a URL.
let dataPath = ("\(packDirectory)/").appending((cachedFilePath as NSString).lastPathComponent)
print(dataPath)
audioFileURL = dataPath
self.audioPlayerItem = AVPlayerItem(url: NSURL.fileURL(withPath: audioFileURL) as URL)
print(self.audioPlayerItem)
print(dataPath) returns:
/Users/Geoff/Library/Developer/CoreSimulator/Devices/A31BF8F8-21F6-4227-97B6-9DBDED26CA3E/data/Containers/Data/Application/788085B9-242E-46E7-9644-6A3BF9D515DB/Documents/Next-pk000/7b54d8a0f1a64b710058d4408ca4d696_The%20Name%20of%20the%20Wind%2029-92.mp3
print(self.audioPlayerItem) returns: - the url part:
URL = file:///Users/Geoff/Library/Developer/CoreSimulator/Devices/A31BF8F8-21F6-4227-97B6-9DBDED26CA3E/data/Containers/Data/Application/788085B9-242E-46E7-9644-6A3BF9D515DB/Documents/Next-pk000/7b54d8a0f1a64b710058d4408ca4d696_The%2520Name%2520of%2520the%2520Wind%252029-92.mp3
I don't really understand this stuff but i can see 2 issues with this.
1) file:// : i have purposely removed this from my "dataPath" as when using file manager it cant find anything with this prefix. i have used this code for that:
userDirectory.removeSubrange(userDirectory.startIndex..<userDirectory.index(userDirectory.startIndex, offsetBy: 7))
let packDirectory = userDirectory.appending("Next-\(self.selectedPack!)")
2) the encoding in the .lastComponent has been changed from %20 to %2520
Very confused !
---- EDIT ----
let urlItem = AVPlayerItem(url: URL(fileURLWithPath: audioFileURL))
if let urlAsset = urlItem.asset as? AVURLAsset {
self.audioPlayerItem = AVPlayerItem(url: NSURL(string: urlAsset.url.path) as! URL)
print(urlAsset.url.path)
}
print(self.audioPlayerItem!)
print(urlAsset.url.path) returns :
/Users/Geoff/Library/Developer/CoreSimulator/Devices/A31BF8F8-21F6-4227-97B6-9DBDED26CA3E/data/Containers/Data/Application/BAD0194A-8CDD-44CE-BF99-B9FF35E23BCA/Documents/Next-pk000/7b54d8a0f1a64b710058d4408ca4d696_The%20Name%20of%20the%20Wind%2029-92.mp3
print(self.audioPlayerItem!) returns:
<AVPlayerItem: 0x7bf81b60, asset = <AVURLAsset: 0x7bf87c70, URL = /Users/Geoff/Library/Developer/CoreSimulator/Devices/A31BF8F8-21F6-4227-97B6-9DBDED26CA3E/data/Containers/Data/Applicati ... 9-92.mp3>>
self.audioPlayerItem = AVPlayerItem(url: URL(fileURLWithPath: urlAsset.url.path))
prints:
file:///Users/Geoff/Library/Developer/CoreSimulator/Devices/A31BF8F8-21F6-4227-97B6-9DBDED26CA3E/data/Containers/Data/Application/7C212656-8E1C-44C8-9951-4444FB5EF853/Documents/Next-pk000/7b54d8a0f1a64b710058d4408ca4d696_The%2520Name%2520of%2520the%2520Wind%252029-92.mp3
even using something like:
let asset = AVAsset(url: URL(string: urlAsset.url.path)!) as AVAsset
results in losing some of the url:
<AVPlayerItem: 0x79716ed0, asset = <AVURLAsset: 0x797185d0, URL = /Users/Geoff/Library/Developer/CoreSimulator/Devices/A31BF8F8-21F6-4227-97B6-9DBDED26CA3E/data/Containers/Data/Applicati ... 9-92.mp3>>
And nothing plays. So basically i think it won't play with the file:// prefix but when i plug in the string without it something cuts the path at the i in applications???
You can read about absoluteString and path of URL documentation.
For getting self.audioPlayerItem's URL with lacking of file:/// you can access asset of self.audioPlayerItem and get path of asset.url
let asset = self.audioPlayerItem?.currentItem?.asset
if asset == nil {
return nil
}
if let urlAsset = asset as? AVURLAsset {
return urlAsset.url.path
}
Edited: if you use local file, init URL with URL.init(fileURLWithPath: ) instead of URL.init(string: ). If you use URL.init(string: ), string will be full path (contains file:///), not path.
That's ok, the decoding result is the same. Try to read reference A html space is showing as %2520 instead of %20
P/S: that snippet is just pseudo, please follow the idea from that snippet.

Writing: Operation not permitted issue while working pdf

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

Resources