Skip to main content

Getting Started (CPIK Libraries)

Contents

Follow the setup steps below to integrate CPIK libraries and get CoPilot running in your app.

Android

Step 1: Add CoPilot repository

Add the following to your project build.gradle file:

repositories {
    maven {
        url "https://trimblemaps.jfrog.io/artifactory/android"
    }
}

Step 2: Add dependency

Add the following to your module build.gradle file. You can find the most recent CoPilot version in our release notes.

dependencies {
    implementation (group: 'com.trimblemaps', name: 'cpik-android', version: '11.XX.X.XXXX', ext: 'aar')
}

Step 3: Configure AndroidManifest.xml

Add the following permissions and metadata to your AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

<service android:name="com.alk.copilot.CopilotService" android:enabled="true" android:foregroundServiceType="location" />
<meta-data android:value="true" android:name="ALK_isCustomFragment" />
<meta-data android:value="true" android:name="ALK_useInternalStorage" />
<meta-data android:value="true" android:name="ALK_doBackgroundStart" />
<meta-data android:name="ALK_useOpenGL" android:value="true" />

Step 4: Permissions validation

Add permission checking code to your MainActivity:

public static final int REQUEST_CONST = 3110;

private boolean hasAllPermissions() {
    String[] permissions = new String[] {
        Manifest.permission.INTERNET,
        Manifest.permission.ACCESS_COARSE_LOCATION,
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
        Manifest.permission.ACCESS_NETWORK_STATE,
        Manifest.permission.WAKE_LOCK,
        Manifest.permission.READ_CONTACTS,
        Manifest.permission.ACCESS_WIFI_STATE,
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    };
    for (String permission : permissions)
        if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED)
            return false;
    return true;
}

public void permissionCheck() {
    if (!hasAllPermissions()) {
        ActivityCompat.requestPermissions(this, new String[] {
            Manifest.permission.INTERNET,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
            Manifest.permission.ACCESS_NETWORK_STATE,
            Manifest.permission.WAKE_LOCK,
            Manifest.permission.READ_CONTACTS,
            Manifest.permission.ACCESS_WIFI_STATE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
        }, REQUEST_CONST);
    } else {
        setup();
    }
}

Step 5: Service binding

Add service binding code to connect to CoPilot:

private static final int FOREGROUND_SERVICE_ID = 3283;
private CopilotService.CopilotBinder copilotBinder = null;

private ServiceConnection copilotServiceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        copilotBinder = (CopilotService.CopilotBinder) service;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            copilotBinder.startForeground(FOREGROUND_SERVICE_ID, getNotificationForService());
        } else {
            NotificationCompat.Builder builder = new NotificationCompat.Builder(
                MainActivity.this);
            builder.setContentTitle(getString(R.string.app_name)).setSmallIcon(R.drawable.ic_launcher_foreground);
            Intent resultIntent = new Intent(MainActivity.this, MainActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this,
                0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
            builder.setContentIntent(pendingIntent);
            copilotBinder.startForeground(FOREGROUND_SERVICE_ID, builder.build());
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        // Handle disconnection
    }
};

public void startService() {
    Intent copilotServiceIntent = new Intent(this, CopilotService.class);
    this.bindService(copilotServiceIntent, copilotServiceConnection, Context.BIND_AUTO_CREATE);
}

Step 6: Startup control

Add licensing and startup listeners. Replace AMS_USERNAME and AMS_COMPANYID with your credentials from Account Manager. The username is the individual asset assigned a license, and the company ID is shared across all assets in your fleet.

public static final String AMS_USERNAME = "YOUR_USERNAME";
public static final String AMS_COMPANYID = "YOUR_COMPANY_ID";

private class LicenseHookListener extends LicenseListener {
    @Override
    public void onLicenseMgtLogin(LicenseActivationResponse activationStatus, LicenseMgtInfo loginInfo) {
        super.onLicenseMgtLogin(activationStatus, loginInfo);
    }

    @Override
    public LicenseMgtInfo licenseMgtCredentialHook() {
        return new LicenseMgtInfo(AMS_USERNAME, AMS_COMPANYID);
    }
}

