Post

Replies

Boosts

Views

Activity

NSPopover not showing content on macOS Sonoma
I'm experiencing a weird issue where NSPopover doesn't show content. What's also strange is that when inspecting view in Xcode Debug View Hierarchy, it renders all the views as expected. Here is how the Xcode Debug View Hierarchy looks like: I just don't understand the issue; why is LoginViewController's view not shown. This issue started with macOS Sonoma. Here is the Popover setup: { _popover = NSPopover.new; _popover.animates = NO; _popover.behavior = NSPopoverBehaviorApplicationDefined; NSViewController* vc; if (user == nil) { vc = LoginViewController.new; } else { vc = MessageViewController.new; } _popover.contentViewController = [RootViewController.alloc initWithRootViewController:vc]; [_popover.contentViewController loadView]; _statusItem = [NSStatusBar.systemStatusBar statusItemWithLength:24]; _statusItem.button.action = @selector(onPress); _statusItem.button.target = self; [self reloadPopoverTrayImageForce:YES]; } And here is how Popover's RootViewController is setup. I mean nothing out-of-standard here, just embedding the child view controller and his view to parent's view controller. { self.view = NSView.new; self.view.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:self.containerView]; if (self.rootViewController) { [self addChildViewController:self.rootViewController]; [self.containerView addSubview:self.rootViewController.view]; self.rootViewController.view.translatesAutoresizingMaskIntoConstraints = NO; id r = @{ @"root": self.rootViewController.view }; [self.containerView addFor:r constraints:@"|[root]|"]; [self.containerView addFor:r constraints:@"V:|[root]|"]; } [self.view addSubview:self.footerView]; [self reloadConstraints]; id v = @{ @"container": self.containerView, @"footer": self.footerView }; [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:WIDTH]]; [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:HEIGHT]]; [self.view addFor:v constraints:@"|[container]|"]; [self.view addFor:v constraints:@"|[footer]|"]; [self.view addFor:v constraints:@"V:|[container]-0-[footer(44)]|"]; }
4
1
476
Sep ’23
How to add new NSFileProviderDecorations to FileProviderExtensions
I'm having an issue where adding new decorations to NSFileProviderDecorations doesn't make those decorations visible in the app. Here is my NSFileProviderDecorations array in plist file: <key>NSFileProviderDecorations</key> <array> <dict> <key>BadgeImageType</key> <string>com.apple.icon-decoration.badge.checkmark</string> <key>Category</key> <string>Badge</string> <key>Identifier</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER).iconSynced</string> <key>Label</key> <string>Synced</string> </dict> <dict> <key>BadgeImageType</key> <string>com.apple.icon-decoration.badge.warning</string> <key>Category</key> <string>Badge</string> <key>Identifier</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER).iconConflict</string> <key>Label</key> <string>In Conflict</string> </dict> <dict> <key>BadgeImageType</key> <string>com.apple.icon-decoration.badge.locked</string> <key>Category</key> <string>Badge</string> <key>Identifier</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER).iconLocked</string> <key>Label</key> <string>Locked</string> </dict> <dict> <key>BadgeImageType</key> <string>com.apple.icon-decoration.badge.warning</string> <key>Category</key> <string>Badge</string> <key>Identifier</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER).iconUploadFailed</string> <key>Label</key> <string>Upload failed</string> </dict> </array> The first two decorations: iconSynced and iconConflict work just fine as expected, but then I added the other two decorations: iconLocked and iconUploadFailed and I just can't get them to work. Here is an example of my decorations implementation: var decorations: [NSFileProviderItemDecorationIdentifier]? { [ entry.synced ? "iconSynced" : "", entry.inConflict ? "iconConflict" : "", entry.locked && !entry.uploadFailed ? "iconLocked" : "", entry.uploadFailed ? "iconUploadFailed" : "" ].filter { !$0.isEmpty }.map { NSFileProviderItemDecorationIdentifier(rawValue: "\(Bundle.main.bundleIdentifier!).\($0)") } } What I tried: Clear cache project and/or manually deleting Derived Data folder Various combination changes and log prints to try to figure out what's wrong Increasing Xcode project version Computer restart macOS: 12.6.5 (21G531) Does anyone have the same issue or does anyone have an idea on how to resolve this? So, my problem is that I can't get the new badge decorations added to plist file to work (to be shown in Finder when reported from decorations callback).
1
0
558
Jul ’23
How to prevent writing to file in macOS FileProviderExtension
I'm implementing FileProviderExtension on macOS (NSFileProviderReplicatedExtension) and one requirement I have to support is the support for locked files. My requirement is that writing to locked files should be forbidden. Is there a way to support that in FileProviderExtension? My approach was to report capabilities in FileProviderItem like: var capabilities: NSFileProviderItemCapabilities { if locked { return [.allowsReading, .allowsReparenting, .allowsDeleting] } return [.allowsReading, .allowsWriting, .allowsRenaming, .allowsReparenting, .allowsDeleting] } and indeed rename is forbidden (in Finder you cannot enter rename-state) but writing to file is allowed. Is there a way to prevent writing to file in macOS FileProviderExtension?
1
0
449
Jun ’23
How to prevent folder creation in macOS FileProviderExtension
I need to prevent folder-creation in certain scenarios. I know I can achieve that via NSFileProviderUserInteractions but that only works when folder creation attempt is done via Finder. If however, user tries to create a folder in Terminal via mkdir folder1 then createItem callback does get called. In createItem callback I tried two options: Option 1 func createItem(basedOn itemTemplate: NSFileProviderItem, fields: NSFileProviderItemFields, contents url: URL?, options: NSFileProviderCreateItemOptions = [], request: NSFileProviderRequest, completionHandler: @escaping (NSFileProviderItem?, NSFileProviderItemFields, Bool, Error?) -> Void) -> Progress { let progress = Progress(totalUnitCount: 1) if itemTemplate.parentItemIdentifier == .rootContainer || itemTemplate.contentType == .aliasFile || itemTemplate.contentType == .symbolicLink { print("Preventing item creation in root level") let entry = Entry( id: UUID().uuidString.lowercased(), type: itemTemplate.contentType == .folder ? Entry.Kind.folder : Entry.Kind.file, filename: itemTemplate.filename, parentId: NSFileProviderItemIdentifier.trashContainer.rawValue, contentType: itemTemplate.contentType!, size: itemTemplate.documentSize as! Int, creationDate: itemTemplate.creationDate!!, modificationDate: itemTemplate.contentModificationDate as? Date, lastUsedDate: itemTemplate.lastUsedDate as? Date, fileSystemFlags: itemTemplate.fileSystemFlags?.rawValue ?? 4, version: nil, rootContainerId: nil, archived: false ) let item = FileProviderItem(entry: entry) print("Returning trashed item") completionHandler(item, [], false, nil) return progress } // other code } and indeed when creating folder via Finder (with NSFileProviderUserInteractions disabled), folder appears briefly and disappears immediatelly after that. Option 2 func createItem(basedOn itemTemplate: NSFileProviderItem, fields: NSFileProviderItemFields, contents url: URL?, options: NSFileProviderCreateItemOptions = [], request: NSFileProviderRequest, completionHandler: @escaping (NSFileProviderItem?, NSFileProviderItemFields, Bool, Error?) -> Void) -> Progress { let progress = Progress(totalUnitCount: 1) if itemTemplate.parentItemIdentifier == .rootContainer || itemTemplate.contentType == .aliasFile || itemTemplate.contentType == .symbolicLink { print("Preventing item creation at root level") let error = NSError( domain: NSCocoaErrorDomain, code: NSFeatureUnsupportedError, userInfo: [ NSLocalizedDescriptionKey: "Folder creation is not allowed." ] ) completionHandler(nil, [], false, error) return progress } // other code } The problem is that with both options, when folder is created via Terminal, it stays created. Extension marks the folder with exclamation-mark and attempts to invoke createItem callback a few times before giving up. My goal is to prevent folder-creation in the first place so that when user tries to create folder in Terminal, he can get an error in respond. % mkdir folder1 error: folder creation forbidden Is that possible to achieve with FileProviderExtension?
2
0
599
Jun ’23
macOS FileProvider extension receives SIGTERM when running in Xcode debug session
I'm developing a macOS FileProvider extension and: Run extension in Xcode Leave it for a few minutes (ie 2-3 minutes) and use some other app The extension receives SIGTERM pointing to mach_msg_trap() on main thread. Is this expected or there is something in my code that is causing the crash. Inspecting all the other threads doesn't show anything meaningful. What about in production? Would the macOS automatically kill the extension process if user is not using the FileProvider Extension.
1
0
589
Apr ’23
How to open macOS FileProvider CloudStorage folder programmatically
I have an app with two targets: MainApp FileProvider Extension I would like to be able to open the FileProvider CloudStorage folder in Finder from within the MainApp. So far, I've only be able to achieve that by asking user to select his Home folder via NSOpenPanel, and then persisting security-scoped bookmark data, create symbolicLink in user's home folder and then later in the app: let aliasLocationURL = try URL(resolvingBookmarkData: aliasLocationBookmarkData,                             options: .withSecurityScope,                             relativeTo: nil, bookmarkDataIsStale: &isStale) aliasLocationURL.startAccessingSecurityScopedResource() NSWorkspace.shared.open(aliasURL) aliasLocationURL.stopAccessingSecurityScopedResource() The problem is that if user does not select his Home folder via NSOpenPanel then my app gets an error message: The application “MyApp” does not have permission to open “MyApp-FileProvider.” I can get the path to CloudStorage folder via: let fileProviderFolderURL = try await NSFileProviderManager(for: domain)?.getUserVisibleURL(for: .rootContainer) and it properly states that fileProviderFolderURL is /Users/me/Library/CloudStorage/MyApp-FileProvider but whenever I try to open that path, it results in error.
1
1
890
Feb ’23
How to access files in macOS FileProvider Extension programmatically?
I have a FileProvider app consisting of MainApp and FileProviderExtension. MainApp has a popover which should have features like: Button which opens FileProvider folder List of files being uploaded/download and when user clicks on a file, it should either be opened or shown in Finder in containing folder. How to achieve these in Sandboxed macOS app? I know it's possible because Microsoft's OneDrive app is distributed via AppStore and can perform these features. So far I've been able to create an alias to a FileProvider folder in user's home folder by utilizing NSOpenPanel. I tried opening FileProvider files from MainApp with something like: let url = try! await NSFileProviderManager(for: myDomain)?.getUserVisibleURL(for: fileIdentifier) NSWorkspace.shared.open(url!) but getUserVisibleURL returns nil. Does anyone know how to achieve described functionality?
6
1
2.7k
Nov ’22
macOS FileProviderExtension prevent file creation via NSFileProviderUserInteractions
My FileProviderExtension should allow creating folders in the root level, but not files. Is there a way to achieve that? I tried creating a NSFileProviderUserInteractions entry like <dict> <key>ActivationRule</key> <string>(action == "Create" OR action == "MoveIn" OR action == "CopyIn") AND destinationItem.itemIdentifier == "NSFileProviderRootContainerItemIdentifier"</string> <key>SubInteractions</key> <array> <dict> <key>ActivationRule</key> <string>TRUEPREDICATE</string> <key>Alert</key> <dict> <key>LocalizedRecoveryOptions</key> <dict> <key>Cancel</key> <string>OK</string> </dict> <key>LocalizedSubTitle</key> <string>Files cannot be added to root level.</string> <key>LocalizedTitle</key> <string>Forbidden action</string> <key>RecoveryOptions</key> <dict> <key>Continue</key> <false/> </dict> </dict> </dict> </array> </dict> but this prevents creation of both files and folders in the root level. How to just prevent file creation? Probably relevant: Apple NSFileProviderItem.h states for 'Create': 'Create': creating an item (available in macOS 12.0 and later) The Create action will be evaluated when the user creates a new file or folder in a system Open/Save panel. The sourceItem is the file/folder being created. The only field that is populated for this item is the filename. The type of file/folder, size, etc, are unknown at Create evaluation time. The destinationItem is the directory which the file/folder is being created within. Does this mean that whether it is a file or a folder which is being created is unknown at 'Create' time? I find that quite weird and if that is the case then this cannot be supported?
1
1
963
Oct ’22
No DistributedNotificationCenter.postNotificationName(_:object:userInfo:deliverImmediately:) method available?
When I try: let center = DistributedNotificationCenter.default center.postNotificationName(Notification.Name(rawValue: "SomeName"), object: "SomeString", deliverImmediately: true) I get compiler error: Extra argument 'deliverImmediately' in call. What I'm trying to do is post a distributed notification from FileProvider extension. When I check documentation I see that deliverImmediately parameter exists. Does anyone know what's going on there?
3
0
1.3k
Aug ’22
FileProvider allowsReparenting capability not honored by system
If I don't include the allowsReparenting capability in FileProviderItem capabilities list, the system allows to move the folder to another parent. Example of my capabilities list: var capabilities: NSFileProviderItemCapabilities { [.allowsReading, .allowsWriting, .allowsRenaming, .allowsDeleting] } Expected: when I move the item (ie Folder) in Finder to another location, Finder should present an error that move is not allowed. Actual: even though I didn't include allowsReparenting capability, system still allows to move the item in Finder. Did anyone encounter similar issue. I guess I'll submit a bug report to Apple, but maybe I'm missing something here?
1
0
927
Jul ’22