Categories
developer documentation v0.0.27
mimik Developer Documentation
  • Tutorials
  • Working with edgeEngine in an iOS project

Working with edgeEngine in an iOS project

Objective

The objective of this article is to demonstrate how to use the mimik Client Library interfaces when working with the edgeEngine Runtime in an iOS project.

Intended Readers

The intended readers of this document are iOS software developers, who want to familiarize themselves with the basics of mimik Client Library interfaces, specifically methods for interfacing with the edgeEngine Runtime.

What You'll Be Doing

In this tutorial you'll be covering the following topics that are relevant to using the mimik Client Library edgeEngine interfaces:

  • Starting edgeEngine
  • Stopping edgeEngine
  • Creating an Access Token
  • Retrieving Runtime Information
  • Resetting edgeEngine
  • Lifecycle Management
  • Working with an iOS Simulator

Technical Prerequisites

This article has the following technical prerequisites:

  • A device running the latest iOS version.
  • A familiarity with working with mimik Client Library components as described in this Key Concepts article.
NOTE:

Working with the iOS Simulator and the mimik Client Libraries entails some special consideration. For more more information about iOS Simulator support see this tutorial.

Starting edgeEngine

Once the mimik Client Library components have been Integrated and initialized into your project, we can get into the specifics of working with the edgeEngine Runtime.

You can think of edgeEngine as a host platform where edge microservices are deployed to. Also, edgeEngine provides http interfaces to the iOS application in order to do various tasks.

One prerequisite for being able to call the edge microservice interfaces is that the edgeEngine needs to be in a running state. The code example below in Listing 1 shows you how to do this. An explanation of the code follows.


1: func startEdgeEngine() async -> Result<Bool, NSError> {
2: // edgeEngine license from mimik Developer Portal
3: let edgeEngineLicense = <EDGE_ENGINE_LICENSE>
4:
5: // Use the MIMIKStartupParameters object to configure the edgeEngine Runtime startup behavior
6: let startupParameters = MIMIKStartupParameters(license: edgeEngineLicense)
7:
8: // Calling mimik Client Library Engine component
9: switch await self.edgeEngine.startEdgeEngine(startupParameters: startupParameters) {
10: case .success:
11: print("Success starting edgeEngine")
12: // Startup was successful, returning success
13: return .success(true)
14: case .failure(let error):
15: print("Error starting edgeEngine", error.localizedDescription)
16: // Startup was unsuccessful, returning error
17: return .failure(error)
18: }
19: }

Listing 1: Starting edgeEngine


First, we get our edgeEngine license from mimik Developer Portal and set the value at Line 3. (The article Working with edgeEngine in an iOS project provides the details about obtaining an edgeEngine license.)

Next, we set the edgeEngine Runtime configuration object at Line 6 by calling MIMIKStartupParameters(license: edgeEngineLicense). There are additional startup parameters available, but for the purpose of this article, only the license parameter will be used.

Then, we call the startEdgeEngine() method of the mimik Client Library Engine component at Line 9, which requires a value for the parameter named startupParameters

WHERE

startupParametersis the configuration object we set at Line 6

NOTE:
To learn more about the edgeEngine configuration parameters, see the MIMIKStartupParameters class in the code documentation.

After the call, we validate the result.

If the edgeEngine startup is successful, we return a success at Line 13.

If there is an issue, we return an error at Line 17.

NOTE:
Repeat startEdgeEngine() calls have no further effect. Learn more about managing the edgeEngine lifecycle in the section titled Lifecycle Management Management below

[EDITOR: What was the intention of ** next to Management above?]

Stopping edgeEngine

Sometimes developers want to shut the edgeEngine Runtime down manually. For example, when a developer opts out from the automatic lifecycle management, or when the user wants to clear out all their data after a logout. The code example below shows you how to do this.

We call the stopEdgeEngine() method of the mimik Client Library Engine component and that's it. There are no values returned, nor there is a need to do any validation. Once the library method returns, the edgeEngine is no longer in a running state.

1: func stopEdgeEngine() async {
2: // Calling mimik Client Library Engine component
3: self.edgeEngine.stopEdgeEngine()
4: }
NOTE:
Due to the nature of the edgeEngine shutdown process, this call blocks the main thread for its duration. Repeat stopEdgeEngine() calls have no further effect. Learn more about managing the edgeEngine lifecycle in the section Lifecycle Management below.

Creating an Access Token

Most of the edgeEngine Runtime functions require an Access Token for their operations. The Access Token is based on the developer ID Token generated at the mimik Developer Portal. The code example below in Listing 2 shows you how to do this.


