John
John

Reputation: 31

Using Cocoa NSSavePanel in non-Sandboxed causes Assertion failure

Only in MacOS 10.15, only when trying to save a file twice to the same directory, and only after opening a NSOpenPanel then tap Cancel or Open. My app hangs up with the following stacktrace and the app does not recover, and I had to kill it.

*** Assertion failure in -[NSSavePanel _attachSandboxExtensions:toURL:orURLs:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/AppKit/AppKit- 1894.30.142/Nav.subproj/OpenAndSavePanelRemote/NSVBOpenAndSavePanels.m:711 -[NSSavePanel observeValueForKeyPath:ofObject:change:context:] caught non-fatal NSInternalInconsistencyException 'unexpected class type for sandbox extension string!' with backtrace (

0   CoreFoundation                      0x00007fff2bc5c8ab __exceptionPreprocess + 250
1   libobjc.A.dylib                     0x00007fff61f16805 objc_exception_throw + 48
2   CoreFoundation                      0x00007fff2bc85d10 +[NSException raise:format:arguments:] + 88
3   Foundation                          0x00007fff2e37e241 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
4   AppKit                              0x00007fff297987b2 __53-[NSSavePanel _attachSandboxExtensions:toURL:orURLs:]_block_invoke + 240
5   CoreFoundation                      0x00007fff2bbd4037 __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__ + 7
6   CoreFoundation                      0x00007fff2bbeac36 -[__NSSingleObjectArrayI enumerateObjectsWithOptions:usingBlock:] + 80
7   AppKit                              0x00

Does anybody have the same problem and a solution for this?

This is the code I am using to save the file:

@IBAction func saveAct(_ sender: Any) {
 let savePanel = NSSavePanel()
 defaultPath = UserDefaultUtil.pathDir

 savePanel.directoryURL = URL(fileURLWithPath: defaultPath)
 savePanel.nameFieldStringValue = "export"
 savePanel.allowedFileTypes = ["jpeg"]
 savePanel.accessoryView = accessoryView

 // <--------------- Assertion failure HERE (the beginSheetModal not called) 

 savePanel.beginSheetModel(for: self.view.window!, completionHandler: {(num) -> Void in

      if num == .OK {
           ....
      }else{
           ....
      }
 })

}

Upvotes: 2

Views: 842

Answers (2)

Sharjeel Ayubi
Sharjeel Ayubi

Reputation: 31

Make sure you are assigning directory path in savePanel.directoryURL, not the file path. For example: savePanel.directoryURL should have a value /Users/macbook/Documents/ NOT /Users/macbook/Documents/file.txt

Upvotes: 1

Alisha Mahajan
Alisha Mahajan

Reputation: 11

There are 2 ways of fixing this problem:

  1. Add file extension to your filename while saving. Modify your code to

    savePanel.nameFieldStringValue = "export.jpeg"

  2. Implement NSSavePanelDelegate by setting save panel delegate to self and implement following function:

    func panel(_ sender: Any, validate url: URL) throws { return TRUE; }

Upvotes: 1

Related Questions