This repository is a note of how to implement cross compatibility between Swift and Objective-C within a Unity project in xCode.
Written with StackEdit.
In order for your Swift code to call and access Objective-C variables and functions, and visavercer - Obj-c to call Swift functions and variables - we need to do a few steps
in order to expose your Objective-C code to your Swift code you need to add your header files to the UnityFramework umbrella header (UnityFramework.h)
1 - add your .h files to the umbrella .h Find the umbrella file UnityFramework.h
Side note: UnityFramework.h is a UMBRELLA file for the framework (a file that contains all .h files, so you can just import UnityFramework.h and like not 54 single .h files..) https://www.google.com/search?q=xcode+what+is+a+umbrella+header
It is located at Unity-iPhone/UnityFramework/UnityFramework.h
Here we need to add our Objective-C headers that swift wants to see
For my use case, my 1 swift (UnityNativeSwift.swift) file needs to see my 1 objective-c file (UnityNativeObjC.mm)
Therefor we only need to add the UnityNativeObjC.h to UnityFramework.h, in order to expose UnityNativeObjC functionality to our Swift files
Open UnityFramework.h, find the line #import "UnityAppController.h" and add #import "UnityNativeObjC.h" above it
2 - add .h files to Public Headers setting
Now we need to add UnityNativeObjC.h as a public header
If it is not a public header, then Swift won’t be able to see it
Go to the project settings page (on the file hierarchy browser on the left, scroll to the top and click on Unity-iPhone at the top)
Select the UnityFramework target
Click on Build Phases (in the top right quadrant)
Expand Headers
The Public Headers list is where we want to drag and drop our .h that we want to expose to Swift
So, Drag and drop your objective-c .h file/s to the Public Headers list
Drag it to the top of the list (supposedly the order does matter. I do not know details and it just works at the top so put your .h file/s at the top of the public headers list)
Your Swift file/s should now see your Objective-C functionalities
in order to expose your Swift code to your Objective-C code, your need to complete a successful build in order have xcode automatically generate the UnityFramework-Swift.h interface file for us.
1 - add .m/.mm to precompile
We need to add our Objective-C file and Swift file into the precompile list, in Build Phases, on the target UnityFramework
2 - do a successful build
We need to do a SUCCESSFUL build in order to auto generate the interface file UnityFramework-Swift.h
UnityFramework-Swift.h is a objective C file that has wrapper/helper methods that just point to the corresponding Swift class, var or function
We need this file to be auto generated so that we can reference it in our .m/.mm files, and expose the swift vars and funcs in our objective-c code
This file is autogenerated on a SUCCESSFUL build.
So comment out any code that is throwing out errors (if any) so that you can do a successful build
If you comment out functions this can cause other errors e.g “method does not exist”. So it might be easiest to just comment out the method’s body (the functions code) and not the actual functions
Now do a build with CMD-B, and hopefully it built successfully
3 - import auto generated interface
Now that the project has successfully been built, we can import the auto generated swift interface file UnityFramework-Swift.h
Open your objective-c .m/.mm file and add
#import <UnityFramework/UnityFramework-Swift.h>
your .m/.mm file should now see your swift code
NOTES:
- Make sure that all the Swift code you want your Objective-C code to see is marked with @objc and public
Bridging-Header in the past, the bridging-header method was used to in order to expose Swift and Objective-C cross functionatlity. But things changed. Sometime between 2018-2020 Unity or xCode changed something. (completely guessing this) The change meant that UnityFramework now handles the swift and objective-c files Here is the catch: frameworks CAN NOT USE bridging headers. therefor, new methods were necessary.
the new methods:
- Umbrella header for Swift calling obj-c
- Auto generated interface file for Obj-c calling Swift
Links:
-
- Scroll down to Mixing Objective-C and Swift.
- This is exactly what we are trying to achieve
-
https://forum.unity.com/threads/swift-ios-native-plugins-hurdles.802623/
-
Shopify/unity-buy-sdk#596 scroll to the bottom
Swift
UnityNativeSwift.swift
import Foundation
@objc public class UnityNativeSwift : NSObject
{
//Global static instance
@objc public static var _sharedInstance = MySwift();
//Variables
var aString = ""
public var byteArray : [UInt8] = []
@objc public func exampleSimpleMethod(arg1:String, arg2:String)
{
// ... do stuff
let unityNativeObjC: UnityNativeObjC = UnityNativeObjC()
unityNativeObjC.exampleObjCMethod();
aString = unityNativeObjC.someVariable;
}
@objc public func exampleComplexMethod(arg1:String, arg2:String)
{
aString = arg1;
}
}
Objective-C
UnityNativeObjC.h
#import <Foundation/Foundation.h>
@interface MyObjC : NSObject
@property (strong, nonatomic) id exampleVar;
- (**void**) exampleObjCMethod;
@end
UnityNativeObjC.m
#import "UnityNativeObjC.h"
#import <AVFoundation/AVFoundation.h>
@implementation UnityNativeObjC
- (void) exampleObjCMethod
{
NSLog(@"Hello World");
}
@end
SEO key words: How to use Objective-C code in Swift with Unity in xCode How to use Swift code in Objective-C with Unity in xCode Swift and Objective-C cross compatibility in a Unity project with Native plugins