UIApplicationDelegate extension in Swift

I have an iOS app written in Objective-C and I want to add an extension for UIApplicationDelegate using Swift. Specifically, I want to add code for the Objective-C method:


- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options;


so that my app can handle an imported file.


In Swift, this method has the signature:


optional func application(_ app: UIApplication, open url: URL, options: [String : AnyObject] = [:]) -> Bool


To simplify the problem and I have created a Single View Application and have added the Swift code:


import Foundation
extension AppDelegate {
     @objc public func application(_ app: UIApplication, open url: URL, options: [String : AnyObject] = [:]) -> Bool {
   
        return true
    }

    @objc public func testMessage() {
        print("Test Message")
    }
}


This code compiles and runs, but does not get called which a file is imported. The MODULE-NAME-swift.h file conatins the following code:


...
@class UIApplication;


@interface AppDelegate (SWIFT_EXTENSION(AppDelegateTest))
- (BOOL)application:(UIApplication * _Nonnull)app open:(NSURL * _Nonnull)url options:(NSDictionary<NSString *, id> * _Nonnull)options;
- (void)testMessage;
@end
...


This does not have the expected Objective-C signature and therefore, I assume is not called when a file is imported. Note that I can call both of these methods from Objective-C code,


If I change the signature in the Swift code to:


    @objc public func application(_ app: UIApplication, openURL url: URL, options: [String : AnyObject] = [:]) -> Bool {
     
        return true
    }


I get a compilation error:


Delegate.swift:13:24: Method 'application(_:openURL:options:)' with Objective-C selector 'application:openURL:options:' conflicts with method 'application(_:open:options:)' with the same Objective-C selector
__ObjC.AppDelegate:20:17: Method 'application(_:open:options:)' declared here


Any help would be appreciated.


David

I have made a simpler example.


First I defined the following Objective-C protocol and changed AppDelegate to adopt it:


@protocol XXXX
@optional
-(void)printMe:(NSString* _Nullable) text;
@end

@interface AppDelegate : UIResponder <UIApplicationDelegate,XXXX>
@property (strong, nonatomic) UIWindow *window;
@end


I then added the function printMe1 to the extension for AppDelegate:


extension AppDelegate {
  
    @objc public func printMe1(_ text: String?) {
        print(text)
    }
}


This compiles and the resulting MODULE-NAME-swift.h files contains the following code:


@interface AppDelegate (SWIFT_EXTENSION(AppDelegateTes
- (void)printMe1:(NSString * _Nullable)text;
@end


The generated signature for printMe1 "matches" that of printMe in the protocol definition.


If I change printMe1 to printMe I get the following compilation errors:


AppDelegate.swift:29:23: Method 'printMe' with Objective-C selector 'printMe:' conflicts with previous declaration with the same Objective-C selector
__ObjC.AppDelegate:99:17: 'printMe' previously declared here


I would have expected the two declarations of printMe in Objective-C to match?


David

Your issue can be easily reproduced, and I can find exactly the same message.


Try modifying the Objective-C header for `AppDelegate` as:

@interface AppDelegate : UIResponder <UIApplicationDelegate>

(Just removing `,XXXX`)

and the extension in Swift:

extension AppDelegate: XXXX {

(Moving the conformance declaration for `XXXX' the the extension.)

and then, see what you get.


I'm not sure whether this is a current limitation of Swift that we need to accept for a while, or it's a sort of bug which should be fixed soon.

Hello, I'm having the exact same issue here, did you find the way to solve it?

Thank you in advance

UIApplicationDelegate extension in Swift
 
 
Q