Want Swift5 and Objective-C to work together

Asked 2 years ago, Updated 2 years ago, 51 views

After creating a bridge header, I was able to confirm that the ObjectiveC method works from swift.

TestProvider.swift

import NetworkExtension
// @objc (TestProvider)
class TestProvider:NEAPPushProvider {
    
    override init() {
        super.init()
    }
    
    // MARK: - NEAppPushProvider Life Cycle
    override func start (completionHandler:@escaping(Error?) - > Void) {
        completionHandler(nil)
    }
    
    override func stop (with reason: NEProviderStopReason, completionHandler: @escaping()->Void) {
        completionHandler()
        NSLog ("end")
    }
}

Bridge Header
TestProvider-Bridging-Header.h

#ifndef TestProvider_Bridging_Header_h
#define TestProvider_Bridging_Header_h

# import "TestObjC.h"

#endif /* TestProvider_Bridging_Header_h*/

Objective-C Header
TestObjC.h

#ifndefTestObjC_h
#define TestObjC_h

#import<Foundation/Foundation.h>

@ interface TestObjC:NSObject
- (void) printTest;

@end

#endif /*TestObjC_h*/

Objective-C Source
TestObjC.mm

#include "TestObjC.h"
※(1)

@implementationTestObjC{
    
}

-(void)printTest{
    NSLog (@"printTest");
    
}
@end

I was able to verify that the printTest string is printed in the console log.
To work with each other, I referred to the following site.

https://qiita.com/edo_m18/items/861d090a5471f4f0eeae

TestProvider.swift

import NetworkExtension
@objc (TestProvider)
class TestProvider:NEAPPushProvider {
    
    override init() {
        super.init()
    }
    
    // MARK: - NEAppPushProvider Life Cycle
    override func start (completionHandler:@escaping(Error?) - > Void) {
        completionHandler(nil)
    }
    
    override func stop (with reason: NEProviderStopReason, completionHandler: @escaping()->Void) {
        completionHandler()
        NSLog ("end")
    }

    // have a factory method defined
    class func create() - > TestProvider {
        return TestProvider()
    }
    @objc func doMethod()->(){
        NSLog ("start")
    }
}

As I was able to build it, I added the code to Objective-C side, but when I couldn't find the test, I got an error.
  
TestObjC.mm

#include "TestObjC.h"

@implementationTestObjC{

}

-(void)printTest{
    NSLog (@"printTest");
    TestProvider* test=[TestProvider create]; ※

}
@end

The following error will appear in two TestProvider locations in の

Unknown type name 'TestProvider'
I'm worried about how to make it work together.
If you have any good advice, please let me know.

# As you pointed out, the code was incorrect, so I corrected it

Next, I put #import "TestProvider-Swift.h" in ((1) on the TestObjC.mm side, and the following warning came out:

SWIFT_CLASS("_TtC17TestProvider17TestProvider")
@interface Test: NEAppPushProvider 11
- (nonnull instance type) init OBJC_DESIGNATED_INITIALIZER;
- (void) startWithCompletionHandler: (void(^_Nonnull)(NSError*_Nullable)) completionHandler;
- (void) stopWithReason: (NEProviderStopReason) reason completionHandler: (void(^_Nonnull)(void)) completionHandler; 22
- (void) doMethod;
@end

1
in one place annCannot find interface declaration for 'NEAppPushProvider', superclass of 'TestProvider'
2
in two places tExpected a type ]
There was an error.

I feel that NEAPP PushProvider, which is inherited by TestProvider.swift, is being scolded because of the different types of Swift and ObjectiveC, but I am worried about how to link them together.
If you have any good advice, please let me know.

swift objective-c swift5

2022-09-29 21:56

1 Answers

Thank you for correcting your question.When I tried the latest Xcode 12.5, I found that the contents of the description and the events that occurred almost matched (*), so I am writing a reply.

(*The @interface section of TestProvider-Swift.h should be @interfaceTest instead of @interfaceTest.)

I put #import "TestProvider-Swift.h" in ((1) on the TestObjC.mm side

Use Swift's code Put it in Objective-C's code You can write the import of the Swift header in that location (after other import/include on the implementation file side).

1
in one place annCannot find interface declaration for 'NEAPPushProvider', superclass of 'TestProvider'

Usually, it is OK to import the header to the above location, but as you asked, the Objective-C++ file does not enable the @importNetworkExtension; part of the header, and the error appears to be as described.Add your own relevant import

TestObjC.mm

#include "TestObjC.h"
#import<NetworkExtension/NetworkExtension.h>//<-
# import "TestProvider - Swift.h"

//...

(There seems to be no particular part that uses the C++ function, but is there any part that you want to compile as Objective-C++ on purpose?)

Also, you have to add @objc to all Swift method properties that you want to use from Objective-C.

TestProvider.swift

//...
    @objc class func create() - > Test {//<-
        return Test()
    }
//...

Also, it seems that there are some bugs in the current Xcode, and if there is an error in some of the Swift headers, the error may not disappear even if the build is successful by adding import.If Build Succeeded appears, there is no problem, so please ignore it.
(I didn't know for sure how to erase it, but it disappeared before I knew it.)


2022-09-29 21:56

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.