Please make sure before updating to SDK 3.0.0
that you don't need to support devices with firmware < 4.0
.
As of version 3.0.0
only devices with firmware 4.0
or higher will be supported.
To configure Kontakt.io Devices please use our new iOS Administration App or iOS Kio Gateway Installer.
You can find our demos and sample code in Examples folder.
This document shows you a quick way to start using the Kontakt.io SDK in location-aware apps. You will find code examples for core features and best practices that we recommend developers follow.
You can find more detailed information in the Appledocs.
To use the Kontakt.io SDK in your project, the minimum deployment target must be iOS 12.0.
You can add Kontakt.io SDK to an Xcode project by adding it as a package dependency.
- From the File menu, select Add Packages...
- Enter "https://github.com/kontaktio/kontakt-ios-sdk" into the package repository URL text field
- Add KontaktSDK directly to your application.
- Open up Terminal,
cd
into your top-level project directory, and run the following command if your project is not initialized as a git repository:
$ git init
- Add Kontakt.io SDK as a git submodule by running the following command:
$ git submodule add https://github.com/kontaktio/kontakt-ios-sdk.git
-
Open the new
kontakt-ios-sdk
folder, and drag theKontaktSDK.framework
into the Project Navigator of your application's Xcode project.- Make sure your target is checked in
Add to targets
section.
- Make sure your target is checked in
-
Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar.
-
In the tab bar at the top of that window, open the "General" panel.
-
Click on the
+
button under the "Embedded Binaries" section. -
Select the
KontaktSDK.framework
and clickAdd
button. -
In the Build Phases tab, click the + button at the top and select “New Run Script Phase”. Enter the following code into the script text field:
bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/KontaktSDK.framework/strip-frameworks.sh"
(The last step, courtesy of Realm, is required for working around an iOS App Store bug when archiving universal binaries.)
Our SDK uses nullability and generics annotations added in Xcode 13 which means that the Kontakt.io iOS SDK is very easy to use with swift.
Create a new header file from the File menu and name it YourProjectName-Bridging-Header.h.
Add the following import to your YourProjectName-Bridging-Header.h:
#import <KontaktSDK/KontaktSDK.h>
###Further information
For your app to work correctly you have to add a new key to your project's plist file.
- In the project navigator, select your project.
- Select your projects Info.plist file
- Add the following key string pair to the file.
<key>NSLocationAlwaysUsageDescription</key>
<string>Required for ios 8 compatibilty</string>
The string can be empty, the content is not important.
New SDK requires API Key to be specified. You can get it by registering a free account at https://panel.kontakt.io.
Objective-C
#import <KontaktSDK/KontaktSDK.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Set API Key
[Kontakt setAPIKey:@"Your API Key"];
return YES;
}
Swift
import KontaktSDK
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Set API Key
Kontakt.setAPIKey("Your API Key")
return true
}
In the following example we'll show you how to can create a simple application to monitor beacons for a specific region using the Kontakt.io SDK.
In our example, we have used the AppDelegate.m class for simplicity. You would probably want to create your own class in a real application.
First we'll import the Kontakt.io SDK.
#import <KontaktSDK/KontaktSDK.h>
We'll add the KTKBeaconManager object as a property.
KTKBeaconManager informs its delegates when a device enters or exits a region, and when beacons are ranged.
@property KTKBeaconManager *beaconManager;
Make sure AppDelegate
conforms to KTKBeaconManagerDelegate
protocol.
@interface AppDelegate () <KTKBeaconManagerDelegate>
We will use application:didFinishLaunchingWithOptions:
to initiate beacon manager and start monitoring for region.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Set API Key
[Kontakt setAPIKey:@"Your API Key"];
// Initiate Beacon Manager
self.beaconManager = [[KTKBeaconManager alloc] initWithDelegate:self];
// Request Location Authorization
[self.beaconManager requestLocationAlwaysAuthorization];
...
return YES;
}
You can test if the current device is capable of monitoring beacons using:
if ([KTKBeaconManager isMonitoringAvailable]) {
}
or check authorization status using:
if ([KTKBeaconManager locationAuthorizationStatus] == kCLAuthorizationStatusAuthorizedAlways) {
}
Now we'll start monitoring a specific region.
For more information on KTKBeaconRegion see Appledoc.
Regions define a set of beacons that your application is aware of, so the beacon manager will interact only with those beacons.
// Kontakt.io proximity UUID
NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:@"f7826da6-4fa2-4e98-8024-bc5b71e0893e"];
// Create region instance
KTKBeaconRegion *region = [[KTKBeaconRegion alloc] initWithProximityUUID: proximityUUID identifier:@"identifier"];
// Start Monitoring
[self.beaconManager startMonitoringForRegion: region];
// You can also start ranging ...
[self.beaconManager startRangingBeaconsInRegion: region];
Secure beacon region is very similar to standard beacon region. For more information on KTKSecureBeaconRegion see Appledoc.
Read more about security and shuffling on our support page.
You can find your beacon's Secure Proximity UUID in Kontakt.io Web Panel (in the Security Section).
// Your secure proximity UUID
NSUUID *secureProximityUUID = [[NSUUID alloc] initWithUUIDString:@"00000000-0000-0000-0000-00000000"];
// Create secure region instance
KTKSecureBeaconRegion *region = [[KTKSecureBeaconRegion alloc] initWithSecureProximityUUID:secureProximityUUID identifier:@"identifier_secure"];
You can also use an unsecure proximity UUID and it will be translated to the secure proximity by calling Cloud API under the hood.
// Kontakt.io proximity UUID
NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:@"f7826da6-4fa2-4e98-8024-bc5b71e0893e"];
// Create secure region instance with your non secure proximity
KTKSecureBeaconRegion *region = [[KTKSecureBeaconRegion alloc] initWithProximityUUID: proximityUUID identifier:@"identifier"];
Now we'll add the the delegate methods for beaconManager, and get them to log some output. All delegate methods can be found in KTKBeaconManagerDelegate documentation.
- (void)beaconManager:(KTKBeaconManager*)manager didChangeLocationAuthorizationStatus:(CLAuthorizationStatus)status;
{
// ...
}
- (void)beaconManager:(KTKBeaconManager*)manager didEnterRegion:(__kindof KTKBeaconRegion*)region
{
NSLog(@"Enter region %@", region);
}
- (void)beaconManager:(KTKBeaconManager*)manager didExitRegion:(__kindof KTKBeaconRegion*)region
{
NSLog(@"Exit region %@", region);
}
- (void)beaconManager:(KTKBeaconManager*)manager didRangeBeacons:(NSArray <CLBeacon *>*)beacons inRegion:(__kindof KTKBeaconRegion*)region
{
NSLog(@"Ranged beacons count: %lu", [beacons count]);
}
When using Swift the final class should look like the following:
import UIKit
import KontaktSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var beaconManager: KTKBeaconManager!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Set API Key
Kontakt.setAPIKey("API Key")
// Initiate Beacon Manager
beaconManager = KTKBeaconManager(delegate: self)
beaconManager.requestLocationAlwaysAuthorization()
// Region
let proximityUUID = NSUUID(UUIDString: "f7826da6-4fa2-4e98-8024-bc5b71e0893e")
let region = KTKBeaconRegion(proximityUUID: proximityUUID!, identifier: "region")
// Start Monitoring and Ranging
beaconManager.startMonitoringForRegion(region)
beaconManager.startRangingBeaconsInRegion(region)
return true
}
}
extension AppDelegate: KTKBeaconManagerDelegate {
func beaconManager(manager: KTKBeaconManager, didChangeLocationAuthorizationStatus status: CLAuthorizationStatus) {
}
func beaconManager(manager: KTKBeaconManager, didEnterRegion region: KTKBeaconRegion) {
print("Enter region \(region)")
}
func beaconManager(manager: KTKBeaconManager, didExitRegion region: KTKBeaconRegion) {
print("Exit region \(region)")
}
func beaconManager(manager: KTKBeaconManager, didRangeBeacons beacons: [CLBeacon], inRegion region: KTKBeaconRegion) {
print("Ranged beacons count: \(beacons.count)")
}
}
You won't be able to run apps that use Apple Core Location services (that includes our SDK) on the Simulator, so first, you'll need to connect a physical iOS device to run your app.
- Connect an iOS device to your Mac.
- In the project navigator, choose your device from the scheme pop-up menu. Xcode assumes you intend to use the selected device for development and automatically registers it for you.
- Click the Run button.
Check out Apple's guide to Launching Your App on Devices for more details.
KTKEddystoneManager is key to retrieving Eddystone format beacon information.
KTKEddystoneManager
can discover nearby Eddystone format devices using regions/filters to narrow results.
@interface ViewController () <KTKEddystoneManagerDelegate>
@property KTKEddystoneManager *eddystoneManager;
@property KTKEddystoneRegion *namespaceRegion;
@property KTKEddystoneRegion *domainRegion;
@property KTKSecureEddystoneRegion *secureNamespaceRegion;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Eddystone Manager
self.eddystoneManager = [[KTKEddystoneManager alloc] initWithDelegate:self];
}
In this example we will start discovering Eddystone devices in viewWillAppear:
method and stop in viewWillDisappear:
.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// If should scan for all nearby Eddystones
// Passing nil will look for all regions
[self.eddystoneManager startEddystoneDiscoveryInRegion:nil];
// Scan for Eddystones with specific namespace ID
self.namespaceRegion = [[KTKEddystoneRegion alloc] initWithNamespaceID:@"namespaceID"];
[self.eddystoneManager startEddystoneDiscoveryInRegion: self.namespaceRegion];
// Scan for Eddystone with specific domain in url
self.domainRegion = [[KTKEddystoneRegion alloc] initWithURLDomain:@"github.com"];
[self.eddystoneManager startEddystoneDiscoveryInRegion: self.domainRegion];
// Scan for Secure Namespace Region
self.secureNamespaceRegion = [[KTKSecureEddystoneRegion alloc] initWithSecureNamespaceID:@"secure_namespace_id"];
[self.eddystoneManager startEddystoneDiscoveryInRegion: self.secureNamespaceRegion];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// Stop
[self.eddystoneManager stopEddystoneDiscoveryInAllRegions];
// ... or you can just stop for one specific region by using
[self.eddystoneManager stopEddystoneDiscoveryInRegion: self.domainRegion];
}
Read more about security and shuffling on our support page.
All delegate methods can be found in KTKEddystoneManagerDelegate documentation.
- (void)eddystoneManager:(KTKEddystoneManager *)manager didDiscoverEddystones:(NSSet <KTKEddystone*>*)eddystones inRegion:(__kindof KTKEddystoneRegion* _Nullable)region
{
if ([region isEqual:self.domainRegion]) {
// Eddystone discovered with URL in `github.com` domain ...
}
}
The Kontakt.io Rest API provides a series of resources to query/update our cloud platform and allow you to manage your venues and beacons, and retrieve beacon actions.
Class responsible for communication with API is KTKCloudClient.
You can initialize it by calling ...
KTKCloudClient *client = [KTKCloudClient new];
or use shared instance (singleton) used by the SDK API calls ...
KTKCloudClient *client = [KTKCloudClient sharedInstance];
If specific NSURLSessionConfiguration
configuration is required you can use:
KTKCloudClient *client = [[KTKCloudClient alloc] initWithSessionConfiguration: ...];
API Key must be provided before calling any method from KTKCloudClient
.
[Kontakt setAPIKey:@"Your API Key"];
After initialization; KTKCloudClient
object acts as a facade between your app and Kontakt.io services. You can use it to get actions, beacons, and venues assigned to your company (and much more).
Getting list of devices is as simple as ...
Objective-C
[[KTKCloudClient sharedInstance] getObjects:[KTKDevice class] completion:^(KTKKontaktResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"%@". [response objects]);
}];
or in Swift
KTKCloudClient.sharedInstance().getObjects(KTKDevice.self) { response, error in
print(response?.objects)
}
// Get Venues
KTKCloudClient.sharedInstance().getObjects(KTKVenue.self) { response, error in
print(response?.objects)
}
To create, update or delete objects you can use one of provided methods:
- createObject:completion:
- updateObject:completion:
- deleteObject:completion: or deleteObject:primaryKey:completion:
All classes representing objects from the API conforms to protocol KTKCloudModel
.
All Cloud Client responses are wrapped with KTKKontaktResponse. KTKKontaktResponse
provides more context for the result. You can for example get next set of the results using nextResultsURL
property like:
// Get Device by unique ID ...
NSDictionary *parameters = @{ @"uniqueId": @"K0nT" };
[[KTKCloudClient sharedInstance] getObjects:[KTKDevice class] parameters:parameters completion:^(KTKKontaktResponse * _Nullable response, NSError * _Nullable error) {
// Check for errors etc ...
// Call next result set ..
[[KTKCloudClient sharedInstance] GET:response.nextResultsURL completion:^(KTKKontaktResponse * _Nullable response, NSError * _Nullable error) {
// ... more results ?
}];
}];
If there is a custom call you would like to make to the API you can use:
Both methods take endpoint name parameter and HTTP parameters dictionary.
You can find more information in the Appledocs KTKCloudClient class reference.
The Kontakt.io iOS SDK contains classes and methods that let you easily connect to a Kontakt.io device, read its parameters, and modify some of them. First however, you need to scan for nearby devices.
@property KTKDevicesManager *devicesManager;
...
self.devicesManager = [[KTKDevicesManager alloc] initWithDelegate: self];
// Calling `startDevicesDiscoveryWithInterval:` will report devices every `interval` value you specify.
[self.devicesManager startDevicesDiscoveryWithInterval:2.0];
// Calling `startDevicesDiscovery` will report devices in real time.
[self.devicesManager startDevicesDiscovery];
KTKDevicesManager informs its delegate about devices currently in range.
All delegate methods can be found in KTKDevicesManagerDelegate documentation.
#pragma mark - KTKDevicesManagerDelegate method
- (void)devicesManager:(KTKDevicesManager*)manager didDiscoverDevices:(NSArray <KTKNearbyDevice*>* _Nullable)devices;
// Do something with devices.
}
Nearby Devices discovered by KTKDevicesManager are of KTKNearbyDevice class.
Changing KTKNearbyDevice configuration requires KTKDeviceConnection and it is as simple as:
Objective-C
// Create Configuration
KTKDeviceConfiguration *configuration = [KTKDeviceConfiguration new];
configuration.name = @"Disco Beacon";
configuration.advertisingInterval = @350;
configuration.major = @123;
// Connection
KTKDeviceConnection *connection = [[KTKDeviceConnection alloc] initWithNearbyDevice: nearbyDevice];
// Write Cofiguration
[connection writeConfiguration:configuration completion:^(BOOL synchronized, KTKDeviceConfiguration * _Nullable configuration, NSError * _Nullable error) {
// Process response
}];
Swift
// Create Configuration
let configuration = KTKDeviceConfiguration()
configuration.name = "Disco Beacon"
configuration.advertisingInterval = 350
configuration.major = 123
// Connection
let deviceConnection = KTKDeviceConnection(nearbyDevice: device)
// Write Cofiguration
deviceConnection.writeConfiguration(configuration) { synchronized, configuration, error in
// Process response
}
More code samples and scenarios will be covered in our sample project on github.
Kontakt.io iOS SDK makes extensive use of two native iOS frameworks: Core Location and Core Bluetooth. It is important to understand that although both of them use Bluetooth Low Energy, they are separate technologies and do not have much in common.