问题
I've just added iCloud support to an app that I am working on. Its working great, except that when I open the application without a document in focus the iCloud open file dialog appears and I don't want it to!
In my app delegate I have:
- (BOOL) applicationShouldOpenUntitledFile:(NSApplication *)sender
{
[mainWindowController.window makeKeyAndOrderFront:self];
return NO;
}
Which I use to show my own custom window. However now, both the iCloud open file dialog and my own dialog are displayed. Any ideas on how I can get rid of the iCloud dialog?
回答1:
https://developer.apple.com/library/prerelease/content/releasenotes/AppKit/RN-AppKitOlderNotes/index.html
NSDocument Support for iCloud
In 10.8, NSDocument-based applications with a ubiquity-container-identifiers entitlement gain new functionality and UI to facilitate iCloud document management.
When iCloud is enabled and an application is first launched or re-activated and no windows are visible or being restored, instead of creating a new Untitled document, NSDocumentController will display a non-modal open panel showing the user's iCloud library.
...
Applications that do not wish to use these features for any or all of their NSDocument subclasses can override +[NSDocument usesUbiquitousStorage] and return NO. If all of the application's declared NSDocument subclasses return NO from this method, then NSDocumentController will never show the new non-modal open panel.
So if you can give up using the features listed in this release note, return NO
at +[NSDocument usesUbiquitousStorage]
.
I confirmed you can still open/save your file into iCloud storage from the normal dialog.
回答2:
Putting below codes in your App Delegate lets you bypass that iCloud pop up New Document screen. Tested for High Sierra.
-(void)applicationDidFinishLaunching:(NSNotification *)notification
{
// Schedule "Checking whether document exists." into next UI Loop.
// Because document is not restored yet.
// So we don't know what do we have to create new one.
// Opened document can be identified here. (double click document file)
NSInvocationOperation* op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(openNewDocumentIfNeeded) object:nil];
[[NSOperationQueue mainQueue] addOperation: op];
}
-(void)openNewDocumentIfNeeded
{
NSUInteger documentCount = [[[NSDocumentController sharedDocumentController] documents]count];
// Open an untitled document what if there is no document. (restored, opened).
if(documentCount == 0){
[[NSDocumentController sharedDocumentController]openUntitledDocumentAndDisplay:YES error: nil];
}
}
回答3:
- (BOOL) applicationShouldOpenUntitledFile:(NSApplication *)sender
{
[mainWindowController.window makeKeyAndOrderFront:self];
return NO;
}
This part is correct. I've just tested it.
Just make sure your that this class is really your app delegate.
- Make a new class called prefixAppDelegate
- In your
MainMenu.xib
, drag a new object to the side and set it's custom class to the app delegate class - Right click Application and drag from Delegate down to your app delegate object.
- Now just paste the code above into your app delegate class
If that still doesn't help, try logging something in applicationShouldOpenUntitledFile:
.
Also, I recommend not to set [mainWindowController.window makeKeyAndOrderFront:self];
in this method. You should rather use the app delegate method applicationDidFinishLaunching:
method.
回答4:
My observation and fix:
[applicationShouldOpenUntitledFile:] won't be executed except you remove Key NSDocumentClass
from *-info.plist. But this is harmful if your app is document based application, it won't open the document type you linked.
My fix is open my customised window directly in -(void)applicationWillFinishLaunching:(NSNotification *)notification
method (Application delegate)
ETDocumentWindowController *windowController = (ETDocumentWindowController*)get your own window controller here...;
[windowController.window makeKeyAndOrderFront:nil];
回答5:
I thought I would share my solution to this issue as I see others still looking for an answer. Its not a great solution but it does the trick.
- Subclass NSDocumentController and add the following:
+ (void) setCanOpenUntitledDocument: (BOOL) _canOpenUntitledDocument
{
canOpenUntitledDocument = _canOpenUntitledDocument;
} // End of setCanOpenUntitledDocument:
- (void) openDocument: (id) sender
{
// With iCloud enabled, the app keeps trying to run openDocument: on first launch (before apphasfinishedlaunching gets set.
// This method lets us check and see if the app has finished launching or not. If we try to open a document before
// its finished, then don't let it.
if(!canOpenUntitledDocument)
{
return;
} // End of appHasFinishedLaunching not set
[super openDocument: sender];
} // End of openDocument:
Add the following to your app delegate:
- (void) applicationDidFinishLaunching: (NSNotification *) aNotification
{
// Finished launching. Let us open untitled documents.
[SQLProDocumentController setCanOpenUntitledDocument: true];
...
}
And the reasoning -- By setting a breakpoint in openDocument
I've found that its called before applicationDidFinishLaunching
, applicationShouldOpenUntitledFile
or applicationShouldHandleReopen:hasVisibleWindows:
get called, meaning adding those methods is useless. Again, it's not great code but it works and does the trick. (None of the other solutions have worked for me).
回答6:
I ran into a similar problem -- it turned out that in my case, I had to remove the NSDocumentClass
key and value from my Info.plist in the CFBundleDocumentTypes
array. Only then would the applicationShouldOpenUntitledFile:
method get called and thus allow me to prevent the iCloud/Document window from opening.
来源:https://stackoverflow.com/questions/13825228/icloud-enabled-stop-the-open-file-displaying-on-application-launch