我嘗試為我的應用程式分配檔案型別。
在 Info.plist 我添加:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>type</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icon</string>
<key>CFBundleTypeName</key>
<string>My Project</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSTypeIsPackage</key>
<false/>
</dict>
</array>
在 Main.mm 中:
....
-(BOOL) application:(NSApplication *)sender openFile:(NSString *)filename {
NSLog(@"Opened by file");
return YES;
}
@end
int main(int argc, char* argv[]) {
[NSApplication sharedApplication];
[[[[Window alloc] init] autorelease] makeMainWindow];
[NSApp run];
return 0;
}
但是當我嘗試雙擊我的檔案型別時,應用程式只打開警告:無法打開,MyApp 無法以格式打開檔案。此外,根本不呼叫來自 NSLog 的訊息。
uj5u.com熱心網友回復:
您發布的代碼存在幾個問題,但我能夠通過一些修改獲得所需的行為。
我假設這是您的視窗界面和實作:
@interface Window : NSWindow <NSApplicationDelegate>
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
@end
@implementation Window
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename {
NSLog(@"Opened by file");
return YES;
}
@end
將視窗物件用作應用程式委托是非常奇怪的。通常,您有一個控制器物件,它擁有和管理視窗并充當應用程式的委托。
在任何情況下,仍然可以通過將main()函式更改為以下內容來獲得......好吧,功能行為:
int main(int argc, const char * argv[]) {
[NSApplication sharedApplication];
Window *window = [[[Window alloc] init] autorelease];
NSApp.delegate = window;
[window makeKeyAndOrderFront:nil];
[NSApp run];
return 0;
}
有兩個顯著的變化。首先,您的問題是您沒有將視窗實體設定為應用程式委托。二、IIRC,千萬不要-makeMainWindow直接呼叫;相反,該方法存在,因此您可以根據需要覆寫它。如果要在螢屏上顯示視窗,請呼叫-makeKeyAndOrderFront:。
打開檔案應該會在控制臺中顯示記錄的行(如果您使用的是 Xcode 12.5.1,如果需要解決顯示錯誤,請調整日志視窗的大小)。
在手動參考計數下,我相信這會泄漏記憶體,因為沒有創建自動釋放池,但我沒有在控制臺中看到任何常見的警告。無論如何,雖然此代碼有效,但會導致相當不理想的情況。應用程式中沒有主選單,因此要退出它,您必須使用 Dock。創建的視窗也很小,沒有調整大小等功能。
uj5u.com熱心網友回復:
NSWindow 的以下子類應該允許您使用唯一的“.jaf”擴展名保存檔案,然后通過雙擊將檔案重新打開到應用程式中。info.plist 并不像我最初想象的那么重要;我沒有改變由 Xcode 創建的那個。對于這個非基于檔案的應用程式來說,最重要的似乎是呼叫 NSApplicationDelegate 方法 -(BOOL) 應用程式:openFile。NSApplicationDelegate 被添加到 NSWindow 子類中,而不是像通常那樣有一個單獨的 AppDelegate。正常作業時,雙擊 .jaf 檔案后呼叫此方法時,您應該會聽到蜂鳴聲;我找不到 NSLog 輸出。要在 Xcode 中運行演示,首先創建一個 objc 專案并洗掉“main.m”檔案中的所有內容,然后將以下源代碼復制/粘貼到其中。洗掉預先提供的 AppDelegate 類以避免重復符號。在權利中將 App Sandbox 設定為 NO 并將只讀設定為零。制作 JAF 應用程式后,使用它以“.jaf”擴展名將檔案保存到桌面。然后制作應用程式的副本(顯示在 Finder 中)并將其復制/粘貼到應用程式檔案夾中。下一步很關鍵;右鍵單擊您剛剛創建的檔案,然后使用“獲取資訊”或“打開方式”將檔案設定為始終使用新創建的應用程式打開。此時,您應該能夠雙擊 xxxx.jaf 檔案,并在聽到嗶嗶聲的情況下將其打開到您的應用程式中。然后制作應用程式的副本(顯示在 Finder 中)并將其復制/粘貼到應用程式檔案夾中。下一步很關鍵;右鍵單擊您剛剛創建的檔案,然后使用“獲取資訊”或“打開方式”將檔案設定為始終使用新創建的應用程式打開。此時,您應該能夠雙擊 xxxx.jaf 檔案,并在聽到嗶嗶聲的情況下將其打開到您的應用程式中。然后制作應用程式的副本(顯示在 Finder 中)并將其復制/粘貼到應用程式檔案夾中。下一步很關鍵;右鍵單擊您剛剛創建的檔案,然后使用“獲取資訊”或“打開方式”將檔案設定為始終使用新創建的應用程式打開。此時,您應該能夠雙擊 xxxx.jaf 檔案,并在聽到嗶嗶聲的情況下將其打開到您的應用程式中。
#import <Cocoa/Cocoa.h>
@interface Window : NSWindow <NSApplicationDelegate> {
NSTextView *txtView;
}
- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)style backing:(NSBackingStoreType)backingStoreType defer:(BOOL)flag;
-(void) buildMenu;
-(void) openAction;
-(void) saveAction;
@end
@implementation Window
#define _wndW 700
#define _wndH 550
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename {
NSLog(@"This comes from JAF : filename = %@.",filename);
NSBeep(); // Listen for this.
NSError *error;
NSURL *url = [NSURL fileURLWithPath:filename];
NSString *fileStr = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
if (!fileStr) {
NSLog(@"Unable to open file %@", error);
} else {
[txtView setString:fileStr];
}
return YES;
}
-(void) buildMenu {
// **** Menu Bar **** //
NSMenu *menubar = [NSMenu new];
[NSApp setMainMenu:menubar];
// **** App Menu **** //
NSMenuItem *appMenuItem = [NSMenuItem new];
NSMenu *appMenu = [NSMenu new];
[appMenu addItemWithTitle: @"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
[appMenuItem setSubmenu:appMenu];
[menubar addItem:appMenuItem];
}
-(void) openAction {
NSOpenPanel *op = [NSOpenPanel openPanel];
[op setAllowedFileTypes:[NSArray arrayWithObjects: @"jaf", @"txt", nil]];
[op beginSheetModalForWindow: self completionHandler: ^(NSInteger returnCode) {
if (returnCode == NSModalResponseOK) {
NSURL *url = [op URL];
NSError *error;
NSString *fileStr = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
if (!fileStr) {
NSLog(@"Unable to open file %@", error);
} else {
[self->txtView setString:fileStr];
}
}
}];
}
-(void) saveAction {
NSSavePanel *sp = [NSSavePanel savePanel];
[sp setTitle:@"Save contents to file"];
[sp setAllowedFileTypes:[NSArray arrayWithObjects: @"jaf", nil]];
[sp setNameFieldStringValue: @".jaf"];
[sp beginSheetModalForWindow: self completionHandler: ^(NSInteger returnCode) {
if (returnCode == NSModalResponseOK) {
NSURL *url = [sp URL];
NSString *viewStr = [[self->txtView textStorage] string];
NSError *err;
BOOL fileSaved = [viewStr writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:&err];
if (!fileSaved) { NSLog(@"Unable to save file due to error: %@", err);}
}
}];
}
- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)style backing:(NSBackingStoreType)backingStoreType defer:(BOOL)flag {
self = [super initWithContentRect:NSMakeRect(0, 0, _wndW, _wndH) styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:NO];
[self setTitle: @"Test window"];
[self center];
[self makeKeyAndOrderFront: nil];
// ****** NSTextView with Scroll ****** //
NSScrollView *scrlView = [[NSScrollView alloc] initWithFrame:NSMakeRect( 10, 10, _wndW - 20, _wndH - 80 )];
[[self contentView] addSubview:scrlView];
[scrlView setHasVerticalScroller: YES];
[scrlView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
txtView = [[NSTextView alloc] initWithFrame:NSMakeRect( 0, 0, _wndW - 20, _wndH - 80 )];
[scrlView setDocumentView: txtView];
// **** Open Button **** //
NSButton *openBtn =[[NSButton alloc]initWithFrame:NSMakeRect( 30, _wndH - 50, 95, 30 )];
[openBtn setBezelStyle:NSBezelStyleRounded ];
[openBtn setTitle: @"Open"];
[openBtn setAutoresizingMask: NSViewMinYMargin];
[openBtn setAction: @selector (openAction)];
[[self contentView] addSubview: openBtn];
// **** Save Button **** //
NSButton *saveBtn =[[NSButton alloc]initWithFrame:NSMakeRect( 130, _wndH - 50, 95, 30 )];
[saveBtn setBezelStyle:NSBezelStyleRounded ];
[saveBtn setTitle: @"Save"];
[saveBtn setAutoresizingMask: NSViewMinYMargin];
[saveBtn setAction: @selector (saveAction)];
[[self contentView] addSubview: saveBtn];
return self;
}
- (BOOL)windowShouldClose:(id)sender {
[NSApp terminate:sender];
return YES;
}
@end
int main() {
NSApplication *application = [NSApplication sharedApplication];
Window *window = [[Window alloc]init];
[window buildMenu];
[application setDelegate:window];
[application activateIgnoringOtherApps:YES];
[NSApp run];
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/336724.html
上一篇:目標c中自定義類的初始化錯誤
