.. role:: switch(samp) .. |rightarrow| unicode:: 0x2192 .. _iOS_Topics: ********** iOS Topics ********** .. index:: iOS Topics This section describes how to set a project up for deployment on iOS devices, and how to use GNAT Pro for iOS to include Ada code in your App. It also describes how to build and deploy this App on the iOS simulator. Prerequisites ============= In order to use GNAT Pro for iOS, you need to have Xcode and the Xcode Command Line Tools installed on your machine. Please refer to the Xcode documentation on how to install these components. Preparing Your Ada Project for Xcode Integration ================================================ The recommended approach for including Ada in your iOS App is to bundle your Ada code into a library, using a GPRbuild Standalone Library Project file. For instance, here is a simple Standalone Library Project file which creates an archive called :file:`libiplanet.a` in the ``lib`` directory. .. code-block:: gpr project IPlanet is for Languages use ("Ada", "C"); for Source_Dirs use ("src"); for Object_Dir use "obj"; for Library_Dir use "lib"; for Library_Kind use "static"; for Library_Name use "iplanet"; for Library_Interface use ("main"); end IPlanet; With a Standalone Library Project file, the resulting library provides two functions to perform the library's elaboration and finalization. The names of these functions depend on the name of the library (specified using the ``Library_Name`` attribute in your project file). For instance, with the IPlanet project file above, the name of the elaboration function is ``iplanetinit``. This will be important later on, when integrating your Ada project into your App. To build your Ada project, simply use gprbuild as usual. For instance: .. code-block:: sh $ gprbuild --target=aarch64-ios-darwin -P iplanet Please refer to the GPRbuild documentation for more detailed information regarding project files. Your iOS App needs to know the identities of all the Ada functions that it is going to call. This is achieved by creating a header file containing all the function prototypes. This file will be integrated later into the iOS App project. Here we will assume that the project provides one header file called :file:`iplanet.h`. Integrating Your Ada Project into Your App ========================================== .. index:: Xcode Developing an App for iOS requires that an Xcode Project be created for that App first. Please refer to the Xcode documentation for instructions on how to create such a project. To integrate your Ada project: * Add a call to the elaboration function of your Ada library (see above) inside your App's code such that this function gets called before your App starts calling the rest of your Ada library. For instance, if your App uses Swift, and assuming you are using the project file above, this can be done by adding a call to ``iplanetinit`` at the start of the "application" function in file :file:`AppDelegate.swift`. * Integrate the Ada code into your project. For this, use the ``Add files to ...`` menu item in the Project Navigator's contextual menu. * Add the various C header files provided by your Ada project (:file:`iplanet.h` in the example project above). * Add your Ada library's archive file (:file:`libiplanet.a` in our example above). * Add the Ada runtime libraries :file:`libgnat.a` and :file:`libgnarl.a`. The location of those files is usually in :file:`/lib/gcc/aarch64-apple-darwin//rts-native/adalib`, where ```` is the location where you installed GNAT Pro, and ```` is the version printed by the command ``aarch64-apple-darwin-gcc -dumpversion``, for example 6.4.1. * Tell Xcode where to find the various C header files you just added, by adding the path where those files are located to the ``Objective-C Bridging Header`` field in the project ``Build Settings`` tab. * Tell Xcode where to find the Ada libraries you just added. For this, update the ``Library Search Path`` in the ``Build Settings`` tab. * Add the directory where your Ada library is located. * Add the directory where :file:`libgnat.a` and :file:`libgnarl.a` are located (see location above). * Additional libraries may be required by your project. In that case, just follow the same process described above. * Because Ada runtime libraries are not built with bitcode enabled, you have to disable bitcode in the ``Build Settings`` tab of your App's project. Once you have performed the above steps, you should be able to add calls from your App to your Ada project and then build your project as usual (menu ``Product`` |rightarrow| ``Build For`` |rightarrow| ``Running``). Running Your App on Your iOS Device =================================== Once the iOS App has been built, you can deploy it and run it on your device through Xcode using the standard method recommended by the Xcode documentation. Note that the first time you run the App you will have to trust your developer app certificate on your device. To do so: * Open the settings app on your iOS device * Navigate to ``General`` |rightarrow| ``Device Management`` * Select your Developer App certificate to trust it. Using the iOS Simulator ======================= Using an iOS simulator to run the App is roughly the same process as for the real iOS device, except for the following changes: * Your Ada project needs to be built with the ios-simulator runtime, using the native GNAT Pro compiler. For this, we no longer use :switch:`--target=aarch64-ios-darwin` in our gprbuild command, and add :switch:`--RTS=ios-simulator` instead. For instance: .. code-block:: sh $ gprbuild -P iplanet --RTS=ios-simulator * In the Xcode project, the location for :file:`libgnat.a` and :file:`libgnarl.a` runtime libraries is in ``/lib/gcc///rts-ios-simulator/adalib`` where ```` is the output of ``gcc -dumpmachine`` (eg: x86_64-apple-darwin14.5.0) Once you have completed these steps, just rebuild and run your App using Xcode targeting the iOS simulator. Please refer to the Xcode documentation for more information. Debugging Your App on Your iOS Device ===================================== Once the iOS App has been deployed on your device, you can debug it using Xcode. As with any debugger, you can suspend/resume the App, add/remove breakpoints, both in Swift or in Ada code. However, beyond this, the Xcode debugger only has limited support for Ada. Because of App high-security rules, the AdaCore debugger cannot be used to debug your App directly on the iOS device. Our recommendation is to validate all your Ada code on the iOS simulator, where the AdaCore debugger can be used for debugging Ada. The rest of your App can be validated on the iOS device, using the Xcode debugger. Debugging Ada on the iOS Simulator ================================== The recommended way to debug the Ada code in your App using the iOS simulator is to start your App Xcode, then start GNAT Studio and attach the AdaCore debugger to your running App. To do so: * In Xcode's top navigation icons, choose a simulator. * Start the simulation. - Find the process ID of your App. For instance, in a terminal, type: .. code-block:: sh $ ps aux | grep Devices | grep Application * Start GNAT Studio. * In GNAT Studio, start the debugger using the ``Initialize`` |rightarrow| ``no main file`` menu. * Then attach the debugger to the App using its Process ID (menu ``Debug`` |rightarrow| ``Debug`` |rightarrow| ``Attach``). Alternatively, type :samp:`attach {PID}` in the debugger console, where *PID* is the process ID of your App. * The App should suspend and you can now use GNAT Studio to debug your App. .. rubric:: Known Limitations Once you have connected the AdaCore debugger to your App, you now have two debuggers connected to the same App at the same time. Since neither knows about the other, it is important to not use the Xcode debugger while the AdaCore debugger remains connected to your App. This will avoid one debugger interfering with the other. After the initial attachment and the first "continue" command, the AdaCore debugger is not able to suspend your App. The only way for the debugger to stop the App again is through breakpoints or catchpoints, so be sure to insert any of them before you resume your App's execution.