1: func authenticateEdgeEngine() async -> Result<String, NSError> {
2: // Developer ID Token from mimik Developer Portal
3: let developerIdToken = <DEVELOPER_ID_TOKEN>
4:
5: // Calling mimik Client Library method to get the Access Token for edgeEngine access
6: switch await self.edgeClient.authenticateDeveloperAccess(developerIdToken: developerIdToken) {
7: case .success(let authorization):
8:
9: // Authentication was unsuccessful, returning error
10: guard let accessToken = authorization.userAccessToken() else {
11: // Authentication was unsuccessful, returning error
12: return .failure(NSError.init(domain: "Error", code: 500))
13: }
14:
15: print("Success. Access Token:", accessToken)
16: // Authentication was successful, returning Access Token
17: return .success(accessToken)
18: case .failure(let error):
19: print("Error", error.localizedDescription)
20: // Authentication was unsuccessful, returning error
21: return .failure(error)
22: }
23: }

Listing 2: Authenticating to edgeEngine


First, we get our developer ID Token from mimik Developer Portal and set the value at Line 3. (For more information about the Developer ID Token read the section, Getting the developer ID Token and client ID from mimik Developer Portal in the tutorial Getting the edgeEngine license and Identity server values from mimik Developer Portal.)

Next, we call the authenticateDeveloperAccess() method of the mimik Client Library Engine component at Line 6, which requires the developerIdToken parameter

WHERE developerIdToken is the developer ID Token we set at Line 3 in Listing 2 above.

After the call is made, we validate the result by attempting to extract the Access Token from the authorization at Line 10. If successful, we print and return the Access Token at Lines 15 and 17.

If there is an issue, we return an error at Lines 12 or 21.

NOTE:
This authentication method is meant for developer access only. For enterprise solutions, including user access tokens for backend access, contact mimik support

Retrieving Runtime Information

Sometimes developers need to find out more details about the edgeEngine Runtime system information, such as its version, account or node information. The code example in Listing 3 below shows you how to do this. An explanation follows.


1: // The async return is either a success with a JSON object containing edgeEngine Runtime information values, or a failure with an error.
2: func edgeEngineInfo() async -> Result<Any, NSError> {
3: // Calling mimik Client Library Engine component
4: switch await self.edgeClient.edgeEngineInfo() {
5: case .success(let info):
6: print("Success", info)
7: // Success getting edgeEngine Runtime information, returning the value
8: return .success(info)
9: case .failure(let error):
10: // There was an issue, returning the error
11: print("Error", error.localizedDescription)
12: return .failure(error)
13: }
14: }

Listing 3: Getting information about edgeEngine at runtime


First, we call the edgeEngineInfo() method of the mimik Client Library Engine component on Line 4.

After the call, we validate the result at Lines 5-13.

If edgeEngine information is received, we return a success at Line 8.

If there is an issue, we return an error at Line 12.

An asynchronous call to self.edgeClient.edgeEngineInfo() as shown at Line 4 in Listing 3 above returns an info object. The information return in the info object is similar to the following:

{
"supernodeTypeName" : "_mk-v15-4247._tcp",
"nodeId" : "1234567890",
"accountId" : "1234567890",
"version" : "vX.Y.Z",
"linkLocalIp" : "192.168.1.47"
}

Resetting edgeEngine

When it comes to clearing out user data, developers need to shut down the edgeEngine Runtime and then erase all content stored in its working directory. The code example in Listing 4 below shows you how to do this with one call. An explanation follows.


1: // Return is the result of the erase call
2: func resetEdgeEngine() async -> Bool {
3: // Calling mimik Client Library Engine component
4: switch self.edgeEngine.resetEdgeEngine() {
5: case true:
6: print("Success")
7: // Reset is successful, returning success
8: return true
9: case false:
10: print("Error")
11: // Reset is unsuccessful, returning error
12: return false
13: }
14: }

Listing 4: Resetting edgeEngine


First, we call the resetEdgeEngine() method of the mimik Client Library Engine component on Line 4.

After the call, we validate the result at Lines 5-13.

If edgeEngine reset is successful, we return true at Line 8.

If there is an issue, we return false at Line 12.

NOTE:
Once edgeEngine has been reset, all deployed edge microservice stop functioning, with all their data erased as well.
NOTE:
Due to the nature of the edgeEngine shutdown process, this call blocks the main thread for its duration. Learn more about managing the edgeEngine lifecycle in the section that follows.

Lifecycle Management

When developers initialize the mimik Client Library Engine component, they opt-in to an automatic edgeEngine Runtime Lifecycle management by default. This means that the mimik Client Library will be monitoring application lifecycle notifications, and reacting to any significant changes that affect edgeEngine's ability to perform its functions.

