Setting up the project
This section describes the first steps to integrate the Onegini iOS SDK with an existing iOS project.
Adding the SDK to your project
There are two ways to add the iOS SDK to your project. Manually or through CocoaPods as a Pod.
Cocoapods
CocoaPods is the preferred way to add the Onegini SDK to your project. It provides the most convenience and ease of use. You don't have to manually change your Xcode project file.
Install the CocoaPods Artifactory plugin
The Onegini SDK is uploaded to the Onegini Artifactory repository. In order to let CocoaPods use an Artifactory repository you need to install a specific plugin.
gem install cocoapods-art
Note: It is strongly recommended that you install CocoaPods as a Rubygem and not through Homebrew. Installing with Homebrew may cause issues with the CocoaPods hooks mechanism that the plugin relies on.
Setup authentication
The Onegini SDK repository is not a public repository. You must provide credentials in order to access the repo.
Create a file named .netrc in your Home folder (~/
) and add the following contents to it:
machine repo.onegini.com
login <username>
password <password>
Replace the <username>
and <password>
with the credentials that you use to login to support.onegini.com.
Add the OneginiSDK to your Podfile
Adding the OneginiSDK to your Podfile is done in two steps. First you need to add the cocoapods-art
plugin as a plugin in your Podfile
.
plugin 'cocoapods-art', :sources => [
'onegini'
]
Second you need to add the Onegini SDK as a Pod in one of your project targets.
target 'OneginiExampleApp' do
pod 'OneginiSDKiOS', '10.0.0'
end
This way after running pod install
command, OneginiSDKiOS.framework
and OneginiCrypto.framework
will be added to the project.
Adding and updating the onegini
CocoaPods repository
The Onegini CocoaPods repository must be added to your local machine using the following command.
pod repo-art add onegini https://repo.onegini.com/artifactory/api/pods/cocoapods-public
In order to update the Repository you must manually perform an update
pod repo-art update onegini
Note: It is a good habbit to perform
pod repo-art update onegini
every once in a while just as you are doing it with the CocoaPods master repository.
Manually
Copy the Onegini SDK framework into the Frameworks group of the project workspace. Add the OneginiSDKiOS.framework
and the OneginiCrypto.framework
to the "Link Binary With Libraries" section of the Build Phases and add it as an "Embedded binary" to the app target within "General" tab.
The result should look similar to the following example:
Build Settings
Currently its only required to disable the bitcode for the application using the Onegini SDK. It is done by setting the Enable bitcode
to No
value within
the Build Settings
.
Archiving
Onegini SDK is distributed as a fat framework, which means that it cotains symbols for both iOS devices and Simulators. This way juggling between two builds
of the framework is not necessary. However Apple does not allow distribution of apps containing simulator symbols. Unfortunetaly Xcode will not do it for you
(like Cocoapods does), it needs to be done as an additional step before distribution. The issue can be solved by adding the following script as a Run Script
in Build Phases
:
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
done
SDK configuration
Before the SDK can be used in an application it needs to be configured. E.g. you need to tell it the location (URL) of the Token Server instance, but also some of the security features need to be configured. There are two ways of the providing configuration:
- Manually
- Using the SDK Configurator
The latter is the preferred way of working since it does not require the manual steps described in the paragraph below. The SDK configurator can be found on GitHub.
Manual configuration
The paragraphs below explain how to manually configure the SDK.
Configuration model
The SDK relies on a set of configuration parameters which must be provided to the SDK by means of an instance of ONGConfigModel
. The backing data model of
the ONGConfigModel
is a property list. The App is responsible for creating an instance of the ONGConfigModel
with a backing property list and the app also
needs to provide it to the ONGClientBuilder
. Initialization of ONGConfigModel
is described here.
Certificate pinning
Certificates used by the SDK are secured from tampering. In order for the SDK to detect certificate tampering it is required to perform Certificate Pinning.
Instantiating the SDK
The whole functionality of the SDK is accessed by means of a single shared client which is named ONGClient
. The client must be instantiated once early
in the App lifecycle and thereafter only referred to by it's shared instance. This is usually done in the root view controller but can also be done in a
specific non UI class. In order to instantiate SDK ONGConfigModel
containing the configuration parameters and an array of PEM Base64 encoded X509 certificates
has to be provided to the ONGClientBuilder
. This class is the only way to instruct SDK about configuration, X509-encoded certificates and other settings.
After instantiating the shared instance of ONGClient
it is required to call its start: method. In this method the client verifies integrity and performs
validation and registration calls, the result is returned in callback. You need to wait until the start method completes before proceeding with using the Onegini SDK.
Accessing ONGDeviceClient
and ONGUserClient
(both as shared instances or ONGClient
properties) before calling start: method will raise NSInternalInconsistencyException.
Example of the ONGClient
initialization:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
NSString *const certificate = @"AaXeRCk/luuGtm87fM04wO+mPZn+C+mv626PAcwDj1hKvTfIPWhRRH224hoFiB85ccsJP81cqcdnUl4XmGFO3";
NSString *configPath = [[NSBundle mainBundle] pathForResource:@"config" ofType:@"plist"];
ONGConfigModel *configModel = [[ONGConfigModel alloc] initWithContentsOfFile:configPath];
[[[[ONGClientBuilder new] setConfigModel:configModel] setX509PEMCertificates:@[certificate]] build];
[[ONGClient sharedInstance] start:^(BOOL result, NSError *error) {
if (error != nil) {
if (ONGGenericErrorOutdatedApplication == error.code) {
[self showAlertWithTitle:@"Application disabled" message:@"The application version is no longer valid, please visit the app store to update your application"];
}
if (ONGGenericErrorOutdatedOS == error.code) {
[self showAlertWithTitle:@"OS outdated" message:@"The operating system that you use is no longer valid, please update your OS."];
}
}
}];
...
}
Configuration via SDK configurator
Once configurator has generated and added the OneginiConfigModel
class to your App, you can instantiate SDK by calling
the -[ONGClientBuilder build]
method. It automatically finds the OneginiConfigModel
in order to configure SDK correctly.
Example of the ONGClient
initialization:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[[ONGClientBuilder new] build];
[[ONGClient sharedInstance] start:^(BOOL result, NSError *error) {
if (error != nil) {
if (ONGGenericErrorOutdatedApplication == error.code) {
[self showAlertWithTitle:@"Application disabled" message:@"The application version is no longer valid, please visit the app store to update your application"];
}
if (ONGGenericErrorOutdatedOS == error.code) {
[self showAlertWithTitle:@"OS outdated" message:@"The operating system that you use is no longer valid, please update your OS."];
}
}
}];
...
}
Important additional information
Using the security controls during development
Please note that the iOS SDK has the ability to detect if the app works in debug mode or with a debugger attached. This feature is enabled by default. When debug mode detection is enabled and a debugger is detected (which is most likely the case if you run your app in an simulator), the SDK will not allow to execute any of the user related flows and return an error. To disable this feature during development please follow the security controls guide.
Configuring the Application Signature
Depending on the Application Integrity level you use you might need to obtain the App ID and store it in the Token Server. The App ID should not change for the app very often however if for any reason Application Signature verification is hampring the development its recommended to create new application version with Integrity level
set to None
for the duration of development.
Resetting the SDK
After starting the SDK there is a possibility to reset the SDK to state after completing the start method. Reset will clear all of the access tokens stored in memory and all of the challenges waiting for responses from the application. Client credentials will be revalidated and the client configuration will be refreshed. You can do that by calling reset
method from ONGClient
.
[[ONGClient sharedInstance] reset:^(BOOL result, NSError *error) {
if (error != nil) {
// Errors will be from the ONGGenericErrorDomain
}
}];
...