Permissions error renaming a file on disk - swift

I am trying to rename a file on the local hard disk from a swift MacOS application.
Basically I am bringing up the open panel to select the folder where the files are. then I enumerate the files and rename them to the modification date.
Here is the relevant code:
let openPanel = NSOpenPanel()
openPanel.canChooseDirectories = true
openPanel.canChooseFiles = false
openPanel.canCreateDirectories = false
openPanel.allowsMultipleSelection = false
var mtsVideosFolderPathString : String! = ""
if openPanel.runModal() == NSApplication.ModalResponse.OK
{
mtsVideosFolder = openPanel.urls[0] as URL
mtsVideosFolderPathString = mtsVideosFolder?.path
let fileManager = FileManager.default
let enumerator = fileManager.enumerator(atPath: mtsVideosFolderPathString)
while let element = enumerator?.nextObject() as? String
{
if element.hasSuffix("MTS")
{
let filePath = "\(mtsVideosFolderPathString!)/\(element)"
let fileModDate = self.fileModificationDate(url: URL(fileURLWithPath: filePath))
let format = DateFormatter()
format.timeZone = .current
format.dateFormat = "yyyy.MM.dd HH.mm.ss"
let dateString = format.string(from: fileModDate!)
let fromFilename = "\(mtsVideosFolderPathString!)/\(element)"
let toFilename = "\(mtsVideosFolderPathString!)/\(dateString).mts"
print("Rename \(fromFilename) to \(toFilename)")
do {
try fileManager.moveItem(at: URL(fileURLWithPath: fromFilename), to: URL(fileURLWithPath: toFilename))
}
catch let error as NSError
{
print("Ooops! Something went wrong: \(error)")
}
}
}
}
When I run the app its fails at moveItem in the try/catch with the following error:
Rename /Volumes/BigNFast/test/00000.mts to /Volumes/BigNFast/test/2013.08.05 20.09.50.mts
Ooops! Something went wrong: Error Domain=NSCocoaErrorDomain Code=513 "“00000.mp4” couldn’t be moved because you don’t have permission to access “ test”." UserInfo={NSSourceFilePathErrorKey=/Volumes/BigNFast/test/00000.mp4, NSUserStringVariant=(
Move
), NSDestinationFilePath=/Volumes/BigNFast/test/2013.08.05 20.09.50.mp4, NSFilePath=/Volumes/BigNFast/test/00000.mp4, NSUnderlyingError=0x6000002bb450 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
So, the question is, how do I set the permissions? How to I rename a file on disk?
Thank you for any help

Signing and Capabilities -> File Access -> User Selected File
Change it to read and write with the selector.

Related

Listing all files in a directory on macOS Big Sur

In a different question I asked how to save files on a directory of the user's choosing. The reply was the following code, which works great.
func resolveURL(for key: String) throws -> URL {
if let data = UserDefaults.standard.data(forKey: key) {
var isStale = false
let url = try URL(resolvingBookmarkData: data, options:[.withSecurityScope], bookmarkDataIsStale: &isStale)
if isStale {
let newData = try url.bookmarkData(options: [.withSecurityScope])
UserDefaults.standard.set(newData, forKey: key)
}
return url
} else {
let panel = NSOpenPanel()
panel.allowsMultipleSelection = false
panel.canChooseDirectories = true
panel.canCreateDirectories = true
panel.canChooseFiles = false
if panel.runModal() == .OK,
let url = panel.url {
let newData = try url.bookmarkData(options: [.withSecurityScope])
UserDefaults.standard.set(newData, forKey: key)
return url
} else {
throw ResolveError.cancelled
}
}
}
func saveFile(filename: String, contents: String) {
do {
let directoryURL = try resolveURL(for: "savedDirectory")
let documentURL = directoryURL.appendingPathComponent (filename + ".txt")
print("saving " + documentURL.absoluteString)
try directoryURL.accessSecurityScopedResource(at: documentURL) { url in
try contents.write (to: url, atomically: false, encoding: .utf8)
}
} catch let error as ResolveError {
print("Resolve error:", error)
} catch {
print(error)
}
}
Now, the next step is to go to the directory the user chose when the app loads, and if any files are there, ready each one and add the contents of those files to the struct I use to hold the data.
Googling a little bit I found that you can read all files in a directory using FileManager.default.contentsOfDirectory so I wrote:
func loadFiles() {
do {
let directoryURL = try resolveURL(for: "savedDirectory")
let contents = try FileManager.default.contentsOfDirectory(at: directoryURL,
includingPropertiesForKeys: nil,
options: [.skipsHiddenFiles])
for file in contents {
print(file.absoluteString)
}
} catch let error as ResolveError {
print("Resolve error:", error)
return
} catch {
print(error)
return
}
}
But, I get the following error:
Error Domain=NSCocoaErrorDomain Code=257 "The file “myFiles” couldn’t be opened because you don’t have permission to view it." UserInfo={NSURL=file:///Users/aleph/myFiles, NSFilePath=/Users/aleph/myFiles, NSUnderlyingError=0x600000704ba0 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
which looking at my code I would guess it's happening because I'm not using directoryURL.accessSecurityScopedResource. I tried to add that, or find any other way, but I'm running into a block and I don't know how to get to the directory saved in savedDirectory, and go through every file, reading its contents.
Thank you for any help
If I use:
directoryURL.startAccessingSecurityScopedResource()
// load the files
directoryURL.stopAccessingSecurityScopedResource()
Then it works.

SwiftUI macOS Sandboxed application active read the .ssh/config file

I have Sandboxed application active I need to read the following .ssh/config file.
But I am having the following error:
Ooops! Something went wrong: Error Domain=NSCocoaErrorDomain Code=260
"The file “config” couldn’t be opened because there is no such file."
UserInfo={NSFilePath=/Users/name/Library/Containers/sa.GitRepository/Data//.ssh/config,
NSUnderlyingError=0x600003ccf120 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
Can you tell me how I can solve the problem?
Code:
guard let desktopPath = NSSearchPathForDirectoriesInDomains(.desktopDirectory,
.userDomainMask,
true).first else { return }
_path = State(initialValue: desktopPath)
let pathConfig = desktopPath.replacingOccurrences(of: "Desktop", with: "/.ssh/config")
do {
let contents = try String(contentsOfFile: pathConfig, encoding: .utf8)
let myStrings = contents.components(separatedBy: .newlines)
let users = myStrings.filter { $0.contains("github.com-") }.map {$0.replacingOccurrences(of: "Host github.com-", with: "")}
if(users.count > 0){ _user = State(initialValue: users[0]) }
_userArray = State(initialValue: users)
}
catch let error as NSError {
print("Ooops! Something went wrong: \(error)")
}

Error Domain=NSCocoaErrorDomain Code=256

override func viewDidLoad() {
super.viewDidLoad()
let dataURLString: String = Bundle.main.path(forResource: "IMG_0568", ofType: "JPG")!
let dataURL = URL(string: dataURLString)
do {
let binaryData = try Data(contentsOf: dataURL!, options: [])
let kbData = binaryData.subdata(in: 0..<1024)
let stringArray = kbData.map{String(format: "%02X", $0)}
let binaryString = stringArray.joined(separator: "-")
print(binaryString)
editorTextView.text = (binaryString)
} catch {
print("Failed to read the file.")
//Error Domain=NSCocoaErrorDomain Code=256 "The file “IMG_0568.JPG” couldn’t be opened." UserInfo={NSURL=/Users/..../IMG_0568.JPG}
}
I want to display the Binary Data of Image File that I have added to my Xcode project (image name: IMG_0568.JPG).
But there's the error
(Error Domain=NSCocoaErrorDomain Code=256 "The file “IMG_0568.JPG”
couldn’t be opened." UserInfo={NSURL=/Users/..../IMG_0568.JPG})
How can I fix this problem?
This is a very common mistake:
URLs in the file system must be initialized with URL(fileURLWithPath
let dataURL = URL(fileURLWithPath: dataURLString)
The difference is:
URL(fileURLWithPath expects a path starting with a slash like /Users/myUser/file.ext
URL(string expects an URL string including the scheme like file:///Users... or http://example.com
However you can avoid the mistake by using the URL related API of Bundle
let dataURL = Bundle.main.url(forResource: "IMG_0568", withExtension: "JPG")!

Permission denied when trying to open a file with FileManager (Swift 3)

Not sure this is a problem with my code, but I'm getting a "permission denied" error advising I don't have permission to view the file/folder while executing the let files = try fileManager(...) line.
let fileManager = FileManager.default
let folderURL = URL(fileURLWithPath: "/Volumes/Worktop/Telemetry/", isDirectory: true)
do {
let resourceKeys:[URLResourceKey] = [.fileSizeKey]
let files = try fileManager.contentsOfDirectory(at: folderURL, includingPropertiesForKeys: resourceKeys, options: FileManager.DirectoryEnumerationOptions.skipsHiddenFiles)
for file in files
{
if file.pathExtension == "ibt"
{
print(file.absoluteString)
}
}
} catch {
print(error)
}
The attributes are set to read/write for both the files and the folder, so I don't think this is the problem. Any pointers or help on how to access the files from code is appreciated.

Error Domain=NSCocoaErrorDomain Code=257 The fil "" could not be opened - Firebase

So I am accessing the user's videos & photos through a custom UICollectionView, my issue is that when I attempt to upload to firebase the video through the mobile phone, i am getting this error:
2017-09-03 13:09:20.884509-0400 Project[5797:2021536] Cannot get file size: Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_3476.MP4” couldn’t be opened because you don’t have permission to view it." UserInfo={NSURL=file:///var/mobile/Media/DCIM/103APPLE/IMG_3476.MP4, NSFilePath=/var/mobile/Media/DCIM/103APPLE/IMG_3476.MP4, NSUnderlyingError=0x17064f450 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
/var/mobile/Media/DCIM/103APPLE/IMG_3476.MP4
2017-09-03 13:09:21.261767-0400 Project[5797:2021536] Body file is unreachable: /var/mobile/Media/DCIM/103APPLE/IMG_3476.MP4
Error Domain=NSCocoaErrorDomain Code=257 "The file “IMG_3476.MP4” couldn’t be opened because you don’t have permission to view it." UserInfo={NSURL=file:///var/mobile/Media/DCIM/103APPLE/IMG_3476.MP4, NSFilePath=/var/mobile/Media/DCIM/103APPLE/IMG_3476.MP4, NSUnderlyingError=0x170651b20 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}
Here is where I am loading the files
struct Media {
var image:UIImage?
var videoURL:NSURL?
}
var mediaArray = [Media]()
func grabPhotos(){
let imgManager = PHImageManager.default()
let requestOptions = PHImageRequestOptions()
requestOptions.isSynchronous = true
requestOptions.deliveryMode = .highQualityFormat
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
if let fetchResult : PHFetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions) {
if fetchResult.count > 0 {
for i in 0..<fetchResult.count{
var mediaItem = Media()
//Used for fetch Image//
imgManager.requestImage(for: fetchResult.object(at: i) as PHAsset , targetSize: CGSize(width: 400, height: 400), contentMode: .aspectFit, options: requestOptions, resultHandler: {
image, error in
let imageOfVideo = image! as UIImage
mediaItem.image = imageOfVideo;
//Used for fetch Video//
imgManager.requestAVAsset(forVideo: fetchResult.object(at: i) as PHAsset, options: PHVideoRequestOptions(), resultHandler: {(avAsset, audioMix, info) -> Void in
if let asset = avAsset as? AVURLAsset {
let videoData = NSURL(string: "\(asset.url)")
let duration : CMTime = asset.duration
let durationInSecond = CMTimeGetSeconds(duration)
print(durationInSecond)
mediaItem.videoURL = videoData!
self.mediaArray.append(mediaItem)
print(self.mediaArray.count)
}
})
})
}
}
else{
//showAllertToImportImage()//A function to show alert
}
}
}
I dont think it has to do with when I am uploading the video because i can record a video an upload it from the phone, just not upload from the phone itself; I am just transferring over the url to the nextVC like so:
let videoVC = PrepareVideoVC()
videoVC.url = outputFileURL as URL!
self.navigationController?.pushViewController(videoVC, animated: false)
I looked into this The file “ ” couldn’t be opened because you don’t have permission to view it but couldnt really figure out how to implement it
I also came across https://stackoverflow.com/a/41517165/7823620 but once again I tried implementing it but couldnt get it to not give me errors
Also I can upload from the simulator but not the mobile phone
It is trying to get a file from this directory:
NSFilePath=/var/mobile/Media/DCIM/
You can try
url.startAccessingSecurityScopedResource()
<...>
url.stopAccessingSecurityScopedResource()
use this options:
PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
options.version = PHVideoRequestOptionsVersionCurrent;
options.deliveryMode = PHVideoRequestOptionsDeliveryModeHighQualityFormat;
options.networkAccessAllowed = true;
if you request the middle-quality video, then u will get an error " Error Domain=NSCocoaErrorDomain Code=257, no permission..."
So if the AppDelegate gets passed in a document on launch via this method:
func application(_: UIApplication, open url: URL, options _: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
I found that I had to do this to FIX it so that FileManager documents loaded successfully using Ivan's solution above but you CAN NOT make that call if say the document is an e-mail attachment.
This fixed it for me and huge thanks again to Ivan Vavilov for his post.
func application(_: UIApplication, open url: URL, options _: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
print("Doc attachment passed")
let docAttachment = url
// files written to 'tmp' are NOT backed up to iCloud or iTunes
let tempDir = getTempDirectory()
// add file name to tmp path
tempFileToLoad = tempDir.appendingPathComponent(docAttachment.lastPathComponent)
let fm = FileManager()
// passed a file from the FileManger app?
let isAttachmentScopedResource = docAttachment.startAccessingSecurityScopedResource()
do {
// put in tmp so we can read/write
try fm.copyItem(at: docAttachment, to: tempFileToLoad!)
if(isAttachmentScopedResource) {
// have MUST release the security access after calling it
docAttachment.stopAccessingSecurityScopedResource()
}
} catch {
print("Error getting file. \(error)")
return false
}