Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ho to get a reference to appdelegate from Swift in a mixed application (primary language ObjC) to avoid reference loop

First of all I know about this: How do I get a reference to the app delegate in Swift?

Second, what I need to do is to access the appdelegate properties in the Swift side of a mixed app.

Basically,
1- I have a project which is started as an Objective C project. This means AppDelegate is defined in the Objective C side.
2- I have swift code working fine, I have a bridge header and I can reference things form either side on the other side.
3- Here is the problem: To reference the appdelegate in my Swift code I need to #import "AppDelegate.h" in my bridging header. But for other reasons, I also need the AppDelegate.h to import the SWift header ( PROJECT-Swift.h ). This creates a reference loop.

Is there a way to avoid this reference loop? and still access AppDelegate properties?

EDIT: An additional complication that I did not mention in the first edition of the question is that, the AppDelegate property that I want to expose to Swift code, is actually of a Type declared in the Swift side. So I need to declare it in the AppDelegate.h and to be able to do that, I need to import the -Swift.h header in my AppDelegate.h.
To make it more clear:
KB is a public class defined on the Swift side.
AppDelegate has a property like: @property (strong) KB *appkb; I need to get a hold of ((AppDelegate*)UIApplication.SharedApplication()).appkb

like image 525
Ali Avatar asked Jan 09 '23 10:01

Ali


1 Answers

You should import PROJECT-Swift.h in AppDelegate.m, not .h

In AppDelegate.h, you can use "forward declaration" (@class and @protocol) like:

AppDelegate.h:

#import <UIKit/UIKit.h>

@class SwiftClass;
@class KB;
@protocol SwiftProtocol;

@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) id<SwiftProtocol> swifter;
@property (strong, nonatomic) KB *appkb;

-(void)methodReceiveSwiftClass:(SwiftClass *)obj;

//...

@end

AppDelegate.m:

#import "AppDelegate.h"
#import "PROJECT-Swift.h"

@implemetation AppDelegate

//....

@end

PROJECT-Bridging-Header.h

#import "AppDelegate.h"

Any.swift:

@objc public protocol SwiftProtocol {
    // ...
}

@objc public class SwiftClass:NSObject {
    // ...
}

@objc public class KB:NSObject {
    // ...
}

The document says:

To avoid cyclical references, don’t import Swift into an Objective-C header file. Instead, you can forward declare a Swift class to use it in an Objective-C header. Note that you cannot subclass a Swift class in Objective-C.

like image 169
rintaro Avatar answered Jan 27 '23 19:01

rintaro