Creating an Extension Library for iOS

Official Content
This documentation is valid for:

This article gives the implementation details supported for iOS generator in order to create an Extension Library.

iOS Node

Indicates the implementation dependencies for iOS generator.

Attributes: Platforms

Optional. It allows indicating the Apple platforms for which this extension is planned, separated by commas. This means you can set the extension to be supported only for watchOS:

    <iOS platforms="watchOS">

Or for watchOs and tvOS, but not for iOS: 

    <iOS platforms="watchOS, tvOS">

If this attribute is not included, the extension will be supported for all platforms.

Values: iOS, tvOS, watchOS. 

Supported nodes

This section describes which nodes are supported as extensibility points.

ModuleClass node

Optional. A class name which initializes the extensibility implementation with what it needs. It must implement GXExtensionLibraryProtocol.
The value for this extensibility point is optional because it could be nothing to register (e.g. for User Controls).


public class MyExtensionLibraryClassName: NSObject, GXExtensionLibraryProtocol {

    public func initializeExtensionLibrary(withContext context: GXExtensionLibraryContext) {

       GXActionExternalObjectHandler.register(MyGXActionExternalObjectHandlerSubclass.self, forExternalObjectName: "Module.Path.To.MyExternalObject")

       // Other components initialization, except for User Controls because GeneXus automatically generate the mapping by using the UC definition.



Note that the implementation uses Swift language. In such case, the @objc(MyExtensionLibraryClassName) notation must be used in order to instantiated this class at runtime via reflection.

PodFile node

Optional. Support for CocoaPods extensibility dependencies. In this node, the developer may include a relative path to a PodFile template (see the example below). In case that developer uses this feature, CocoaPods command line tool must be installed on the deployment Mac (refer to Command line tool subsection).

It is possible to include public dependencies at CocoaPods global repository, but it is also possible to include private dependencies in a local repository in the Mac. For this last alternative, GeneXus will automatically create a local repository named GXLocal in your deployment Mac computer when detects any extension library that uses CocoaPods. Also, the usage of a local repository might be useful when the Mac has Internet access restriction.

Command line tool

To install CocoaPods command line tool execute the following command on the deployment Mac.

> sudo gem install cocoapods

The download process might fail with the following error.
error: RPC failed; curl 56 SSLRead() return error -9806
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

In such case, retry execute the command.

Warning: If the developer tests the generated application on a Mac computer, the *.xcworkspace file must be opened instead of *.xcodeproj.


target '$Main.iOSXcodeProjectName$' do
  pod 'MyExtension', '~> 2.5.4'
target 'MyServiceExtension' do
    platform :ios, '$Main.iOSDeploymentTarget_iOS$'
  pod 'MyExtension', '~> 2.5.4'

XCProjExtensionFile node

Optional. Reference to a string template which has to produce an XML with the format shown in the example. With this mechanism, it is possible to extend the generated XCode project.


<?xml version="1.0" encoding="utf-8"?>
             <![CDATA[Content to be added to NodeToBeExtended]]>

Every NodeToBeExtended must match with the template placeholders in the XCode project with format <<<NodeToBeExtended>>> (e.g. <<<PBXFileReference>>> for adding a reference to the project).



Since GeneXus 16 upgrade 3 when you want to extend a node that has the format <<< PLACEHOLDER_NAME :: TARGET_NAME :: >>>, it can be extended using the Target attribute. So, it will look as follows: <PLACEHOLDER_NAME target = "TARGET_NAME" ></ PLACEHOLDER_NAME>.

Example:  <<<PBXSourcesBuildPhase::WatchExtension::>>> look likes <PBXSourcesBuildPhase target=‘WatchExtension’>. 



The easiest way to know what has to be added to a project consists on split the XCode generated project. In the duplicate project, make the desired modifications by using XCode and then make a diff with the original project. With this mechanism, the developer can see in an easy way which modifications should make if the project would be made manually.

Check the GeneXus installation Libraries folder; you will find existing libraries so you can check the configuration files to create your own extensions.

For the complete list of available tags check the GeneXusInstallFolder\iOS\Templates\iOS_Genexus\MainName.xcodeproj\project.pbxproj file with the pattern <<<SampleName>>>; some nodes are:

  • PBXBuildFile
  • PBXFileReference
  • PBXFrameworksBuildPhase
  • PBXSourcesBuildPhase
  • PBXResourcesBuildPhase
  • PBXGroup_Shared
  • PBXGroup_Frameworks
  • PBXLibrarySearchPath_Release and PBXLibrarySearchPath_Debug (1)
  • PBXFrameworkSearchPath_Release and PBXFrameworkSearchPath_Debug (1)

CopyListFile node

Optional. Reference to string template which must produce an XML (see the example below) with those files, directories, and templates to be copied to the generated XCode project.


The XML file must be an XSD as follows.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ExtensionCopyFile"
    <xs:element name="CopyList">
            <xs:choice maxOccurs="unbounded">
                <xs:element name="Template">
                        <xs:attribute name="Id"    use="required"/>
                        <xs:attribute name="Name" use="optional"/>
                        <xs:attribute name="InputPath"  default="" use="optional"/>
                        <xs:attribute name="Recursive" type="xs:boolean" default="true"/>
                        <xs:attribute name="Pattern"     default=""/>
                        <xs:attribute name="Output" />
                        <xs:attribute name="Delimiter" use="optional" default="$"/>
                        <xs:attribute name="TemplateEncoding" type="TEncoding" use="optional" />

                <xs:element name="CopyFile">
                        <xs:attribute name="Name" use="required"/>
                        <xs:attribute name="Output"/>

                <xs:element name="CopyDirectory">
                        <xs:attribute name="Name" use="required"/>
                        <xs:attribute name="Output"/>
                        <xs:attribute name="Recursive" type="xs:boolean" default="true"/>
                        <xs:attribute name="Force" type="xs:boolean" default="true"/>

                <xs:element name="Variable">
                        <xs:attribute name="Name" type="xs:string" use="required"/>
                        <xs:attribute name="Class" type="xs:string" use="required"/>

    <xs:simpleType name="TEncoding">
        <xs:restriction base="xs:string">
            <xs:enumeration value="Machine Default" />
            <xs:enumeration value="UTF8 (no BOM)" />
            <xs:enumeration value="UTF8 (including BOM)" />

CustomURLScheme node

Optional. A string value for indicating which URLs can be handled by the application (e.g. when is triggered on the device).



It is highly recommendable to use $Main.IOSBundleIdentifier$ placeholder as a suffix for identifying the application and avoiding conflicts with other apps that might use the same scheme.


Optional. Allows the developer to include bridging headers (import Objective-C modules to Swift, useful for integrating APIs).


<MainBridgingHeaderImports>#import "SomeModuleInObjC.h"</MainBridgingHeaderImports>

DisableBitcode Node

As from GeneXus 16 upgrade 6, the generated applications have the Bitcode option enabled (ref.: SAC#46100). If you have an application that uses extensions needing libraries not compatible with this option, you can add this node with True value. It disables this option in the generated project.


InfoPlist Node

When developing extensions, it may be the case that the libraries used require the addition of special keys in the application's Info.plist file. That is the case of libraries such as AdMob or the Facebook SDK.

To be able to provide special keys to be added to the Info.plist file, you will have to add a new file with the key-value pairs, and add the following to the extensions library's definition file: 


Where "FileName" is the name of the .plist file that you have to create under the iOS Libraries folder. Here you need to add the key-value pairs (which must have a valid format fo the PList extension). Inside it, you may add all the key-value pairs necessary for your extension. For example:


Note: that the values can be a template variable. Specifically, any property defined by your extension library may be used by prefixing it with "Main.Dynamic".

EntitlementsExtensionFile Node

Optional. Reference to a string template file which must produce a PList formatted XML to be added to the <MainName>.entitlements file.


To add the Health Kit entitlement, add the EntitlementsExtensionFile element inside the iOS node to the .library file:

<iOS platforms="iOS">

And then, in the file iOS\MyExtensionLibrary.entitlements, add the following content:





Extension Library implementation is supported as of GeneXus 15 Upgrade 6.

(1) - Available since GeneXus 15 upgrade 12