Files and Storage

RSS for tag

Ask questions about file systems and block storage.

Posts under Files and Storage tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Swift Playgrounds version of 'Copy Bundle Resources' build phase
Hi! I'm participating in the Swift Student Developer competition this year, which requires developers to present a Swift Playground to Apple. I'm used to making normal Xcode projects, and am having trouble finding a Swift Playgrounds version of the Copy Bundle Resources build phase (I don't think it is possible to edit build phases in a Swift Playground). I created a '.usdz' file from a 3D model I designed using Reality Converter and added it to the root of my Swift Playground project. I access the file programmatically from the App Bundle like so (fileName is a non-nullable String): guard let path = Bundle.main.path(forResource: fileName, ofType: "usdz") else { fatalError("Couldn't find the USDZ file.") } At runtime, this throws the Couldn't find the USDZ file error, as the file isn't being copied to the App Bundle. In a normal Xcode project, according to this StackOverflow question, I can get xcodebuild to copy my file over by specifying it in the Copy Bundle Resources build phase, however, in a Swift Playground (required by Apple), I am restricted from modifying Xcode's buildphases (the option is not present when clicking on the default target - the only options are General, Signing & Capabilites and Package Dependencies). How can I ensure that resources are copied over to the App Bundle at buildtime in a Swift Playground? If this is not possible, are there any other options besides using the Bundle.main.path API for accessing the USDZ file (to load a QuickLook preview) at runtime?
2
0
821
Jan ’24
How detect cyclic symbolic links using NSFileManager?
My code is crashing Xcode (or even macOS kernel) during debugging - Xcode just vanishes from screen! // pseudo code public func hunt(in directory: URL) { let fileIterator = fileMan.enumerator(at: directory) // collect app packages into a list var packages = [URL]() for case let fileURL as URL in fileIterator { if fileURL.pathExtension == "app" { packages.append(fileURL) } } // FileWrappers var wrappers = [FileWrappers]() for packageURL in packages { //!!! The line below eventually crashes Xcode (or even macOS kernel once)! wrappers[packageURL] = try? FileWrapper(url: packageURL, options: .immediate) // NOTE: I need FileWrapper.matchesContents later in some code } } // unit test case func test() {} myObj.hunt(in: URL(fileURLWithPath: "/Applications")) } I suspect that the FileWrapper constructor is traversing directories and encounter cyclic symbolic links and eventually it crashes; since it's running at system runtime level, most probably it also crashes macOS kernel! So my question is that is there any way to detect cyclic symbolic links so that I can design my own logics similar to FileWrapper?
2
0
346
Jan ’24
Inferring High-Level Semantics from Low-Level Operations
This is a topic that comes up regularly, both in my Day Job™ with DTS and here on DevForums. This situation is a bit subtle, and it’s long past the time I should have written a proper explanation of it. If you have questions or comments, put them in a new thread here on DevForums. To ensure that I see your thread, tag it based on the technology you’re using. For example: If you’re working with Endpoint Security, use the Endpoint Security tag. If you’re building a Network Extension provider, use the Network Extension tag. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Inferring High-Level Semantics from Low-Level Operations Apple supports a number of APIs that let you observe low-level operations. For example: An Endpoint Security (ES) client can learn about low-level file system operations, like open and close. A Network Extension (NE) filter provider can learn about outgoing and incoming network packets. Folks using these APIs often want to infer high-level semantics from these low-level operations. For example: An ES client might want to prevent the Finder from copying files to an external drive. An NE filter provider might want to block Safari from fetching specific URLs. While DTS supports these APIs, we don’t support this sort of low-to-high inference. That’s because our goal is to help developers use Apple’s APIs in a sustainable way, and it’s impossible to do this inference in a way that will be binary compatible in the long term. Let me illustrate this with an example. Consider the NE scenario above. It’s easy for an NE packet filter to drop packets being sent to a specific host. However, that approach is very brittle. If something changes in the implementation path from Safari requesting a URL to how that’s rendered as IP packets, your product will break. A great example of such a change is iCloud Private Relay. This isn’t to say that such inference can’t be done at all, just that it’s not possible to do it in a sustainable way. Given that, here’s my advice: Try to work with high-level operations where possible. For example, ES recently added high-level log in and log out notifications, which means you no longer need to infer such events from lower-level ones. If the system doesn’t support the necessary high-level operations, file an enhancement request that describes your requirements. In the meantime, you can have a go at doing this inference yourself, but be aware that DTS can’t support you in that task.
0
0
393
Jan ’24
SQLite can't create database outside of "Application Support"
I have an application that takes XML data and converts it into database tables. It uses SQLite3 and SQLCipher. If I hard code the path to save the database to put it in my Application Support folder, it works perfectly -- creates the file (with [fm createFileAtPath: newPath contents: nil attributes: nil];) and then opens it with SQLite, it creates the tables and populates them, everything works as expected. If, however, I allow the user to save the database in the location of their choice, say in Documents or Downloads, the application creates the file (with createFileAtPath) but then when SQLite tries to create the tables, it fails with the error "unable to open database file" and error code 14 (which is a generic "couldn't open database" error.) Looking in the save directory, there is now a zero bytes file in that location. Everything that I've seen online indicates that this is a permissions/security issue, but no one seems to point to a solution -- I went so far as to put in code to run chmod on the database and the folder that it's in, even that didn't help. Your input is very much appreciated!
2
0
339
Jan ’24
FileManager.enumerator and URL problem
I have the following pseudo code: func load(at packageURL: URL) { let realPackageURL = packageURL.resolvingSymlinksInPath() guard let it = fileMan.enumerator(at: realPackageURL) for case let fileURL as URL in it { print(fileURL) // Get filename relative to package root directory let relativeFileName = String(filePath.suffix(filePath.count - packagePath.count)) } } When called with "file:///tmp/some.app", the enumerated fileURL is actually file:///private/tmp/GIMP.app/Contents/ packageURL.resolvingSymlinksInPath() actually does nothing, I assume /tmp is a hard link. This makes it impossible to get a correct relative path. Is there any remedy for this?
2
0
379
Jan ’24
[iOS] AVPlayer won't play file after some time
I download a mp4 file into the date folder. I am able to run an AVPlayer and view the video in the app. After some time video won't play. If I enable UIFileSharingEnabled and check if file exists, I can see it's there but then it won't play even from accessing it through Files. If I copy the file from iOS to Mac then I can pay the video on Mac, but not anymore on iOS. If I delete the app, install again and download the video while UIFileSharingEnabled and if it's played in the app it can be played in the Files app, but again after some time it's not playable again... I can see only first frame. I can even see the length of video. It happens to multiple videos. Any clues?
3
0
545
Jan ’24
Cannot modify files outside my iOS app's sandbox. Permissions issue.
I'm developing an iOS app (latest Swift, iOS, Xcode versions atm of writing) which needs to rename audio files (and later modify its metadata) located anywhere (local storage, external storage, cloud, etc). I'm bringing my own question in StackOverflow but I'd like to know better from the source so I came here. The trouble comes when testing on a physical device while trying to rename a file in some folder On My iPhone, the app does as intended when testing on the Simulator. On my physical iPhone I get an error logged saying that I don't have the permissions to do that. “filename.mp3” couldn’t be moved because you don’t have permission to access “randomFolder". I did my googling and asked GPTs about it, learned about FileCoordinator, UIDocumentPickerViewController⁠, startAccessingSecurityScopedResource. I also saw a couple of videos that I cannot reference in this forum. Some code I have in place: This is the document picker which I then call from a .sheet on another View. struct DocumentPicker: UIViewControllerRepresentable { @Binding var newName: String @EnvironmentObject private var bookmarkController: BookmarkController func makeUIViewController(context: Context) -> UIDocumentPickerViewController { let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: supportedTypes) documentPicker.delegate = context.coordinator return documentPicker } func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) { print("updateUIViewController documentPicker") } func makeCoordinator() -> Coordinator { Coordinator(self, newName) } class Coordinator: NSObject, UIDocumentPickerDelegate { var parent: DocumentPicker var newName: String init(_ parent: DocumentPicker, _ newName: String = "") { self.parent = parent self.newName = newName } func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { // save bookmark print("documentPicker \(urls[0])") parent.bookmarkController.addBookmark(for: urls[0]) // Rename the file var error: NSError? NSFileCoordinator().coordinate(readingItemAt: urls[0], options: [], error: &error) { coordinatedURL in do { // let data = try Data(contentsOf: newURL) print("urls[0]: \(urls[0])") print("coordinatedURL: \(coordinatedURL)") print("renamedURL: \(newName)") try renameFile(at: coordinatedURL, to: newName) } catch { print("Error: \(error.localizedDescription)") } } } } } Renaming function: /// Rename selected file from browser func renameFile(at fileURL: URL, to newName: String) throws { let fileExtension = fileURL.pathExtension let directory = fileURL.deletingLastPathComponent() // Create a new URL with the updated name and the original extension let renamedURL = directory.appendingPathComponent(newName).appendingPathExtension(fileExtension) try FileManager.default.moveItem(at: fileURL, to: renamedURL) } I have a BookmarkController in place so that my URLs are bookmarked for later use. Here it is: import SwiftUI import MobileCoreServices class BookmarkController: ObservableObject { @Published var urls: [URL] = [] init() { loadAllBookmarks() } func addBookmark(for url: URL) { print("adding bookmark for \(url)") do { guard url.startAccessingSecurityScopedResource() else { print("Failed to obtain access to the security-scoped resource.") return } defer { url.stopAccessingSecurityScopedResource() } let bookmarkData = try url.bookmarkData(options: .minimalBookmark, includingResourceValuesForKeys: nil) let uuid = UUID().uuidString try bookmarkData.write(to: getAppSandboxDir().appendingPathComponent(uuid)) urls.append(url) } catch { print("Error Adding Bookmark: \(error.localizedDescription)") } } func loadAllBookmarks() { // Get all the bookmark files let files = try? FileManager.default.contentsOfDirectory(at: getAppSandboxDir(), includingPropertiesForKeys: nil) // Map over the bookmark files self.urls = files?.compactMap { file in do { let bookmarkData = try Data(contentsOf: file) var isStale = false // Get the URL from each bookmark let url = try URL(resolvingBookmarkData: bookmarkData, bookmarkDataIsStale: &isStale) guard !isStale else { // Handle stale bookmarks return nil } print("loaded bookmark: \(url)") // Return URL return url } catch { print("Error Loading Bookmark: \(error.localizedDescription)") return nil } } ?? [] } private func getAppSandboxDir() -> URL { // TODO ver 0 index FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] } } When running on my device, I see url.startAccessingSecurityScopedResource throwing: Failed to obtain access to the security-scoped resource. I have also tried getting access to the parent directory like this: let parentURL = url.deletingLastPathComponent() and then using parentURL instead, but it also fails. Something I noticed is that my app is not shown in the Settings -> Privacy & Security -> Files and Folders list. My app didn't trigger any dialog to be added here given user consent. Fiddling with entitlements in Info.plist and Capabilities did not help either, but I'm not so sure about which ones should I add. So: Could it be that the problem I'm seeing about permissions and my app not appearing at the Files and Folders privacy settings on my iPhone are because my app is signed with a developer account which is not in the apple developer program? this is my last thought since I'm not understanding what else should I try. Any pointers and help will be much appreciated. Thanks!
3
0
603
Jan ’24
Why is fcopyfile faster than copyfile?
In my previous post I asked why copyfile is slower than the cp Terminal command. In this other post I asked how I can make copyfile faster by changing the block size. Now I discovered that the cp implementation on macOS is open source and that when copying regular files it doesn't use copyfile but fcopyfile. In a test I noticed that fcopyfile by default seems to be faster than copyfile. When copying a 7 GB file I get about the same results I observed when comparing filecopy to cp: copyfile: 4.70 s fcopyfile: 3.44 s When setting a block size of 16_777_216, copyfile becomes faster than fcopyfile: copyfile: 3.20 s fcopyfile: 3.53 s Is this expected and why is it so? I would have expected that they both have the same performance, and when changing the block size they would still have the same performance. Here is the test code. Change #if true to #if false to switch from fcopyfile to copyfile: import Foundation import System let source = "/path/to/source" let destination = "/path/to/destination" #if true let state = copyfile_state_alloc() defer { copyfile_state_free(state) } //var bsize = 16_777_216 //copyfile_state_set(state, UInt32(COPYFILE_STATE_BSIZE), &bsize) let sourceFd = try! FileDescriptor.open(source, .readOnly) let destinationFd = try! FileDescriptor.open(destination, .writeOnly) if fcopyfile(sourceFd.rawValue, destinationFd.rawValue, state, copyfile_flags_t(COPYFILE_ALL | COPYFILE_NOFOLLOW | COPYFILE_EXCL | COPYFILE_UNLINK)) != 0 { print(NSError(domain: NSPOSIXErrorDomain, code: Int(errno))) } try! sourceFd.close() try! destinationFd.close() #else source.withCString { sourcePath in destination.withCString { destinationPath in let state = copyfile_state_alloc() defer { copyfile_state_free(state) } // var bsize = 16_777_216 // copyfile_state_set(state, UInt32(COPYFILE_STATE_BSIZE), &bsize) if copyfile(sourcePath, destinationPath, state, copyfile_flags_t(COPYFILE_ALL | COPYFILE_NOFOLLOW | COPYFILE_EXCL | COPYFILE_UNLINK)) != 0 { print(NSError(domain: NSPOSIXErrorDomain, code: Int(errno))) } } } #endif
0
0
384
Jan ’24
iOS app local storage persistency when updating app (Xamarin -> Flutter)
Currently in our published version of iOS app (built in Xamarin.Forms) we are storing some local data (settings etc.) as json and other files in the device. We are planning to do a major update when we re-create the whole app using Flutter. My question is: As long as bundle ID will be the same for the Flutter build as was for the Xamarin.Forms build and the app version of the Flutter build will be higher (than the previously one) will the update in the App Store will act just as a regular update of the app (so the user will theoretically even not notice that the newer version was built with different approach)? Will the update keep or delete the local files stored by the previous version of the app? Even that the older version is build of the Xamarin.Forms and the newer one will be build of the Flutter? Of course the Flutter version will direct to same paths and files as the previous Xamarin version. The files are stored in paths: /var/mobile/Containers/Data/Application//Library/MyApp/ e.g.: .../Library/MyApp/settings.json .../Library/MyApp/Media/caches.json .../Library/MyApp/Media/Settings/settings.json ... etc. Some settings are also stored in .plist NSUserDefaults.StandardUserDefaults as key/value pairs. Is there any official documentation about those 2 my questions? So far I have only found some info about bundle ID in general but no article directly answered me those 2 questions (mentioned above).
2
0
892
Jan ’24
Uninstall FortiClient using a script on macOS
Hi all, I'm trying to uninstall FortiClient on macbook with M1/M2 processor using a script from this article: https://community.fortinet.com/t5/FortiClient/Technical-Tip-Uninstall-FortiClient-using-a-script-on-... I only added two lines to change flags. Here is my script: #!/bin/sh # Uninstall FortiClient.sh pkill FortiClient pkill FortiClientAgent pkill FctMiscAg launchctl unload /Library/LaunchDaemons/com.fortinet* chflags -hv noschg /Applications/FortiClient.app chflags -hv noschg /Applications/FortiClientUninstaller.app rm -Rfv /Applications/FortiClient.app rm -Rfv /Applications/FortiClientUninstaller.app rm -Rfv /Library/Application\ Support/Fortinet rm -Rfv /Library/Internet\ Plug-Ins FortiClient_SSLVPN_Plugin.bundle rm -Rfv '/Library/LaunchDaemons/com.fortinet.forticlient.vpn.plist' rm -Rfv '/Library/LaunchDaemons/com.fortinet.forticlient.wf.plist' rm -Rfv '/Library/LaunchDaemons/com.fortinet.forticlient.fmon.plist' rm -Rfv '/Library/LaunchDaemons/com.fortinet.forticlient.epctrl.plist' rm -Rfv '/Library/LaunchDaemons/com.fortinet.forticlient.appfw.plist' rm -Rfv '/Library/LaunchDaemons/com.fortinet.forticlient.fssoagent_launchdaemon.plist' localAccounts=$(dscl . list /Users UniqueID | awk '$2 > 500 { print $1 }') for user in $localAccounts ; do rm -Rfv /Users/"$user"/Library/Application\ Support/Fortinet/ done But I got error that deleting FortiClient.app and FortiClient.app\Content is not permitted, because application is locked. At this time, FortiClientUninstaller.app has been deleted successfully: chflags: /Applications/FortiClient.app: Operation not permitted /Applications/FortiClientUninstaller.app and rm -Rfv /Applications/FortiClient.app rm: /Applications/FortiClient.app/Contents: Operation not permitted rm: /Applications/FortiClient.app: Operation not permitted Could someone help me with this issue, please? I need to uninstall FortiClient using a script via MDM on multiply devices
1
0
632
Jan ’24
Combating `kFSEventStreamEventFlagMustScanSubDirs`
Hello! In our application we use FSEventStream to track the file system changes, this is required to keep up-to-date cached view on the file system and manage auxiliary state like indices. To get support for tracking symlinks that may point outside of the directory of interest, we have set up an FSEventStream that is watching the root ('/') of the file system. Now, the issue is, the application receives a significant amount of MustScanSubDirs events with the UserDropped flag raised, which creates a non-trivial load on the system by our application as we need to check if all the auxiliary state is still adequate. Tangentially, it was noted that the count of these events is higher on Apple Silicon systems in comparison to the older generation Intel MacBooks. The MustScanSubDirs events inevitably come en masse during a high file system load, which is not surprising by itself, but we are looking for a way to reduce the count. Interestingly, in some cases we have observed a steady stream of such events even after our load test which creates/deletes files would complete, for at least several minutes after. What we have tried: Given it has the UserDropped flag, which indicates that our application cannot keep up with the stream, we have completely removed any work from the event processing callback, reducing it to an event counter increment. For the same reason as above, set the priority of the thread that backs the processing run loop to soft real-time. Instruments' System Trace showed that now our thread is always scheduled within several microseconds after it was awaken by fseventsd and was never preempted. Use DispatchQueue instead of the deprecated RunLoop combination with FSEventStream. The expectation was that it would reduce context switches. Experimented with serial and concurrent dispatch queues with high QoS. Reduce the scope down to the directory of interest instead of watching the file system root. Different combinations of kFSEventStreamCreateFlag* flags with different values of the latency parameter (from 0 to 5 seconds). Recreate the FSEventStream after a MustScanSubDirs event, starting at the event ID directly preceding it (the last non-dropped event). The expectation was that reading from the event log would allow to bypass the "keep up" requirements. None of that helped to definitively lower the count of MustScanSubDirs events. What's worse, as mentioned above, even after the load test would complete, occasionally, we'd continue to receive such events for a while after, without our test generating any load, and judging from the count of events in total during that period, no other application was creating a massive load either. So far we have only observed that when watching the file system root. The (6) somewhat helps with the issue, recreating the stream can allow our application to proceed further at some point, without generating a new MustScanSubDirs event following the last successfully read event, but it also has drawbacks, as the application can "stuck" for a longer periods of time (30-60 seconds) recreating the stream at the same event ID and repeatedly receiving MustScanSubDirs event immediately. Eventually it would get through that event (hopefully without losing anything in the process) and will start receiving new events again. Although, it will very soon encounter the next MustScanSubDirs event and can stuck on it, too. In the end, we're looking for the answer to the following questions: How exactly FSEventStream decides that MustScanSubDirs should be sent? Why do we get UserDropped events even if our application seemingly can keep up with the stream of events? Are there any other knobs that can help with reducing the count of such events? Is it possible to somehow increase buffers or affect fseventsd in some other way to help our application to "keep up"? Or can we do something on the application side? Is there any other API that doesn't require root privileges to reliably track file system events? We are aware of kqueue, but it doesn't suit well as it requires to set up a watch for every individual subdirectory and/or file and can easily max out the count of permitted open file descriptors. What has changed with the Apple Silicon to increase the count of such events? The assumption was the heterogeneous cores and changes to the scheduling procedure, but we still receive a lot even with real-time threads. Thanks!
0
0
251
Jan ’24
Share Extension can access files from the Photos app but not the Files app
Share Extension can access files from the Photos app but not the Files app. In case of the Photos app the file url is something like file:///var/mobile/... In case of the Files app the url stars with file:///private/var/mobile/... The following error is thrown in case of the Files app Error Domain=NSCocoaErrorDomain Code=260 "The file “file.pdf” couldn’t be opened because there is no such file." However the file is there, it was selected via the Files app and the share button was used to launch the Share Extension. Also the access to the file is within the following block url.startAccessingSecurityScopedResource() ... url.stopAccessingSecurityScopedResource() Another issue is that the Share Extension does not appear in the Settings / Privacy / Files and Folders. Here are the apps which have the "Applications that have requested access to files and folders will appear here". What is the solution to allow the Share extension access the files from the Files app ?
0
0
411
Jan ’24
ShareSheet failing but only for US users
I have an app that shares a text file using the iOS ShareSheet. This app has functioned as intended until the release of iOS17 but I now have reports of zero length files ... but only from users based in the US! I have test reports from UK and Europe that show no issues. I have tested the original implementation, that uses UIDocumentInteractionController, and alternatives such as UIActivityViewController e.g.: UIActivityViewController* avc = [[UIActivityViewController alloc] initWithActivityItems:@[self.temporaryURL] applicationActivities:nil]; [self presentViewController:avc animated:YES completion:^{ }]; Like many reports on the forums, there are a lot of errors (from the Sharing library) in the console such as: Failed to request default share mode for fileURL:file:///private/var/mobile/Containers/Data/Application.... or Only support loading options for CKShare and SWY types. But in my testing the file shares without problems. The file to be shared is located in the NSTemporaryDirectory() Has anyone else seen this strange behaviour? If so, does anyone know how to fix it?
3
0
1.1k
Jan ’24
Determine the original network volume name in case it's been renamed automatically due to a name conflict
On macOS, if I mount two volumes whose name is the same, the second one gets renamed, by appending "-1" to its name. I need a method to determine the original volume name, i.e. without such a suffix. (Of course, I cannot blindly remove any "-" plus digits because the volume may actually be named like this.) I can find the original name when using the mount command in Terminal: //tt@192.168.61.121/NAS2 on /Volumes/NAS2 (smbfs, nodev, nosuid, mounted by tt) //tt@QNAS%28AFP%29._afpovertcp._tcp.local/NAS2 on /Volumes/NAS2-1 (afpfs, nodev, nosuid, mounted by tt) Here, I can tell that "/Volumes/NAS2-1" was originally named "NAS2" on the network. How do I determine the share's name without invoking such tools, but via CF or other macOS functions, with providing the path or URL of the mounted volume (such as "/Volumes/NAS2-1")?
1
0
347
Jan ’24
Determine the user name that was used to login to a network server
When using the mount command on macOS, I can see mounted network servers like this: //tt@mynas.local/NAS on /Volumes/NAS (smbfs, nodev, nosuid, mounted by thomas) In this example "thomas" is my macOS user name, under which I mounted the "NAS" volume. But there's also the "tt" name before the "@" - and that's what I'm interested in getting - that's the user name known to the server, i.e. the name I logged in on the server when the connection prompt appeared. How do I get this name (tt) via macOS APIs? I can get it via "mount", but that requires parsing and is inefficient, and so I like to avoid that if possible. man mount mentions getfsent(), but in my testing it only lists internal volumes, not network volumes.
2
0
444
Feb ’24
Troubleshooting Custom File Extension Recognition in iOS 17 with AirDrop and UIDocumentPickerViewController
Since the release of iOS 17, my application is no longer recognized as the default option for opening my custom file extension via AirDrop. I understand that Apple has modified AirDrop functionality to integrate more closely with the Files app. However, within the Files app, my file package is erroneously identified as a folder, thus ignoring my specified file extension. Additionally, my attempts to utilize UIDocumentPickerViewController for opening these files have been unsuccessful, as it fails to recognize the file type. I have explored various approaches with UIDocumentPickerViewController, including the following implementation: let importCustomFiles = UIAlertAction(title: "Import custom file", style: .default) { _ in let myExtensionType = UTType(filenameExtension: "MyExtension")! let pickerViewController = UIDocumentPickerViewController(forOpeningContentTypes: [myExtensionType]) pickerViewController.delegate = self pickerViewController.allowsMultipleSelection = false pickerViewController.shouldShowFileExtensions = true self.present(pickerViewController, animated: true, completion: nil) } Below is an excerpt from my Info.plist file, detailing the relevant configurations for my custom file extension: <!-- MyExtension Document Type --> <key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeIconFiles</key> <array> <string>MyApp File Icon</string> </array> <key>CFBundleTypeName</key> <string>Angles MyExtension</string> <key>LSHandlerRank</key> <string>Default</string> <key>LSItemContentTypes</key> <array> <string>au.com.mycompany.myapp.MyExtension</string> </array> <key>LSTypeIsPackage</key> <true/> </dict> </array> <!-- Exported Type Declaration for MyExtension --> <key>UTExportedTypeDeclarations</key> <array> <dict> <key>UTTypeConformsTo</key> <array> <string>public.directory</string> </array> <key>UTTypeDescription</key> <string>Custom file extension for MyExtension files</string> <key>UTTypeIconFiles</key> <array> <string>MyApp File Icon</string> </array> <key>UTTypeIdentifier</key> <string>au.com.mycompany.myapp.MyExtension</string> <key>UTTypeTagSpecification</key> <dict> <key>public.filename-extension</key> <array> <string>myextension</string> </array> </dict> </dict> </array> <!-- Imported Type Declaration for MyExtension --> <key>UTImportedTypeDeclarations</key> <array> <dict> <key>UTTypeConformsTo</key> <array> <string>public.directory</string> </array> <key>UTTypeDescription</key> <string>Custom file extension for MyExtension files</string> <key>UTTypeIdentifier</key> <string>au.com.mycompany.myapp.MyExtension</string> <key>UTTypeTagSpecification</key> <dict> <key>public.filename-extension</key> <array> <string>myextension</string> </array> </dict> </dict> </array> I am seeking assistance in resolving this issue so that my application can properly recognize and open files with my custom extension, both via AirDrop and within the Files app. Any insights or suggestions would be greatly appreciated.
1
0
499
Jan ’24
How do I prevent my app's folders or files from being displayed or searched in the Files app?
How do I prevent my app's folders or files from being displayed or searched in the Files app? Currently, the app is set to display internal files and folders in the "Files" app, Apple's default app. Is there a way to turn this on and off within the app code so that our app's files or folders are not searched within the Files app? All files and folders in the Documents path and their subfolders and files are eligible.
1
0
358
Feb ’24
MacOS Sonoma cron job doesn't have access to ~/.Trash even though it has full system access
MacOS Sonoma Version 14.2.1 I am running a python script via crontab, and the script runs, but I get an error when trying to iterate the ~/.Trash directory: PermissionError: [Errno 1] Operation not permitted: '/Users/me/.Trash' I have enabled full disk access for: /usr/sbin/cron, /usr/bin/crontab, and terminal.app, but still have the same problem. If I run the script directly, it works fine, but when cron runs it, I get the error above. ~/.Trash is the only directory that I've found to have problems with. I've tried both using absolute path and relative to my home directory . I have tried a few different crontab entries, but get the same result from all of them (I've ran each version directly and each works fine when not ran via cron). */5 * * * * /Users/me/miniforge3/envs/dev/bin/fclean >> /dev/null 2>&1 */5 * * * * /Users/me/miniforge3/envs/dev/bin/python /Users/me/miniforge3/envs/dev/bin/fclean >> /dev/null 2>&1 */5 * * * * /Users/me/miniforge3/envs/dev/bin/python /Users/me/path/to/file.py >> /dev/null 2>&1 if it's helpful the python function that's raising the permission issue is: def clean_folder(folder: Path, _time: int = days(30)) -> None: """ If a file in the specified path hasn't been accessed in the specified days; remove it. Args: folder (Path): Path to folder to iterate through _time (int): optional time parameter to pass as expiration time. Returns: None """ for file in folder.iterdir(): if expired(file, _time): try: rm_files(file) except PermissionError as permission: logging.exception(permission) continue except Exception as _err: logging.exception(_err) continue ``
2
0
700
Feb ’24