How to convert video path to NSData - ios

I have used DKImagePicker for fetching multiple videos from gallery. Able to fetch video but not getting convert to NSData. And also receiving error from server.
Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_0040.MOV” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/var/mobile/Media/DCIM/100APPLE/IMG_0040.MOV, NSUnderlyingError=0x172e5f6b0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
May be not converted to NSData properly or may be some other issue.
what i tried so far is:
let videoURL = User.sharedInstance.arrRoomGalleryVideos.objectAtIndex(index) as? NSURL
var movieData: NSData?
do {
let video = try NSData(contentsOfURL: videoURL!, options: .DataReadingMappedIfSafe)
print("video", video)
multipartFormData.appendBodyPart(data: video, name: "video_path[]", fileName: strVidName, mimeType: "mp4")
} catch {
print(error)
return
}
Please guide. Thanks in advance.

You should copy file into Documents or any other place IMMEDIATELY when you get file path from delegate method. Because originally file was placed into private folder, which is temporary as I understand. So when your 3-rd party tool finishes processing and stores into the file - it becomes inaccessible at some point.
So after you copy it using copyItemAtPath:toPath: or something like that - you may get NSData by reading it from new path.
From DKImagePicker git I found method: writeAVToFile(path:presetName:completeBlock:) which may help. Look here.

Related

NSFileManager moveItem throws Error Code=513

