Golang + cgo - AppDelegate 实现不起作用
Golang + cgo - AppDelegate implementation doesn't work
我想用 go 编写一个能够在 MacOS 上打开自定义文件类型 (.slc) 的应用程序。我创建了一个空白的 xcode 项目来获取所有必要的代码,并通过 cgo 将其实现到我的应用程序中。当我双击一个文件时,应用程序打开但抱怨它无法打开这种格式的文件:
这是我的 Info.plist:
执行如下:
/surge/appDelegate_darwin.go
package surge
//#cgo CFLAGS: -x objective-c
//#cgo LDFLAGS: -framework Cocoa
//#include "appDelegate_darwin.h"
import "C"
/surge/appDelegate_darwin.h
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@end
/surge/appDelegate_darwin.m
#include "appDelegate_darwin.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
-(BOOL)application:(NSApplication *)sender openFile:(NSString *)filename
{
NSLog(@"%@", filename);
YES;
}
-(void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
{
NSLog(@"%@", filenames);
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
@end
其他信息:我使用 wails 框架 (https://wails.app) 向应用程序添加一个不错的 vue.js 前端,并使用内置的 wails build
命令。
cgo 和 objective-c 中的其他实现(如自定义协议处理程序)有效。
经过几个不眠之夜,我通过调查和了解常规 mac 应用程序的结构找到了自己的解决方案。
除了实现 AppDelegate
之外,还需要实现 Document
和一些额外的功能才能获得它 运行。这是我的
/surge/appDelegate_darwin.h
#import <Cocoa/Cocoa.h>
extern void HandleFile(char *);
@interface AppDelegate : NSObject <NSApplicationDelegate>
@end
@interface Document : NSDocument
@end
/surge/appDelegate_darwin.m
#include "appDelegate_darwin.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
-(BOOL)application:(NSApplication *)sender openFile:(NSString *)filename
{
YES;
}
-(void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
{
NSLog(@"%@", filenames);
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
@end
@interface Document ()
@end
@implementation Document
- (instancetype)init {
self = [super init];
if (self) {
// Add your subclass-specific initialization here.
}
return self;
}
+ (BOOL)autosavesInPlace {
return YES;
}
- (NSString *)windowNibName {
// Override returning the nib file name of the document
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return @"Document";
}
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
// Insert code here to write your document to data of the specified type. If outError != NULL, ensure that you create and set an appropriate error if you return nil.
// Alternatively, you could remove this method and override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
[NSException raise:@"UnimplementedMethod" format:@"%@ is unimplemented", NSStringFromSelector(_cmd)];
return nil;
}
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError {
NSData *dataFromFile = [data retain];
NSString *myString = [[NSString alloc] initWithData:dataFromFile encoding:NSUTF8StringEncoding];
// This is the place where the magic happens. In my case I just call the HandleFile-function to process the file contents in my main go app
NSLog(@"Data received: %@", myString);
HandleFile([myString UTF8String]);
return YES;
}
@end
我希望有人觉得这有用!
我想用 go 编写一个能够在 MacOS 上打开自定义文件类型 (.slc) 的应用程序。我创建了一个空白的 xcode 项目来获取所有必要的代码,并通过 cgo 将其实现到我的应用程序中。当我双击一个文件时,应用程序打开但抱怨它无法打开这种格式的文件:
这是我的 Info.plist:
执行如下:
/surge/appDelegate_darwin.go
package surge
//#cgo CFLAGS: -x objective-c
//#cgo LDFLAGS: -framework Cocoa
//#include "appDelegate_darwin.h"
import "C"
/surge/appDelegate_darwin.h
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@end
/surge/appDelegate_darwin.m
#include "appDelegate_darwin.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
-(BOOL)application:(NSApplication *)sender openFile:(NSString *)filename
{
NSLog(@"%@", filename);
YES;
}
-(void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
{
NSLog(@"%@", filenames);
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
@end
其他信息:我使用 wails 框架 (https://wails.app) 向应用程序添加一个不错的 vue.js 前端,并使用内置的 wails build
命令。
cgo 和 objective-c 中的其他实现(如自定义协议处理程序)有效。
经过几个不眠之夜,我通过调查和了解常规 mac 应用程序的结构找到了自己的解决方案。
除了实现 AppDelegate
之外,还需要实现 Document
和一些额外的功能才能获得它 运行。这是我的
/surge/appDelegate_darwin.h
#import <Cocoa/Cocoa.h>
extern void HandleFile(char *);
@interface AppDelegate : NSObject <NSApplicationDelegate>
@end
@interface Document : NSDocument
@end
/surge/appDelegate_darwin.m
#include "appDelegate_darwin.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
-(BOOL)application:(NSApplication *)sender openFile:(NSString *)filename
{
YES;
}
-(void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
{
NSLog(@"%@", filenames);
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
@end
@interface Document ()
@end
@implementation Document
- (instancetype)init {
self = [super init];
if (self) {
// Add your subclass-specific initialization here.
}
return self;
}
+ (BOOL)autosavesInPlace {
return YES;
}
- (NSString *)windowNibName {
// Override returning the nib file name of the document
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return @"Document";
}
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
// Insert code here to write your document to data of the specified type. If outError != NULL, ensure that you create and set an appropriate error if you return nil.
// Alternatively, you could remove this method and override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.
[NSException raise:@"UnimplementedMethod" format:@"%@ is unimplemented", NSStringFromSelector(_cmd)];
return nil;
}
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError {
NSData *dataFromFile = [data retain];
NSString *myString = [[NSString alloc] initWithData:dataFromFile encoding:NSUTF8StringEncoding];
// This is the place where the magic happens. In my case I just call the HandleFile-function to process the file contents in my main go app
NSLog(@"Data received: %@", myString);
HandleFile([myString UTF8String]);
return YES;
}
@end
我希望有人觉得这有用!