Adding optional method of objective-C class to swift extension

626 views Asked by At

To an already extensive Objective-C app I wanted to add Core Data functionality. Recent additions are in Swift, and this worked well, up until now.

Because my Objective-C AppDelegate already contains quite some stuff, I decided to write a Swift extension to AppDelegate. I found that both the Objective-C and Swift parts can live together quite happily, except for the following.

The Core Data stuff I copied from the Swift template of an empty Swift Core Data project.

The problem is with an optional method applicationShouldTerminate: (from the NSApplicationDelegate protocol) which I don't define in the legacy Objective-C part of the class. But the definition in the Swift extension won't compile because the method appears to be doubly defined. Apparently, not mentioning the optional method in the Obj-C source causes a default version to be included.

I tried to implement a dummy applicationShouldTerminate: in Obj-C that calls an applicationShouldterminate2(sender) in Swift, but the Obj-C doesn't see the methods in the extension. Is there a way with e.g. @objc that I can make the symbol visible?

Any hints on how I should proceed?

Important to know is that my Swift extension with the Core Data stuff compiled OK originally. The symbol clash first occurred when I upgraded to XCode 6.3b2 (I think). Before there was no conflict. I am now at XCode 7b1, but still no cigar.

Edit: added source code
File "AppDelegate.h":

#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
{
//stuff for swift extension
  NSPersistentStoreCoordinator *_pSCo;
  NSManagedObjectContext *_mOC;
}
-(NSString *)diag_mOC_descr;
@property (strong) IBOutlet NSPanel *window;
...
#pragma mark for Swift Core Data extension (workaround for iVars)
@property (strong) NSPersistentStoreCoordinator *pSCo;
@property (strong) NSManagedObjectContext *mOC;
@end

File "AppDelegate.m"

#import "AppDelegate.h"
#import "MainWindowController.h"
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { ... }

// allow Core Data in Swift
-(NSString *)diag_mOC_descr { return _mOC.description; } //diag to test whether _mOC is used by property
...
//properties
@synthesize window = _window;
...
// See swift extension for CoreData stuff
@end

AppDelegate+CD.Swift

import Foundation
extension AppDelegate {
  ...
  // MARK: - Core Data stack
  func applicationDocumentsDirectory () -> NSURL  {...}
  ... //all the regular methods from the swift Core Data stuff ending in:
  func applicationShouldTerminate(sender: NSApplication) -> NSApplicationTerminateReply { ...
  }
}

The NSApplicationDelegate protocol has the following definition

SWIFT
optional func applicationShouldTerminate(_ sender: NSApplication) -> NSApplicationTerminateReply
OBJECTIVE-C
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender

Error message:

/Volumes/.../AppDelegate+CD.swift:150:8: Method 'applicationShouldTerminate' with Objective-C selector 'applicationShouldTerminate:' conflicts with previous declaration with the same Objective-C selector

What I think is that since XCode6.3b2 the compiler generates a default "applicationShouldTerminate:" definition, while it didn't before.
My current workaround is to comment out func applictionShouldTerminate {...} altogether (I expect little harm, since I am accessing the CD data read-only -- the CD data is written by another application). However there may be a nicer workaround.

0

There are 0 answers