private class StartupListener extends CopilotListener {
    @Override
    public void onCPStartup() {
        displayCopilot();
    }
}

public void setup() {
    LicenseListener.registerHook(new LicenseHookListener());
    LicenseListener.registerListener(new LicenseHookListener());
    CopilotListener.registerListener(new StartupListener());
    startService();
}

Step 7: Display CoPilot

Add the CoPilot view to your layout and display it:

Layout XML (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <RelativeLayout
       android:id="@+id/copilotLayout"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content">
   </RelativeLayout>

</FrameLayout>

Java code

private void displayCopilot() {
    View copilotView = CopilotMgr.getView();
    ((RelativeLayout) findViewById(R.id.copilotLayout)).addView(copilotView);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    permissionCheck();
}
iOS

Step 1: Download the CPIK iOS files

CoPilot files can be downloaded from the Partner Portal. Once logged in, navigate to B2B > CPIK > iOS > .Native.

Note
When downloading files, be sure to download the latest version of CoPilot and to only include files from that version in your project.

Step 2: Add required frameworks

Add these frameworks to your project’s “Link Binary With Libraries” build phase:

Framework Framework
AddressBook CoreAudio
AddressBookUI CoreGraphics
AssetsLibrary CoreLocation
AudioToolbox CoreTelephony
AVFoundation ExternalAccessory
CFNetwork Foundation
Contacts MediaPlayer
ContactsUI MessageUI
OpenGLES QuartzCore
Security StoreKit
SystemConfiguration UIKit
WebKit

Step 3: Add required libraries

Add these libraries to your project:

Library
libc++
libsqlite3
libz

Step 4: Add resources

Add the Library and Resource > assets > copilot_resources.bundle file to your project root.

Step 5: Basic integration

Add this code to initialize and display CoPilot:

#import <CoPilotIntegrationKit/CoPilotIntegrationKit.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Get CoPilot instance
    CoPilot* cp = [CoPilot sharedManager];

    // Set the CoPilot delegate
    cp.delegate = self;

    // Start the CoPilot Navigation App
    [cp startNavApp];

    return YES;
}

// Receive startup callback
-(void)onCPStartup {
    NSLog(@"CoPilot is Ready!");
    // CoPilot is now ready to use
}

// Display CoPilot
- (IBAction)showCopilot:(id)sender {
    UIViewController *cpVC = [CoPilot sharedManager].copilotViewController;
    [self.navigationController pushViewController:cpVC animated:YES];
}
Android .NET and .NET MAUI

Step 1: Download the CPIK libraries

You can download and integrate the CPIK libraries files for Android .NET one of two ways:

  • Automated method, using our public repository.
  • Manual method, by logging into our public repository or Partner Portal.

Automated method

  1. Open your solution in Visual Studio and then select Tools > Options. Scroll down to NuGet Package Manager, expand it, and then select Package Sources. Click on the plus icon to add a new source.

  2. In the Name field, enter a name (ex: trimble-maps) and in the Source field, enter this url: https://trimblemaps.jfrog.io/artifactory/api/nuget/dotnet. Make sure the checkbox is checked and hit OK.

  3. Go to Tools > NuGet Package Manager > Manage NuGet Packages For Solution. Now select the name you chose in Step 2 in the Package source dropdown box. After about a minute, on the left side of the pane, you should see one package appear named cpik. If it is not installed, select it and hit Install. If it is already installed, check if any new update is available in the update section. Once the install is complete, you should see CPIKWrapper has been added under your project References.

Manual method

You can manually download the files:

  • As NuGet packages in our public repository: https://trimblemaps.jfrog.io/ui/native/dotnet/.
  • As a .zip file in our Partner Portal: https://c2.trimblemaps.com/. After downloading and extracting the CoPilot CPIK libraries .zip file from the partner portal, you should have access to everything needed to get up and running quickly. The CPIK libraries package includes the following:

Sample App

  • Source code of the sample application
  • Sample application APK that can be install on an Android device