I'm trying to move a file from a URL to another, however I get an error with code 513. I understand that this is a NSFileWriteNoPermissionError. I don't see how this possible considering I created the folder in the first place.
//self.video!.folderURL.path = /var/mobile/Containers/Data/Application/066BDB03-FD47-48D8-B6F8-932AFB174DF7/Documents/AV/769c504203024bae95b47d78d8fe9029
try? fileManager.createDirectory(atPath: self.video!.folderURL.path, withIntermediateDirectories: true, attributes: nil)
// Update permission for AV folder
do {
let parentDirectoryPath = self.video!.folderURL.deletingLastPathComponent().path
let result = try fileManager.setAttributes([FileAttributeKey.posixPermissions: 0o777], ofItemAtPath: parentDirectoryPath)
print(result)
} catch {
print("Error = \(error)")
}
// sourceURL = file:///private/var/mobile/Containers/Data/PluginKitPlugin/50D8B8DB-19D3-4DD6-93DD-55F37CF87EA7/tmp/trim.6D37DFD2-5F27-4AB9-B478-5FED8AA6ABD7.MOV
// self.url = file:///var/mobile/Containers/Data/Application/066BDB03-FD47-48D8-B6F8-932AFB174DF7/Documents/AV/0b0b6803e891780850152eeab450a2ae.mov
do {
try fileManager.moveItem(at: sourceURL, to: self.url)
} catch {
QLogTools.logError("Error moving video clip file \(error)")
}
Error
Error Domain=NSCocoaErrorDomain Code=513 "“trim.90A10B33-B884-419F-BAD9-65583531C3C3.MOV” couldn’t be moved because you don’t have permission to access “AV”." UserInfo={NSSourceFilePathErrorKey=/private/var/mobile/Containers/Data/PluginKitPlugin/0849234B-837C-43ED-BEDD-DE4F79E7CE96/tmp/trim.90A10B33-B884-419F-BAD9-65583531C3C3.MOV, NSUserStringVariant=(
Move
I tried altering the permission of the folder I created in the first place to 0o777, but when I print out its attributes it returns 511 as its permissions.
P.S:This only happens on iOS 13.
I solved my issue, but it may be different to what you were experiencing: I still had issues when changing to copyItem. I'm adding my findings here as an answer in case anyone else stumbles upon this question as I did and it helps them out.
My app loads custom files that can be downloaded from my website. With iOS 13's download manager, these are copied to the Downloads folder first, and can then be opened by my app. Yet my app was having permission errors when attempting to access these files in the same way as iOS 12.
This answer to a different question clued me in. I need to call startAccessingSecurityScopedResource() and stopAccessingSecurityScopedResource() as follows:
// source and destination are URLs
if source.startAccessingSecurityScopedResource() {
try FileManager.default.moveItem(at: source, to: destination)
}
source.stopAccessingSecurityScopedResource()
The Apple documentation doesn't really suggest that this is new with iOS 13 but I think just the different approach to file downloading means sandboxing considerations need to be made.

File not exists while copy from document folder to nsbundle app folder swift

I am trying to save xlsx file from document folder to app folder. Here is code but it showing error:
Error Domain=NSCocoaErrorDomain Code=260 "The file “file1.xlsx” couldn’t be opened because there is no such file." UserInfo={NSFilePath=file:///private/var/mobile/Containers/Data/Application/8AC91C23-3662-44FF-90EF-20F6A34AF61F/Documents/file1.xlsx, NSUnderlyingError=0x16169a60 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
let directoryContents = try NSFileManager.defaultManager().contentsOfDirectoryAtURL( documentsUrl, includingPropertiesForKeys: nil, options: [])
let xlsxFiles = directoryContents.filter{ $0.pathExtension == "xlsx" }
let xlsxFileNames = mp3Files.flatMap({$0.URLByDeletingPathExtension?.lastPathComponent})
var fileManager = NSFileManager.defaultManager()
do {
try fileManager.copyItemAtPath(xlsxFiles[0].absoluteString, toPath: NSBundle.mainBundle().resourcePath! + xlsxFileNames[0] + ".xlsx")
}
catch let error
{
print(error)
}
You have two problems. The first one is causing the error you posted in your question.
Both parameters to copyItemAtPath need to be full file paths. Your first argument is just a file name. You need to append the file name to a full path to its location (similar to what you do for the second argument).
The app's bundle is read-only. You can't copy a file to your app's bundle. So even once you fix the first problem, you will have a new problem. If the file is already inside your app's Documents folder, why do you try to copy it to the bundle?

Rewrite or delete existing .png file in IOS swift apllication

I would like to add the text on my .png image which exist in my swift application and REPLACE my old image with this edited image.
But when I am trying to remove old image I am getting the error message :
Error : Error Domain=NSCocoaErrorDomain Code=513 "“Background.png”
couldn’t be removed because you don’t have permission to access it."
UserInfo={NSFilePath=/var/containers/Bundle/Application/57134C17-50A5-
4709-9E3B-8013733175BA/SignatureApp.app/Background.png, NSUserStringVariant=(
Remove
), NSUnderlyingError=0x12cd8c150 {Error
Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
Code which I am using to remove my old png file is :
let path = NSBundle.mainBundle().pathForResource("Background", ofType: "png")!
let fileManager = NSFileManager.defaultManager()
do {
try fileManager.removeItemAtPath(path)
}
catch let error as NSError {
print("Error: \(error)")
}
Can anybody give an idea how is it possible to rewrite or delete existing .png file in IOS swift aplication?
I don't believe you can do this. The image is part of your app bundle. You would need to upload a new application.
Instead you could store the image in the documents or cache directory and in your code check if that file exists and load it instead of Background.png.

Transform video file from library to NSData object, using full path to that video (in Swift)

How read video file from video library on the phone if we know full path to video file, for example:
/private/var/mobile/Media/DCIM/100APPLE/IMG_0011.MOV
I tried to use that path in NSData like this:
let videoData = try NSData(contentsOfFile: "/private/var/mobile/Media/DCIM/100APPLE/IMG_0011.MOV", options: NSDataReadingOptions.DataReadingMappedIfSafe)
but I receive this error:
Error Domain=NSCocoaErrorDomain Code=257
"The file “IMG_0011.MOV” couldn’t be opened because you don’t have permission to view it."
UserInfo={NSFilePath=/private/var/mobile/Media/DCIM/100APPLE/IMG_0011.MOV,
NSUnderlyingError=0x17d88fc0 {Error Domain=NSPOSIXErrorDomain Code=1
"Operation not permitted"}}
Reading (loading) video file from folder (path) in the aplication works fine, but reading from path that is not in the application folder (like path above) does not work.
So, my question is: how read (get) video file from phone's video library (using full video path) and transform to NSData object, but without saving any data to the disc (using RAM only) during that process?

iOS 9 read file permission

In iOS 9+ I get a nil on any attempt to read from file. The file in this case is a image file path.
using
NSData(contentsOfFile: stringpath, options: NSDataReadingOptions.DataReadingUncached)
or
NSData(contentsOfFile: stringpath)
Actions:
I have removed the "file://" from the path and it now has a permissions issue.
Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_0048.JPG” couldn’t be opened because you don’t have permission to view it." UserInfo={NSFilePath=/var/mobile/Media/DCIM/100APPLE/IMG_0048.JPG, NSUnderlyingError=0x13f978f50 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
I have added the NSAllowArbitraryLoads and set it to true.
I have tried to look for the file myself using "NSSearchPathDirectory" however the paths do not match in any way
I encountered this error because I was attempting to access multiple files in the same block. The fix that worked for me was changing the code structure such that each file url was obtained, then read from, before attempting to get the next file url.
You are most likely getting this error, because iOS apps only have access to files within its sandbox. See Apple documentation on file systems for details.
In your Application, you don't have permission to access the file of /var/mobile/Media/DCIM/100APPLE/IMG_0048.JPG, because of Sandboxing.
So, whatever you do, you can't initialize NSData or UIImage with the file path. But you can access the file of /var/mobile/Media/DCIM/100APPLE/xxx.mov with AVURLAsset. In my application, I extracted the data rather than URL from gallery by Photos kit and initialized UIImage with the data.
PHImageManager.default().requestImageData(
for: assetObject!, options: options,
resultHandler: {
data, _, _, _ in
if data != nil {
self.assetUrl = movieMaker.createMovieFrom(imageData: data!, duration: Int(CXPreparetValue.imageDuration))
}
})
it works for me! If you have other opinions, please tell me.
In my case, the file permissions were too restrictive, so I couldn't read the file.
Adding read+write permissions to the file before accessing it solved it.
do {
// Retrieve any existing attributes
var attrs = try FileManager.default.attributesOfItem(atPath: stringpath)
let existing = (attrs as NSDictionary).filePosixPermissions()
// Set the read+write value in the attributes dict
attrs[.posixPermissions] = existing | 0b110000000
// Update attributes
try FileManager.default.setAttributes(attrs, ofItemAtPath: stringpath)
// Read data from file
let data = try Data(contentsOf: URL(fileURLWithPath: stringpath, isDirectory: false), options: .uncached)
print("success: \(data.count)")
} catch {
print(error)
}
That works if you're in a folder with enough permissions, as you can change the files permissions even if you didn't had read permission on the file previously. This solution was applied at https://github.com/ZipArchive/ZipArchive/issues/293.

Resources