Step By Step Guide To Merge Unity Build Application With Native iOS App.
Ammad Raza
Sr Unity Developer / Software Engineer @ Proxify | AR VR XR Metaverse Development
At the time of this documentation, Xcode 12.5 and Unity 2019.4.xx was used for overall Merge process. In addition, during the time of research and development this document was updated several times and over.
Nevertheless, the report holds all the necessary steps to merge Unity made app with a native iOS App, starting from the creation of simple native iOS app, then comes the preparation of Unity project in a merged space of Xcode, and lastly the creation and implementation of Bridge that aids in connecting two projects via UnityFramework.?
Step 1. Create Native iOS App?
- You can start by opening your Xcode and selecting “Create a new Xcode projectâ€.?
- Choose “iOS†in Multiplatform section and select “App†from Application Area. Then proceed by clicking to “Next†Button.
- Next comes the part in which you need to provide Project details.
Please make sure to provide appropriate “Product Nameâ€, “Team†and “Organization Identifierâ€.
Also, make sure that the “Interfaceâ€, “Life Cycle†and “Language†options are set to what is shown in the image below.
Step 2. Prepare Native iOS App
- Expend your project and make your way towards “Main.storyboardâ€, and expend “View Controller Sceneâ€.
- Here you need to create two buttons, the first button is to initialize UnityFramework and the second button is to show Unity Scene over UIViewController.
Important note: In actual there is no need of two button, one can simply initialize UnityFramework and call upon a function to show Unity Scene using a single press of a button, however, the purpose of this document is to provide proper knowledge to the developers, by simply dividing large steps into small segments that would even make easier for non-coders to comprehend.
You can instantly access the “Objects Libraryâ€, by clicking on “+†button found at the center top bar of the Xcode.
If you do not see a “+†button, expend the “View†and select “Show Libraryâ€.
- Just drag and drop two Buttons on to the Main.storyboard.
Expected outcome at this point:
- Select the first Button and then select the “Attributes Inspector†area that usually take place on the right side of the Xcode.?
-??????If one would observe, the options available in the Attributes Inspector are not very complicated, and therefore you can easily modify the size, color, font, text of the Button.
-??????Feel free to modify both buttons as you desire.
Expecting somewhat similar outcome at this point:
- Create “Constraintsâ€.?
-??????Select one of the buttons, then select the “Add New Constraints†option found on the center bottom of the Xcode.
-??????Make sure to check “Widthâ€, “Height†and “Aspect Ratioâ€. Then Hit “Add 3 Constraintsâ€.
-??????Repeat the process for another button.
If you have applied the Constraints correctly, a small red arrow may appear beside the View Controller Scene.
U
pon click to the small red arrow, Xcode will show you the missing Constraints.
Click on the small red dot, and select “Add Missing Constraintsâ€. It should take care all the red Constraints errors at the same time, if not, you can take care of each red dot one at a time.?
If you find any yellow triangle warning dots, make sure to take care of them as well by clicking the yellow triangle, selecting “Remove Constraintâ€, and hitting the “Confirm†button.
Expected outcome at this point:
Step 3. Creating Merged Space.
Reference: https://www.youtube.com/watch?v=2zQYrOeF1Ko
- ?Creating Workspace.
-??????Open up your Xcode, go to the “File†section, select “Newâ€, then select “Workspaceâ€.
-??????Make sure to give appropriate name to your new workspace, and save it in the same folder as where you have saved your native iOS app.?
-??????Now, make sure your Unity made iOS project is also in the same folder as to where native iOS app and workspace is saved.
- Setup Workspace.
-??????Open up the Workspace you have recently created. It must be empty.
-??????Go over the “File†section, and select “Add Files to xxxx.xcworkspaceâ€.
-??????Within the same folder you should be able to find and “Add†the native iOS project you have just created.
-??????Next, within the same folder you should be able to find and “Add†the Unity project.
Expected outcome at this point:
You should have both (native and Unity project) in your workspace.
领英推è
- Add UnityFramwork.?
In your workspace, select the native iOS app, in the “General†options, scroll down to find “Frameworks, Libraries, and Embedded Contentâ€.
Select the “+†button to add Unity framework.
Expected outcome at this point:
- Remove UnityFramwork.framework from Binary Library.?
Again, in your native app, access the “Build Phasesâ€, and expend “Link Binary With Librariesâ€.
Here, you need to select the “UnityFramwork.frameworkâ€, and select “-†button to remove it from Binary Library as it may cause errors.
Expected outcome at this point:
- Prepare Unity Project.
In your workspace, expend your Unity-iPhone.
-??????If your project contains any plugins, redirect to the “Libraries†Folder to access “Plugins/IOSâ€. Select all the header scripts, and in the inspector, under “Target Membership†put a check on “UnityFrameworkâ€, and make sure to mark it as “Publicâ€.
-??????Now, in the Unity-Project, you need to make one more change in-order to complete the Unity-project setup process.?
Redirect to the “Data†folder found in Unity-project, and in the inspector, under “Target Membershipâ€, put a check to “UnityFramework†and uncheck the “Unity-iPhoneâ€.
Merged Space Created!
Step 4. Bridge Creation & Implementation
Coming back to the native app located inside the workspace.
- Create new script in native app.?
Right click to your native app folder, and select “New File…â€
Make sure the new file you create is “Swift Fileâ€, and name it “BridgeActâ€.
- Copy the following code and paste it into the BridgeAct swift script you have just created.
import UIKit
import Foundation
import UnityFramework
?
class BridgeAct: UIResponder, UIApplicationDelegate, UnityFrameworkListener {
?
??? private var framework : UnityFramework!
???
??? private static var launchOptions : [UIApplication.LaunchOptionsKey: Any]?
?
??? func unityIsInitialized() -> Bool
??? {
??????? return framework != nil && (framework.appController() != nil)
??? }
???
? ??func getUnityController() -> UIViewController
??? {
??????? return framework.appController().rootViewController
??? }
?
??? static func setLaunchOptions(_ launchOpts : [UIApplication.LaunchOptionsKey: Any]?)
??? {
??????? BridgeAct.launchOptions = launchOpts
??? }
?
??? func showMainView()
??? {
??????? if unityIsInitialized()
??????? {
??????????? framework.showUnityWindow()
??????? }
??? }
?
??? func initUnity()
??? {
??????? if unityIsInitialized()
??????? {
??????????? showMainView()
??????????? return
??????? }
?
??????? self.framework = UnityFrameworkLoad()!
??????? framework.setDataBundleId("com.unity3d.framework")
??????? framework.register(self)
?
??????? framework.runEmbedded(withArgc: CommandLine.argc, argv: CommandLine.unsafeArgv, appLaunchOpts: BridgeAct.launchOptions)
??? }
?
??? func unloadUnity()
??? {
??????? if unityIsInitialized()
??????? {
??????????? framework.unloadApplication()
??????????? framework = nil
??????? }
??? }
?
??? func UnityFrameworkLoad() -> UnityFramework?
??? {
??????? let bundlePath: String = Bundle.main.bundlePath + "/Frameworks/UnityFramework.framework"
?
??????? let bundle = Bundle(path: bundlePath )
???????
??????? if bundle?.isLoaded == false
??????? {
??????????? bundle?.load()
??????? }
?
??????? let framework = bundle?.principalClass?.getInstance()
???????
??????? if framework?.appController() == nil
??????? {
??????????? let machineHeader = UnsafeMutablePointer<MachHeader>.allocate(capacity: 1)
??????????? machineHeader.pointee = _mh_execute_header
????
??????????? framework!.setExecuteHeader(machineHeader)
??????? }
???????
??????? return framework
??? }
}
?
- Access the “AppDelegate.swift†file in your native app, and call upon a BridgeAct.setLaunchOptions() method inside the following event call.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
??????? BridgeAct.setLaunchOptions(launchOptions)
??????? // Override point for customization after application launch.
??????? return true
}
- Access the “ViewController.swift†file in your native app, and copy & paste the following code.
import UIKi
import UnityFramework
?
class ViewController: UIViewController, UnityFrameworkListener {
???
??? @IBOutlet weak var StartUnity: UIButton!
??? @IBOutlet weak var ShowUnity: UIButton!
???
??? var instance : BridgeAct!
???
??? @IBAction func SceneStartUnity(_ sender: UIButton)
??? {
??????? instance = BridgeAct()
??????? instance.initUnity()
?
??????? //hide the first button
??????? StartUnity.isEnabled = false
??????? StartUnity.isHidden = true
???????
???? ???//enable second button
??????? ShowUnity.isEnabled = true
??????? ShowUnity.isHidden = false
??? }
???
??? @IBAction func ShowUnityScene(_ sender: UIButton)
??? {
??????? if(instance.unityIsInitialized())
??????? {
??????????? //set Unity viewcontroller
??????????? present(instance.getUnityController(), animated: true, completion: nil)
???????????????????
??????????? //show unity screen
??????????? instance.showMainView()
???????????????
??????????? //disable second button
??????????? ShowUnity.isEnabled = false
??????????? ShowUnity.isHidden = true
??????? }
??? }
???
??? override func viewDidLayoutSubviews()
??? {
??????? //disable second button
??????? ShowUnity.isEnabled = false
??????? ShowUnity.isHidden = true
???????
??????? //center allign button fonts
??????? StartUnity.titleLabel?.textAlignment = .center
??????? ShowUnity.titleLabel?.textAlignment = .center
??? }
???
??? override func viewDidLoad()
??? {
??????? super.viewDidLoad()
??? }
}t
Do not worry if you are getting error on UnityFramework at this point
- Connect Buttons.
-??????Open up a new editor, you can do that by clicking on the “Add Editor on Right†button pointed in the image below.
-??????Make sure to have “View Controller.swift†opened on the left Editor and have “Main.storyboard†opened on the right Editor.
-??????Now, connect both buttons in the “Main.stroyboard†with the buttons in “ViewControllerâ€.
Observe the empty circles appearing in the index column of the “ViewControllerâ€. If the circle is empty, that means the value is not assigned or connect to the storyboard.
?Assign all the button values and button functions to their respective UI Objects.
Expected outcome at this point:
- Build Unity-iPhone?
-??????Set the active scheme as “Unity-iPhone†and choose “Any iOS Device†for the Build, and press “cmd†+ “B†to compile.
DON’T PRESS PLAY BUTTON!
- Build UnityFramework.
-??????Similar to the above process, set active scheme as “UnityFramework†and choose “Any iOS Device†for the Build, and press “cmd†+ “B†to compile. ?
DON’T PRESS PLAY BUTTON!
?
- Build Native iOS App
-??????After both Build have be compiled successfully, plugin your iPhone to your Mac.
set active scheme as “UnityFramework†and choose “(YOUR iPhone DEVICE)†(the one that is plugged in) for the Build, and press “cmd†+ “B†to compile.
DON’T PRESS PLAY BUTTON!
At this point any errors related to UnityFramwork should get fixed.
- Final Check.
If your Unity project requires any particular access for instance, a “Camera Accessâ€, you need to update “Info.plist†file found in your native iOS App.
Example:
At this point Bridge Creation & Implementation process is completed!
You can click on the Play button to Compile and install the merged app on your iPhone.
Lead Software Engineer at Inarix (AgriTech)
2 å¹´Awesome ??