Libraries & Resources

  • The CPIKWrapper.dll is the biggest change from Xamarin to .NET as now the CPIKWrapper.dll does not include the Android libraries and assets. It is just a wrapper for the Java code.
  • Libs/CPIKWrapper.dll: The customer application shall use this library to integrate CPIK libraries.
  • Libs/cpiklibraryaar-release.aar: Android archive containing all the libraries and assets needed.
  • Native Libs/. : The native library need to place a libs folder in the customer application (optional).
  • Asset: Need to copy to customer’s application asset folder (optional)
  • AndroidManifest_template.xml: Reference AndroidManifest.xml file.

Note: When downloading files, be sure to download the latest version of CoPilot and to only include files from that version in your project. You use the CPIK API calls the same way as you did in Xamarin.

Step 2: Run the Sample App

Source Code

  1. Open the CPIKFragment_NET.sln from Sample App/Source Code/CPIKFragment_NET.sln in Visual Studio 2022.
  2. If you want to run the app using the CPIK_JavaBindings project, hit Run and let the application build. The FragmentApp.csproj is set up for CPIK_JavaBindings.
  3. If you want to manually reference the cpiklibraryaar-release.aar and CPIKWrapper.dll in the FragmentApp.csproj, you need to do it following the steps below. This can apply to your own application as well, not just the fragment app. Add code below to the FragmentApp.csproj. It adds the cpiklibraryaar-release.aar and CPIKWrapper.dll reference to the application. It contains all the information required to run (i.e. library, asset, resources, component, etc.)
<ItemGroup>
    <AndroidLibrary Remove="cpiklibraryaar-release.aar" />
  </ItemGroup>
  <ItemGroup>
    <None Remove="cpiklibraryaar-release.aar" />
  </ItemGroup>
<ItemGroup>
    <Reference Include="CPIKWrapper">
      <HintPath>..\..\Library and Resource\libs\CPIKWrapper.dll</HintPath>
    </Reference>
  </ItemGroup>
  1. You can now run the app: com.alk.copilot_generic_enterprise_NET_fragment.apk Sample APK which can be installed on CoPilot

Step 3: CPIK Java bindings

The CPIK Java Bindings project is a Java library bindings project that creates a wrapper, CPIKWrapper.dll, for CPIK. However, in .NET Android, the .aar files are no longer embedded in the dll. This means that in order to use the CPIKWrapper.dll, we need the cpiklibraryaar-release.aar alongside it.

The CPIK Java Bindings is a separate project that can nicely separate this task for you. Your application, like our fragment app, would reference this project and be able to use the CPIK APIs. This is an example of a nicer, cleaner, and more organized way to add CPIK to your application. Of course, you can simply add references to both the CPIKWrapper.dll and cpiklibraryaar-release.aar in your .csproj like in the code snippet above.

Libraries & Resources

  • Libs /CPIKWrapper.dll: This is a binding library to interface with CoPilot. The CPIK libraries jar files are no longer wrapped into CPIKWrapper.dll. You will need to add the cpiklibraryaar-release.aar to your application.
  • Libs/cpiklibraryaar-release.aar.: This is the aar containing all the assets, native libs and CPIK jar files that are needed.
  • Native libs/. (Optional): This is the native library used by CoPilot. Copy the native library to your project. Copy all the folders under Library and Resource/native libs/. to /lib/. to your project. It contains native libraries for different architectures required to run CoPilot. If you have an existing lib folder to your project, merge the content. To deploy a native library with a .NET Android application, add the library binary to the project and set its Build Action to AndroidNativeLibrary.
  • Asset (Optional): Copy the Library and Resource/assets folder into your project. Copy the entire assets folder located under Library and Resource/assets/ to /assets/ folder to your project. It contains vital information to run CoPilot (e.g. theme, config files, skin, etc.). If you have an existing assets folder in your project, merge the content. Make sure that the entire Copilot folder under Assets is added to .NET and set BuildAction to AndroidAsset. If you want to add your own product.cfg to your project, then you can create a /assets/copilot/product.cfg in your project. This product.cfg will be added to your application for CoPilot.
  • AndroidManifest_template.xml: This file contains all required attributes and permission to run the CoPilot. You need to merge this information to your existing AndroidManifest.xml.

Library integration instructions