For example, when protectedDataWillBecomeUnavailableNotification or willTerminateNotification system notifications are received, edgeEngine stop is called. When protectedDataDidBecomeAvailableNotification system notification is received, edgeEngine start is called.

Developers can opt-out of this automatic lifecycle management during the mimik Client Library Engine component initialization, by setting the manageRuntime parameter to false; for example, when they prefer to start and stop the edgeEngine Runtime manually.

The code example below shows you how to activate the automatic edgeEngine Runtime Lifecycle management:

let edgeEngine: MIMIKEdgeClientEdgeEngine = {
guard let mimikEdgeEngine = MIMIKEdgeClientEdgeEngine() else {
fatalError("Error")
}
return mimikEdgeEngine
}()

This code example shows you how to deactivate the automatic edgeEngine Runtime Lifecycle management:

let edgeEngine: MIMIKEdgeClientEdgeEngine = {
guard let mimikEdgeEngine = MIMIKEdgeClientEdgeEngine(manageRuntime: false) else {
fatalError("Error")
}
return mimikEdgeEngine
}()

Finally, this code example code shows you how to determine whether the mimik Client Library is currently managing the edgeEngine Runtime Lifecycle:

// Returns whether the edgeEngine Runtime Lifecycle is being managed by the mimik Client Library
func edgeEngineRuntimeIsManaged() -> Bool {
// Calling mimik Client Library Engine component
switch self.edgeEngine.edgeEngineRuntimeIsManaged() {
case true:
print("Success")
// edgeEngine Runtime Lifecycle is being managed by the mimik Client Library, returning true
return true
case false:
print("Error")
// edgeEngine Runtime Lifecycle is not being managed by the mimik Client Library, returning false
return false
}
}

Working with an iOS Simulator

Normally, developers intend to run their applications on iOS devices where the mimik Client Library Engine is used to facilitate the integration of the edgeEngine Runtime binary directly within the iOS application sandbox. This is done by vendoring the edgeEngine binary inside the MIMIKEdgeClientEngine pod component.

However, the inclusion of MIMIKEdgeClientEngine pod component in the iOS project prevents developers from being able to compile their project for the iOS Simulator or Mac Catalyst environments. This is because edgeEngine is a binary compiled specifically for iOS devices.

In order to remedy this, the mimik Client Library is split into its Core MIMIKEdgeClientCore and Engine MIMIKEdgeClientEngine pod components. This gives developers the choice of having the edgeEngine bundled in within the iOS application or having it running on a host platform of their choice (e.g., macOS, Linux, Windows, etc...)

So to summarize. When compiling for an iOS device, include the MIMIKEdgeClientEngine pod component in your project and use edgeEngine internally. When compiling for an iOS Simulator or Mac Catalyst environments, don't include the MIMIKEdgeClientEngine pod component in your project. Instead, run edgeEngine on an external platform, and activate edgeEngine external support in the mimik Client Library.

NOTE:
Download edgeEngine release binaries for various platforms here.

The code example below shows you how you can conditionally include the MIMIKEdgeClientEngine pod component, using two different targets.

target 'internal-edgeEngine-target' do
pod 'MIMIKEdgeClientCore'
pod 'MIMIKEdgeClientEngine'
end
target 'external-edgeEngine-target' do
pod 'MIMIKEdgeClientCore'
end

The code example below shows you how you can conditionally import MIMIKEdgeClientEngine into your class using the EXTERNAL compiler flag.

import MIMIKEdgeClientCore
#if !EXTERNAL
import MIMIKEdgeClientEngine
#endif

Next, let's assume we want to have edgeEngine running externally, for example on a macOS host, with a 192.168.4.118 IP address and 8083 port number.

NOTE:
Learn how to run edgeEngine on macOS here

Once the edgeEngine is running externally on macOS, we can activate the external edgeEngine support in the mimik Client Library, by calling the activateExternalEdgeEngine() method.

The code example below shows you how to do this.

func activateExternalEdgeEngine() -> Result<URLComponents, NSError> {
switch MIMIKEdgeClient.activateExternalEdgeEngine(host: "192.168.4.118", port: 8083) {
case .success(let urlComponents):
print("Success. urlComponents:", urlComponents)
return .success(urlComponents)
case .failure(let error):
print("Error", error.localizedDescription)
return .failure(error)
}
}

You can continue using your application and mimik Client Library normally, keeping in mind that the edgeEngine Runtime is now running externally on a host system. As a result, your iOS application doesn't have any control over its lifecycle.

Was this article helpful?

© mimik technology, Inc. all rights reserved