Creating an Extension Library for iOSOfficial Content

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

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).

Example

@objc(MyExtensionLibraryClassName)
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.

Example

$if(Main.AppleDevice_iOS)$
target '$Main.iOSXcodeProjectName$' do
  pod 'MyExtension', '~> 2.5.4'
end
target 'MyServiceExtension' do
    platform :ios, '$Main.iOSDeploymentTarget_iOS$'
  pod 'MyExtension', '~> 2.5.4'
end
$endif$

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.

Example

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

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).

Tip: 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.

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.

Example

The XML file must be an XSD as follows.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ExtensionCopyFile"
            targetNamespace="http://schemas.genexus.com/ExtensionCopyFile.xsd"
            elementFormDefault="qualified"
            xmlns="http://schemas.genexus.com/ExtensionCopyFile.xsd"
            xmlns:mstns="http://schemas.genexus.com/ExtensionCopyFile.xsd"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:pd="http://schemas.genexus.com/ExtensionCopyFile.xsd"
>
    <xs:element name="CopyList">
        <xs:complexType>
            <xs:choice maxOccurs="unbounded">
                <xs:element name="Template">
                    <xs:complexType>
                        <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:complexType>
                </xs:element>

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

                <xs:element name="CopyDirectory">
                    <xs:complexType>
                        <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:complexType>
                </xs:element>

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

    <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)" />
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

CustomURLScheme node

Optional. A string value for indicating which URLs can be handled by the application (e.g. when myapp.com.artech.myapp://vdir/resource?parameters is triggered on the device).

Example

<CustomURLScheme>myapp.$Main.IOSBundleIdentifier$</CustomURLScheme>

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.

MainBridgingHeaderImports

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

Example

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

Notes

Availability

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



Was this page helpful?
What Is This?
Your feedback about this content is important. Let us know what you think.