Setup instructions:

  1. Integrate the contents of Library & Resource/AndroidManifest_template.xml into your application’s AndroidManifest.xml.
  2. You can either reference the CPIK_JavaBindings bindings project that contains the cpiklibraryaar-release.aar and will create a CPIKWrapper for it or you can manually reference these two objects to your project. If you choose to reference the CPIK_JavaBindings project, then you are done and can use CPIK! Otherwise move to step 3. This is the recommended way to do it because the way .NET creates .dll wrappers now does not embed the CPIK library inside the .dll so the process is tricker.
  3. Reference Library & Resource/libs/ CPIKWrapper.dll that contains the C# wrapper for the jar files.
  4. Add Library & Resource/libs/cpiklibraryaar-release.aar to your project and set the BuildAction to Android Library. If you see some build error related to CPIK, you might need to edit your .csproj manually. Refer to the code block above.
  5. Develop! Use the included sample application as a guide.

API documentation

  • The API documentation detailed on this site references the classes and their members. It also contains the signature of each member of the classes including description and usage.

  • The documentation contains syntax for Java. Developers can easily map the relevant syntax with C# in Xamarin. You can also check the syntax in Xamarin by exploring CPIKWrapper.dll by adding reference in project.

Sample application

This sample application is meant to demonstrate how to properly integrate CoPilot into your application. If you’re just getting started, take a look at MainActivity.cs. This is the application’s launcher activity. It demonstrates how to bind to the CoPilot service and how to show the service’s associated view either through a fragment (see CustomFragment.cs) or by simply putting the view on the screen. After binding to the service, you will receive a callback (onCPStartup()) from CoPilot that indicates that the library is ready to receive API calls.

Most of our APIs are demonstrated in the sample app via various fragment classes that each correspond to a different API module. These fragments are controlled by ApiMainActivity.cs. If you have a question about how to use a specific API, look at the module’s fragment to see how to use it properly.

CoPilot Appearing very dim

It has been noted that in some circumstances the CoPilot UI can appear significantly darker/dimmer than the integrated application. This can be due to the styles.xml settings and easily resolved by adding the following to your styles.xml:

<style name="MyTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <item name="android:backgroundDimEnabled">false</item>
</style>

Step 4: Service Binding

Add the following to your MainActivity.cs:

#region IServiceConnection

        public void OnServiceConnected(ComponentName name, IBinder service)
        {
            Binder = service.JavaCast<CopilotService.CopilotBinder>();
            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                Binder.StartForeground(FOREGROUND_SERVICE_ID, GetNotificationForService());
            }
            else
            {
                NotificationCompat.Builder builder = new NotificationCompat.Builder(mSelfRef);
                builder.SetContentTitle("Hello World");

                Intent resultIntent = new Intent(this, typeof(MainActivity));
                Android.App.PendingIntent pendingIntent = Android.App.PendingIntent.GetActivity(this, 0, resultIntent, Android.App.PendingIntentFlags.UpdateCurrent | Android.App.PendingIntentFlags.Mutable);
                builder.SetContentIntent(pendingIntent);

                Binder.StartForeground(FOREGROUND_SERVICE_ID, builder.Build());
            }
        }

        public void OnServiceDisconnected(ComponentName name)
        {

        }

        [Android.Annotation.TargetApi(Value = 26)]
        private Android.App.Notification GetNotificationForService()
        {
            Android.App.NotificationManager notificationManager = (Android.App.NotificationManager)ApplicationContext.GetSystemService(Context.NotificationService);
            string channelName = Resources.GetString(Resource.String.app_name);
            Android.App.NotificationChannel notificationChannel = new Android.App.NotificationChannel(NOTIFICATION_CHANNEL, channelName, Android.App.NotificationImportance.Default);
            notificationChannel.Description = channelName;
            notificationChannel.SetSound(null, null);

            notificationManager.CreateNotificationChannel(notificationChannel);
            Intent resultIntent = new Intent(ApplicationContext, typeof(MainActivity));
            Android.App.PendingIntent pendingIntent = Android.App.PendingIntent.GetActivity(ApplicationContext, 0, resultIntent, Android.App.PendingIntentFlags.UpdateCurrent | Android.App.PendingIntentFlags.Mutable);

            return new Android.App.Notification.Builder(ApplicationContext, NOTIFICATION_CHANNEL)
                    .SetContentTitle(channelName)
                    .SetOngoing(true)
                    .SetChannelId(NOTIFICATION_CHANNEL)
                    .SetContentIntent(pendingIntent)
                    .SetSmallIcon(Resource.Drawable.alk_icon_launcher)
                    .Build();
        }

        #endregion

