Trying to get ObjC app project to call Swift function within ObjC static lib……….
My ObjC app project build gets build error for reference to a Swift function that is within an ObjC static lib (.a) that is imported into the app project.
The file Hub_lib-Bridging-Header.h has no code.
OBJ-C APP PROJECT……………………………………….
ViewController.mm within the ObjC app project…
#import "ViewController.h"
#import "Hub_lib.h"
#import "Hub_lib-Swift.h"
#import "hublib.hpp"
@interface ViewController ()
@end
@implementation ViewController
. . .
- (IBAction)run_simple_central:(id)sender {
[self BLE.start_central];
}
BLE.h within ObjC app project………..
#import <CoreBluetooth/CoreBluetooth.h>
#import "Hub_lib-Swift.h"
@interface BLE: NSObject
//< CBPeripheralManagerDelegate >
@property(strong, nonatomic) CBPeripheralManager* peripheralManager;
@property(strong, nonatomic) CBMutableCharacteristic* transferCharacteristic;
@property(strong, nonatomic) NSData* dataToSend;
@property(nonatomic, readwrite) NSInteger sendDataIndex;
-(void)start_central;
@end /* BLE_h */
BLE.m within app; a wrapper for call to swift……………………..
#import "BLE.h"
#import "Hub_lib-Swift.h"
@interface BLE ()
@end
@implementation BLE
-(void)start_central
{
Hub_lib* BLE_central = [Hub_lib new];
[BLE_central centralManager.run_central];
}
2
Answers
Solution from StackO user: Asperi
Emptied top folder
Created workspace at top folder 1.1 Copied clean app and lib to top folder
Add ObjC lib .xcodeproj to workspace using Xcode > File > Add files ...
Add ObjC app .xcodeproj to workspace
Added dependency of sim_backend_UI to lib via workspace a. app proj > General tab > Frameworks, Libs.. > + b. Select lib .a c. Add.
Add Some.swift (any swift file you want) to sim_backend_UI, just for the purpose Xcode add required system swift dynamic libraries (which will be needed for swift part in static library as well)... and confirm creating bridge in appeared dialog a. new file > Swift > Some.swift b. Create Bridging Header c. Added to Some.swift ...
import Foundation
struct Some{}
made a test project to be able to replicate your errors.
You are close but you need to take care of how your static lib has its internal methods and classes exposed in its header so you can use them elsewhere.
let’s begin with the Objective-C Static Library project.
Hub_lib.h
static lib counterpart / implementation
Hub_lib.m
notice
BLE_Central
property is placed in the class interface extension and when you want to use swift module stuff that exposes back to objc you need to declare the auto-generated bridge somewhere (best done in.m
file#import "Hub_lib-Swift.h"
)your
BLE_central.swift
with its protocol method implementationAs long no extra code from objc is used in swift inside the static lib, the
Hub_lib-Bridging-Header.h
is emptyNext let’s see how to import your static lib in your "sim backend UI" Objective-C Project app.
Goto "sim backend UI" App Target settings > General > Framework, Libraries, and.. > hit the
+
button and search for your compiledlibHub_lib.a
file. > select it > hit ok. Should be very much in your framework list by now.Yes, thats not enough! You have to declare its header in your app project somewhere. Where exactly is up to you. Instead of implementing it multiple times we do the following in
BLE.h
counterpart
BLE.m
Your
ViewController.m
or.mm
makes use ofBLE.h
with its already imported static lib headerMade a testButton so you can see if the implementation invokes what you expect. Compile!
And? Aoutsch! Does not work. What happened?
If your App is a plain Objective-C project it doesn’t know about swift yet and will complain in a weirdo way, possibly via something like
Solution: Most easy way is to create a swift file in your app project and allow Xcode to make a bridging header for you. (Alternatively change project settings, search for "bridge" and go step by step thru the properties)
The swift file does not have to have special content.
Compile again. now it should work because the partly implemented swift module from within your static lib can properly work when your Objc-App-Project is able to work with swift stuff.
Edit as you asked to work with Objective-C++/C++ in your static library things change a little bit.. so here some additional example code to proof it.
In Hub_lib project (targeting your "framework") add some files which will keep some random testing c++ code
To make Xcode know that you work with C++ you need to have implementation file ending with
.mm
and also need to changeHubCpp.h
"Identity and Type (right Xcode panel while file selected)" toC++ Header
Rename
Hub_lib.m
to.mm
and change its import rules accordingly to the following ..lets change the proofing method in
Hub_lib.mm
so it really uses C++Compile Hub_lib (scheme). It should work by now and also accept the use of
#import <vector>
.If this works go on and change your Objc-Project-App.
Switch your compile Scheme to target your Objc-App.
Change file name
BLE.m
toBLE.mm
(makes it a Objective C++ Source)Change file name
BLE.h
toBLE.hh
(makes it a C++ header)Change in BLE.mm
#import "BLE.h
to#import "BLE.hh
in
ViewController.m
kick out the line#import "BLE.h"
and replace it intoViewController.h
instead as#import "BLE.hh"
(In general its much easier to keep your compiler informed what language to expect in implementation when you place import headers in header files.)
Compile. Thats it! Your Objective-C++ static lib should properly work at this point.
Edit
You can find a ready made workspace for Xcode here…
github: combine cpp swift and objective-c in static lib