The above code creates a new ServiceConnection and overrides two of its methods, the most important one being onServiceConnected(). The code triggers the foreground service and binds CoPilot once the startService() method is called. You’ll also notice the code checks for the Android version. In Android 8.1 and above, Android changed the way it handles services and as a result we have to create a custom notification channel for our service in this case.

Now that we have our core functionality set up for creating and binding the CoPilot service, we need to ensure we have the necessary permissions before doing so.

Step 5: Validate permissions

Add the following code into your MainActivity.cs:

/**
 * Checks each permission to ensure the application has access. Only really need to check the
 * more 'intrusive' permissions like location, but left all in to be consistent with
 * AndroidManifest.xml
 * @return
 */
private void CheckRequiredPermissions()
        {
            mSelfRef.RequestPermissions(new String[]{
                // Network
                Manifest.Permission.Internet,
                Manifest.Permission.AccessNetworkState,
                // Access external storage
                Manifest.Permission.WriteExternalStorage,
                Manifest.Permission.ReadExternalStorage,
                Manifest.Permission.ManageExternalStorage,
                // Location
                Manifest.Permission.AccessFineLocation,
				// Contacts
				Manifest.Permission.ReadContacts,

				Build.VERSION.SdkInt >= BuildVersionCodes.M ? Manifest.Permission.AccessNotificationPolicy : Manifest.Permission.Internet,

                // System settings
                Build.VERSION.SdkInt <= BuildVersionCodes.LollipopMr1 ? Manifest.Permission.ReadPhoneState : Manifest.Permission.AccessWifiState,

                Manifest.Permission.AccessWifiState,
                Manifest.Permission.WakeLock
            }, MY_PERMISSIONS_REQUEST);

        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
        {
            bool bIsPermissionFailed = false;
            if (requestCode == MY_PERMISSIONS_REQUEST && grantResults.Length > 0)
            {
                foreach (Permission permission in grantResults)
                {
                    if (permission != Permission.Granted)
                    {
                        bIsPermissionFailed = true;
                        break;
                    }
                }
            }
            if (bIsPermissionFailed)
            {
            }

            StartCopilot();

        }

With the above we have two main functions:

  1. CheckRequiredPermissions() requests permissions from the user if it needs to, otherwise just starts the setup procedure of CoPilot. We will write the StartCopilot() method later.
  2. We override the OnRequestPermissionsResult() function. When the user grants or denies access when requested, they will return here.

Step 6: Control CoPilot’s Startup

At this point, the core code for starting the service is written, and the app has the permissions it needs to work with CoPilot itself. In this section, we’re going to write a few listeners and hooks to dictate what CoPilot does on its start up. We’ll begin by licensing CoPilot when it starts up, and then ensure the software is ready before interacting with it further. Start by adding the following code to you MainActivity.cs:

public const string AMS_USERNAME = "YOUR_USERNAME";
public const string AMS_COMPANYID = "YOUR_COMPANY_ID";
private class MyLicenseHook : LicenseHookListener  {
    public override void OnLicenseMgtLogin(LicenseActivationResponse activationStatus, LicenseMgtInfo loginInfo) {
        // This is fired when we have an activation response back from the licensing system
        base.OnLicenseMgtLogin(activationStatus, loginInfo);
    }
    public override LicenseMgtInfo licenseMgtCredentialHook() {
        // This is fired on launch when registered as a hook, it either logs the user in as
        // a new user or if the user is already logged in with these credentials, does nothing.
        return new LicenseMgtInfo(AMS_USERNAME, AMS_COMPANYID);
    }
}


private class StartupListener : CopilotListener {

    public override void OnCPStartup() {
        SignalCopilotisReady();
    }
}

The above are two private classes that extend some of CoPilot’s listeners. The LicenseHookListener is used to license and activate CoPilot. The licenseMgtCredentialHook() method is fired on launch and effectively provides the username and company ID to authenticate. If you’re unfamiliar with Trimble Maps Account Manager licensing, please speak to your account manager. Additionally, there is a StartupListener that will fire onCPStartup() when CoPilot is ready to be interacted with. There’s a function that has not been written yet. We’ll get to that shortly. Now that the listeners and hooks are in place, it’s time to register them. This should be done before the service is started to ensure they fire during the startup calls. This helps control your application’s workflow. Add the following to your MainActivity.cs:

public void RegisterStartupListeners() {
    LicenseListener.RegisterHook(new LicenseHookListener());
    LicenseListener.RegisterListener(new LicenseHookListener());
    CopilotListener.RegisterListener(new StartupListener());
}

Lastly, add the CheckRequiredPermissions() function to your onCreate() for the activity to start the whole process.

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    SetContentView(R.Layout.activity_main);


    CheckRequiredPermissions();
}

With that the CoPilot service, licensing and startup procedures are all running. However, they’re running silently in the background—nothing is being displayed yet.

Step 7: Display CoPilot

Inside your main.axml file, or whichever layout file you use to create a view that effectively fills the entire activity, add:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/apiRootMainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
     <!-- Container for the copilot fragment -->
      <RelativeLayout
          android:id="@+id/copilot_fragment_container"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_alignParentBottom="true" />
</RelativeLayout>

For the example above, we want CoPilot to take as much of the screen as is available to it. In your application, you may prefer to take a portion of the screen or even rework all the code written above into a fragment instead. For now, we’ll stick to CoPilot taking the entire view. Once the XML is complete, it’s time to write a function to display CoPilot. Add the following to the class that will display CoPilot:

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     View copilotView = CopilotMgr.View;


            copilotView.RequestFocus();
            return copilotView;

}

.NET Maui

The steps to integrate CPIK for .NET MAUI for Android are the same as the .NET Android instructions above. Whether you are adding CPIKWrapper.dll or NuGet you need to make sure you add it to net7.0-android.

The directory in the Skeleton app

iOS .NET

Step 1: Download the CPIK iOS files

CoPilot files can be downloaded from the Partner Portal. Once logged in, navigate to B2B > CPIK > iOS > .NET.

Note
When downloading files, be sure to download the latest version of CoPilot and to only include files from that version in your project.

The CPIK libraries package includes the following:

Sample App

  • Source code of the sample application
  • Sample application APK that can be installed on an iOS device

Libraries & Resources

  • Libs/CPIKBinding.dll: Your application uses this library to integrate CPIK libraries.
  • Native libs/CoPilotIntegrationKit.framework: Your application uses this framework alongside the CPIKBinding.dll to use the CPIK libraries.
  • Asset/copilot_resources.bundle

Note: When downloading files, be sure to download the latest version of CoPilot and to only include files from that version in your project. The .Net interface is available for the iOS platform. This interface results in all iOS compatible APIs being supported within .Net iOS. It has not been noted on individual APIs that they are also compatible on .Net via this interface as it is always true unless stated otherwise.

Sample app

Source Code

  1. Open the CPIK_Net.sln from Sample App/Source Code/CPIK_Net.sln in Visual Studio 2022. It contains all of the information required to run CoPilot (i.e. libraries, assets, etc.).
  2. You can run com.alk.CPIKNetSampleApp.ipa to install the sample app directly into the device.

Libraries & Resources

Libs /CPIKBinding.dll

This CPIKBinding.dll is a wrapper for the CPIK libraries created by using the .Net iOS Binding Library project. You need to add a reference to this library in your application.

Native libs/CoPilotIntegrationKit.framework

This is the framework containing the CPIK APIs that the CPIKBinding.dll uses. You need to add this as a “native reference” in your project.

Assets

Copy Library and Resource/assets/copilot_resources.bundle into your project. Copy the entire assets folder located under Library and Resource/assets/ to {Your project}/Resources/ folder in your project.

The assets folder contains vital information to run CoPilot (i.e. theme, config files, skins, etc). If you have an existing assets folder in your project, please merge the content. Make sure that the entire folder under Assets is added to the .Net project and set BuildAction to BundleResource.

Step 2: Library integration instructions

Setup instructions:

  1. Reference Library & Resource/libs/ CPIKBinding.dll in your project.
  2. Reference Library & Resource/native libs/CoPilotIntegrationKit.framework in your project as a “native reference”.
  3. Extract the Library & Resource/assets/copilot_resources.bundle folder from the library package into your project (usually {Your project}/Resources/). Make sure to set BuildAction to BundleResource.

Sample app

Use the included sample application as a guide. This sample application is meant to demonstrate how to properly integrate CoPilot into your application. If you’re just getting started, take a look at MainAPIListViewController.cs and Appdelegate.cs. They demonstrate how to register and receive the callbacks as well as how to launch the different screens.

API Documentation

The API documentation detailed on this site references the classes and their members. It also contains the signature of each member of the classes, including description and usage. The documentation contains syntax for Java and Objective C. Developers can easily map the relevant syntax with C# in .Net. You can also check the syntax in .Net by exploring CPIKBinding.dll by adding a reference in your project.

Step 3: Initialize CPIK libraries and insert the CoPilot view

The following steps show the code changes required to initialize the CPIK libraries framework and display the CoPilot navigation app by inserting its UIView into your application’s view stack. The CPIK libraries framework is accessed through a shared singleton object. The caller is not responsible for creating or managing the memory for this object. Memory will be allocated the first time the application accesses the object and will be released when the application exits.

A pointer to the CPIK libraries framework object of type CoPilot is obtained by calling the CoPilot SharedManager class method. The object returned by this method can be stored by the calling application, however memory management calls such as retain or release will have no effect on the object.

Step A: Import the CPIK libraries header file

The file CoPilotIntegrationKit.h imports all header files necessary for working with CPIK libraries. This file should be imported in any files that will access the CPIK libraries framework. Here is an example from our sample application:

using CoPilotIntegrationKit/CoPilotIntegrationKit
using Foundation;
using UIKit;
using System;
using System.IO;
using CoPilotIntegrationKit;
using System.Linq;

Include CoPilotIntegrationKit in any source file which uses CPIK libraries API.

Step B: Set the CoPilot delegate and start CoPilot

The CoPilot application is started by making a call to the CoPilot instance StartNavApp() method. When this method is called, CoPilot will begin loading resources, open the GPS device, and begin drawing to its UIView.

The start-up process for CoPilot is performed on a separate thread so this method will return immediately, however the CPIK libraries API methods cannot be called until CoPilot has finished starting up. Any call to the CPIK libraries functions before CoPilot has finished initializing will result in an exception.

When CoPilot has finished initializing, it will notify the calling application calling the delegate method onCPStartup. Here is an example from the sample app.

public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
        {
            //store temporary pointer to shared CoPilot object
            CoPilot coPilot = CoPilot.SharedManager;


            //Set the CoPilot delegate
            coPilot.WeakDelegate = this;
            coPilot.StartNavApp();


            return true;
        }

Setup CoPilot delegate and start CoPilot

And to receive the onCPStartup callback:

[Export("onCPStartup")]
        public void OnCPStartup()
        {
            if (CallbackUtil.IsCallbackEnabled(CallbackUtil.CallbackDelegate.OnCPStartup))
                Util.DisplayMessage("", "OnCPStartup called");
        }

Step C: Display CoPilot

The CoPilot class contains a UIViewController property named CopilotViewController which represents the root view controller of the CoPilot navigation app. This view controller can be used in your application like any other typical UIViewController. It can be displayed on the screen using the UIViewController presentViewController method, the UINavigationController PushViewController method, or any other methods that add a UIViewController to the view controller stack.

 public partial class ViewController : UIViewController
    {


        protected ViewController(IntPtr handle) : base(handle)
        {
            // Note: this .ctor should not contain any initialization logic.
        }


        partial void ShowCP()
        {
            UIViewController cpVC = CoPilot.SharedManager.CopilotViewController;
            this.NavigationController.PushViewController(cpVC, true);
        }
}

Manipulating the CopilotViewController’s view directly is strongly discouraged, because CoPilot needs to respond to certain events, such as UIInterfaceOrientation changes, and these events are handled at the view controller level.

Last updated January 7, 2026.
CoPilot Version:

Contents