Favendo GmbH

Note
This document is valid for Backspin iOS SDK 1.1.0 Build 65

1. List of Functions

1.1. Provided by the iOS SDK

1.1.1. Positioning

The SDK offers iBeacon based indoor-positioning including bluloc-exclusive crypto-beacon (rolling-id mode) support. Since iOS SDK 1.1.x the positioning includes beacon-region monitoring to automatically start positioning and beacon-proximity ranging in the background once the user enters a beacon-region, without requiring the app to be active or suspended in background.

The positioning can be configured with different “accuracy”-settings for different use-cases (e.g. a power-saving-mode if positioning is in background for location-based-notifications only).

Some restrictions of iOS apply:

  • no more than 20 regions PER APP are allowed, which includes custom created geo-regions, e.g. CLCircularRegions . Each unique beacon-UUID leads to 1 region that is monitored.

    • See Apple Documentation for Region Monitoring:

    • Be judicious when specifying the set of regions to monitor. Regions are a shared system resource, and the total number of regions available systemwide is limited. For this reason, Core Location limits to 20 the number of regions that may be simultaneously monitored by a single app. To work around this limit, consider registering only those regions in the user’s immediate vicinity.

  • As mentioned in the section Custom Region Monitoring, you need to add all custom UUIDs that are monitored with an own CLLocationManager to the whitelist of BackspinSDKController: whiteListBeaconUuidsForBeaconMonitoring.

  • Background-activity in iOS (8 & 9) stops after 3 minutes, if the user does not open the app. Therefore, no beacon-proximity-notifications, location-based-messages, or location-updates will be delivered if the three minutes are expired after the beacon-region was entered. Also, the 3 minutes are just an empirical observed value, there is no officially documented time-span from Apple. You can observe it by starting a background-task and looking at the backgroundTimeRemaining property in UIApplication.

1.1.2. Navigation

Turn By Turn in Whitelabel

The SDK calculates a navigation-path from an arbitrary start- to an arbitrary target-position. For both positions the nearest navigation-path intersection is calculated and the actual routing is started from there. Optionally, if a suitable KML is provided, barrier-free navigation route calculation can be requested.

Additionally, functionality is offered to calculate turn-by-turn-directions for a given route to aid the visual output, as in the example screenshot of the Backspin whitelabel app.

1.1.3. Image Downloader & Level/Floor-Plans

Download and caching of images from the backspin-server with a custom resolution. Additionally, functionality exists to download (and cache) level-plan models including the (cached) level-plan-image download.

If the language is specified via the currentLanguageDesignator delegate method and an image for the specified language is uploaded in the dashboard, this image-downloader will download and the image in the given language. Images for each language and resolution are cached separately via NSURLCache.

1.1.4. Location Based Notifications

There are two different types of notifications supported by the SDK:

  • Beacon Proximity Range

    • this type ranges for beacons and triggers a notification if one enters or exits a range around a beacon, which is defined as IMMEDIATE, NEAR, or FAR. These values are approximations for distances around 0.5 metre, 3-5 metres, and 5+ metres. The exact distances at which the notification is fired might vary a little bit for each setup and beacon.

Note
An enter event for a notification that is defined as FAR is also triggered, if one is in the NEAR or IMMEDIATE proximity range.
  • Zone/Location-Based

    • While in the dashboard these are two distinct types “Offer”-triggered and “Venue”-triggered, these are internally handled as the same, since all notifications get the locations of the venues attached to it. If an offer does not have a linked venue, it will therefore not be processed.

    • For such a notification there are three trigger-types: Enter, Exit, and Dwelltime events. The latter will trigger if one has been a specified number of minutes (maximum 120) within the zone/location of the linked venue.

Note
since iOS stops any background-task after three minutes, any dwelltime-notification with more than 2 minutes will not fire while the app is in background-mode.

1.1.5. Apple Push Notifications / User Account

Backspin offers to send push notifications to devices via the Apple Push Notification Services (APNS). You have to enable the app in the Apple Member Center for push notifications, upload the certificate to the Backspin server and implement the UIAppDelegate callback:

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;

Forward the given deviceToken to the SDK via registerDeviceWithApnsTokenAtServer:withUserRegistrationCompletionBlock: This will also return an account-id that can be used for further functionality that is not offered by the SDK yet, but the server. See more at User Accounts.

Note
If just a user-account shall be created without APNS configuration it is also possible to hand over an empty NSData object, which creates a user-account as well. Obviously in that case no push-notifications will be received from Backspin:
[[BackspinSDKController sharedInstance] registerDeviceWithApnsTokenAtServer:[NSData data] withUserRegistrationCompletionBlock:^(NSInteger userAccountId) {
	// do something
}];

1.1.6. Analytics

For several events in the SDK, analytics-events can be generated and sent to the server. For each event-type, the automatic creation can be disabled, as well as the whole analytics-module. The following events are supported:

  • Indoor Location Updates

    • location_updated

  • Navigation Start

    • event has to be forwarded by SDK-user

    • key “navigation_started

  • Navigation Cancelled

    • event has to be forwarded by SDK-user

    • key “navigation_cancelled

  • Navigation Target reached

    • is created automatically if a navigation is started in proximity of the target

    • key “navigation_targetreached

  • Notification created

    • i.e. the notification-object is handed out to the SDK-user

    • key “notification_created

  • Notification “presented”

    • event has to be forwarded by SDK-user

    • key “notification_confirmed

By implementing the BSSDKAnalyticsTypeHandler protocol, arbitrary, custom-defined analytics-events can be sent to the server via the SDK as well by calling queueAnalyticsEventWithType:andAnalyticsData: The events will be queued and persisted until they are successfully uploaded. Note, however, that they might not be accessible via the dashboard per default.

1.1.7. Model-Store & Server-API

The Backspin iOS SDK contains a rudimentary API for the local model-store and offers to download either generic models or the plain JSON from the server. Additionally an API is provided to perform further REST actions, e.g. to utilise the User Accounts.

1.2. Additionally provided by Backspin server

The REST API offers some extended functionality that is currently not covered by the 1.1.x iOS SDK - as of its initial release (March 2016)

1.2.1. Venues and Venue Categories

Venues (shops/facilities) and venue-categories can be created and managed in the Backspin dashboard. They are provided by the REST-API:

  • /rest/v1/venues/de

  • /rest/v1/venuecategories/de

Note that venues within the venuecategories-REST-endpoint are only linked, therefore their model has to be downloaded separately with the venues-REST-endpoint (and vice-versa).

1.2.2. Venue Offers

Offer-models can be downloaded as well, any venue that is associated with an offer is only linked, its model has to be downloaded separately with the venues-REST-endpoint.

  • /rest/v1/venueoffers/de

1.2.3. User Accounts

With registering an APNS token, a user-account is created as well (see Apple Push Notifications / User Account) - the user-account offers further functions that is not yet offered in the iOS SDK. However, their description goes beyond the scope of this SDK documentation, so they are only described briefly.

There are two additional REST-endpoints that are currently not implemented in the backend to register a new user-account and login

  • /rest/v1/userregistration

  • /rest/v1/userlogin

For each app a profile-config needs to be setup in the dashboard, which structure can then be downloaded via

  • /rest/v1/profileconfig/{APPID}/de

The app-id is to be obtained from the dashboard on creating and configuring the “app”.

For the account, the profile can then be downloaded and managed via

  • /rest/v1/accounts/{ACCOUNTID}/profile/{APPID}/de

The last two endpoints is for handling saving user-favourites: Put venues on a likeables list for each account (“Favourite Shops”)

  • /rest/v1/likeables/{ACCOUNTID}/likeables/de

Put offers on a leaflet for each account

  • /rest/v1/offerleaflet/{ACCOUNTID}/de

1.2.4. Analytics

While the Backspin iOS SDK offers to queue, persist, and automatically upload analytics events, custom defined events might not be accessible for analysis via the dashboard. Therefore, the REST-endpoint provides access to all events.

  • /rest/v1/analytics/avgDistribution

  • /rest/v1/analytics/dateAvgDistribution

  • /rest/v1/analytics/dateDistribution

  • /rest/v1/analytics/groupDistribution

  • /rest/v1/analytics/xyDistribution

2. Prepare Your Project

Since v1.1+ the Backspin iOS SDK is created as dynamic framework, since it contains Swift code. Therefore, in all cases, you need to enable the “Embedded Content Contains Swift Code” setting. See underneath in the Manual Installation section.

If using the source/dependency/library manager Cocoa Pods, the installation is very straightforward. In the Podfile paste the following line:

pod 'Backspin-iOS-SDK', :podspec => "http://sdk.favendo.de/Backspin-iOS-SDK/Backspin-iOS-SDK.podspec.json"

You might need to replace the linked .podspec.json file with Backspin-iOS-SDK_1.1.0.65.podspec.json

Since Backspin iOS SDK v1.1+ the framework contains Swift code, so you have to tell CocoaPods that it shall use frameworks and only work with iOS 8.0 upward. Insert the following at the top of your Podfile:

platform :ios, "8.0"
use_frameworks!
Note
Beware, since this might also change some settings/configurations with other pods, as dynamic Frameworks are officially only supported since iOS 8 and all pods will be created as dynamic frameworks instead of static libraries as before!

2.2. Manual Installation

Without Cocoa Pods, the frameworks need to be installed manually.

Extract the ZIP and add all frameworks from the “/Framework” folder to your framework as embedded: Select your target(s), go to “General”, then drag the following frameworks from the folder above into the “Embedded Binaries” section:

  • BackspinSDK.framework

  • FavendoBackspinBackendSwift.framework

  • FavendoBackspinCoreSwift.framework

  • FavendoBackspinLBSSwift.framework

  • FavendoIndoorPositioning.framework

  • FavendoIndoorNavigation.framework

2.2.1. External Dependencies

The Backspin iOS SDK has two external framework dependencies, which need to be added to your project manually:

The framework is linked with the following versions of the frameworks:

  • AFNetworking: 3.0.0

  • CocoaLumberjack: 2.1.0

While it should work with versions lower than that, there is no guarantee that everything works as expected (e.g. AFNetworking had some API-changes since 2.x)

2.2.2. Adjust Project Settings

  1. In Xcode select your project and target.

  2. Select the Build Settings tab.

  3. Search for “Other Linker Flags” in the provided search bar.

    • Add -ObjC to the “Other Linker Flags” setting.

    • Add -l “sqlite3” to the “Other Linker Flags” setting

  4. Search for “Build Options”

  5. Set “Embedded Content Contains Swift Code” to “Yes

  6. Set “Enable Bitcode” to “No

2.2.3. Further Requirements

Add the following library / frameworks required by the Backspin iOS SDK to your Xcode project:

  • Accelerate.framework

  • AudioToolbox.framework

  • CoreBluetooth.framework

  • CoreLocation.framework

  • CoreMotion.framework

  • Foundation.framework

  • ImageIO.framework

  • MapKit.framework

  • MobileCoreServices.framework

  • Security.framework

  • SystemConfiguration.framework

  • UIKit.framework

2.3. Enable Location Services

To be able to access the current location of the user you have to ask about permission to do so. In any case, you should add “Continued use of GPS running in the background can dramatically decrease battery life.” to the App-Store description of the app, otherwise Apple might reject it.

For different platforms there are different configurations needed:

iOS 7: As of SDK Version 1.1, iOS 7 is not supported any more, due to Swift code within the SDK. See Dynamic Frameworks are officially only supported since iOS 8.

iOS 8 & later: Add the NSLocationAlwaysUsageDescription key as well as NSLocationWhenInUseUsageDescription to the Information Property List. Add a custom string value why you have to access the user’s current location - The latter is for beacon-updates while the app is the foreground, while the former is for background updates.

Note
for beacon-region-monitoring the “AlwaysUsage” key is important, because it will not start otherwise, even if the app is in foreground. The “monitoring” methods of the SDK will therefore not work.

iOS 9 & later: In order to receive updates in the background, you need to enable the “Location Updates” Background-Mode.

Background Modes

Setting the value to YES but omitting the UIBackgroundModes key and location value in your app’s Info.plist file is a programmer error.

2.4. Logging with CocoaLumberjack

This paragraph is only important, if you are using CocoaLumberjack as logging framework, which is used by the Backspin iOS SDK.

If you are using this logging framework already, you can continue to use it as before, Backspin iOS SDK has its own logging-flags defined which will not interfere with the default ones. However, one important remark: In order to manage logging-levels, all current DDTTYLoggers will be removed on calling setupBackspinWithApiKey:..! One default logger is added again via [DDLog addLogger:[DDTTYLogger sharedInstance]]. If that doesn’t suit your needs, you can change it in the success or error-block of the setup-method. All other Cocoalumberjack loggers will not be affected at the moment (up to date of this document).

2.5. Custom Region Monitoring

If you are performing custom iBeacon Region Monitoring with the CLLocationManager, you should notify the BackspinSDK about the regions that are monitored. While starting monitoring/positioning, all current regions are removed from monitoring and the current positioning-regions are added again. This is done to ensure there are no dangling/unused regions if the positioning-UUID is changed.

Obviously this leads to the removal of any custom created beacon-regions that are monitored somewhere else in the app. If you have created these, make sure to “whitelist” these regions so the SDK will keep them. This must be done by putting the UUIDs in the set before calling setupBackspinWithApiKey:

[[BackspinSDKController sharedInstance].whiteListBeaconUuidsForBeaconMonitoring addObject:@"CUSTOM_UUID_THAT_IS_MONITORED"];

Geo-Regions (CLCircularRegion) are NOT affected by the cleanup.

3. Start Using the Backspin iOS SDK

3.1. Import the SDK Header

To be able to use any functionality of the Backspin iOS SDK make sure you import the header file.

#import <BackspinSDK/BackspinSDK.h>

3.2. Setup the Controller

The BackspinSDKController is the main interface for communicating with Backspin.

  • setup the environment

  • download level-models

  • download level-plans and images from Backspin

  • start location updates

  • start calculating navigation paths

  • handle notifications

  • send analytics events

  • etc.

for an extensive list of functions, see the sections List of Functions

In the following code section you’ll see how to setup the controller and implement a delegate method to receive location updates. If you are using crypto-beacons with rolling-id, make sure to specify that in the method to start region monitoring or beacon-ranging (see code-example below).

Note
Make sure that you call setupBackspinWithApiKey: before any other call, since the SDK will throw exceptions if not authenticated.
Note
The only two things that should be set before calling setupBackspinWithApiKey: are the root-scope-id - since otherwise for the initial model-download a random scope-id will be used (However, this is only relevant if you have more than one root-scope-id, e.g. multiple root-venues). Additionally, as described in Custom Region Monitoring, add custom monitored iBeacon UUIDs to whiteListBeaconUuidsForBeaconMonitoring.
// ...

@interface YOUR_CLASS <BackspinSDKControllerDelegate, BackspinSDKControllerDatasource>

// ...

	[BackspinSDKController sharedInstance].delegate = self;
	[BackspinSDKController sharedInstance].datasource = self;

	// set the root-scope-id, otherwise a random one will be selected
	// only relevant if there are multiple root-scopes
	[[BackspinSDKController sharedInstance] setRootScopeId:23];

	// add this UUID to the whitelist, so it will be kept during monitoring-region-cleanup
	[[BackspinSDKController sharedInstance].whiteListBeaconUuidsForBeaconMonitoring addObject:@"CUSTOM_UUID];

	[[BackspinSDKController sharedInstance] setupBackspinWithApiKey:@"YOUR_API_KEY" success:^{

		// Set some properties to fit your needs
		[BackspinSDKController sharedInstance].positioningUseNavigationPathSnapping = YES;

		CLLocationCoordinate2D rootVenueCoordinate =
			CLLocationCoordinate2DMake(LATITUDE, LONGITUDE);

		// Now start region monitoring
		// the beacon-ranging and indoor-positioning will start, if one enters the region with the given centre and radius in metres or if a beacon with the given UUID is monitored
		[[BackspinSDKController sharedInstance]
			startMonitoringRegionWithCenter:rootVenueCoordinate withRadius:1000.0f
			andCryptoBeacons:YES andPositioningBeaconUUID:@"YOUR_UUID"
		];

	} errorHandler:^(NSError *connectionError) {
		// Handle error
	}];

// ...

#pragma mark BackspinSDKControllerDelegate

- (void)calculatedNewIndoorLocation:(CLLocation *)indoorLocation {

    // Do something with the location object

    ...

    // use best accuracy setting if the position is on the same level that is currently displayed
    if(indoorLocation.altitude == self.displayedLevelnumber) {
        // best (practice) accuracy preset with all tweaks
        [[BackspinSDKController sharedInstance] enablePositioningAccuracySetting:BSSDKPositioningAccuracySettingBestAccuracy];
    }
    // otherwise the user does not see the position, so it can be “less accurate”
    else {
        // otherwise set power-saving preset
        [[BackspinSDKController sharedInstance] enablePositioningAccuracySetting:BSSDKPositioningAccuracySettingPowerSavingMode];
    }

}

For further implementation details look at the public header files.

4. Notifications

In order for the app to produce background notifications, even if they are triggered from within the app, notifications need to be allowed by the app-user:

[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
// register for remote notifications
[[UIApplication sharedApplication] registerForRemoteNotifications];

The last call is not required for local notifications but is necessary for APNS pushes, which requires the corresponding UIAppDelegate method to be implemented:

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

	// forward the token to the Backspin server to be able to receive timed pushes
	[[BackspinSDKController sharedInstance] registerDeviceWithApnsTokenAtServer:deviceToken withUserRegistrationCompletionBlock:nil];
}

4.1. Notification Delegate

To receive notifications from Backspin SDK implement the corresponding delegate method:

- (void)handleAppNotification:(BSAppNotificationModel *)appNotificationModel {
	...
}

This delegate method uses the BSAppNotificationModel with the following properties (Source comments omitted here, please refer to the public header file):

@interface BSAppNotificationModel : NSObject
@property (readonly) NSString *notificationTitle NS_AVAILABLE_IOS(8_0);
@property (readonly) NSString *notificationBody;
@property (readonly) NSArray *actions;
@property (readonly) NSArray *notificationKeyValueData;
@end

The notificationKeyValueData property contains all the custom key-value pairs that were defined for this notification in the Backspin Dashboard, will contain dictionaries as so:

[ {"key": "foo1", "value": "bar1"}, {"key": "foo2", "value": "bar2"}, {"key": "foo3", "value": "bar3"} ]

The actions-array contains actions that are associated with this notification, mainly to be interpreted and executed by the Backspin iOS SDK itself.

If you want the actions to be executed, forward the model to the SDK: [[BackspinSDKController sharedInstance] executeAppNotification:appNotificationModel];

At the moment two action types are available:

  • Popup

  • Detailview

4.2. Provide custom detailviews

If a detailview (for an offer or a venue/shop) shall be displayed as a result of a notification that is executed by the SDK (via executeAppNotification:), a module-interface needs to be provided, which is described here: How to create Custom Views through BackspinSDK Push Service

4.3. BackspinSDKControllerDatasource

The Backspin iOS SDK automatically searches for the Localizable.string file to localise any popups. If you don’t use the Localizable.string file you should implement the BackspinSDKControllerDatasource protocol and return your own custom translations.

The following keys exist and should be translated:

locationmanager_ls_disabled_title locationmanager_ls_disabled_text

Notify the app-user that location-services are disabled

locationmanager_ls_unauthorised_title locationmanager_ls_unauthorised_text

Notify the app-user that the app is not authorised to use location-services

locationmanager_ble_unavailable_title locationmanager_ble_unavailable_text

Notify the app-user that bluetooth is disabled

locationmanager_popup_ok

text for the “OK” button of any popup with text as above

locationmanager_popup_gotosettings

text for a button to go directly to location-services-settings

notification_popup_title_offernearyou

Title for a offer-notification

notification_popup_doyouwanttoseedetailsforoffer

text for a offer-notification, the title of the offer will be following this text after a whitespace

notification_popup_title_shopvenuenearyou

Title for a shop-notification

notification_popup_doyouwanttoseedetailsforshopvenue

text for a shop-notification, the title of the shop will be following this text after a whitespace

notification_popup_ok

text for the “OK” button for a notification-popup, to close a pure “message” popup with no further action

notification_popup_cancel

text for the “Cancel” button for a notification-popup (e.g. to cancel the opening of a detail-view)

notification_popup_continue

text for the confirmation-button to open up a detail-view

core_update_nointernetconnection_title core_update_nointernetconnection_text

Alert-View that no internet connection is available on first start and at subsequent starts until an initial internet connection has been established

core_update_longtimenoupdate_title core_update_longtimenoupdate_text

Alert-View that the last content-update was over two weeks ago

core_update_close

“Close” button for the two alert-views above

Without a Localizable.strings implement the datasource method:

- (NSString *)localisedStringFor:(NSString *)localisationKey {

    NSString *localisedString = localisationKey;

    if ([localisationKey isEqualToString:@"notification_popup_title_offernearyou"]) {

    } else if ([localisationKey isEqualToString:@"notification_popup_doyouwanttoseedetailsforoffer"]) {

    }  else {
	// ...
    }
    return localisedString;
}

- (NSString *) currentLanguageDesignator {
    return @"de";
}

5. Model-Store & Server API

As described in List of Functions the Backspin iOS SDK contains an API to download, parse, and cache models. Here are some further notes to help using the API and make design-choices:

In general the model-store and the models are read-only, so in case it is required to change a model locally, it might be best to use an own solution for now.

5.1. Model-Store

A short example on how the workflow should look like:

BSBackendConnectionDownloadRestEndpoint *restEndpoint =
    [BSBackendConnectionDownloadRestEndpoint endPointWithPath:restEndpointPath];
restEndpoint.rootScopeId = 23;

[[BackspinSDKController sharedInstance] requestModelDownloadOrUpdateForRestEndpoint:restEndpoint
      andCompletionBlock:^(BSBackendConnectionDownloadRestEndpoint * _Nonnull restEndpoint,
                         NSDate * _Nonnull lastServerUpdate) {


    NSArray *allVenueModels = [BSSDKModelStore modelsForType:@"Venue" withFilters:nil andRootScopeId:-1];

    NSArray *venueModelsForCurrentScope = [BSSDKModelStore modelsForType:@"Venue" withFilters:nil andRootScopeId:23];

    NSArray *venueModelsWithFilter = [BSSDKModelStore modelsForType:@"Venue" withFilters:@[
    		@{@"name": @"venueType", @"equals": @"shop"}]];
}];

Also, all models that are downloaded from Backspin are saved as JSON, so the only model-object that is available is BSGenericModelSQLite which offers generic accessors according to object-type (e.g. stringForName:). All nested/linked models will be replaced with generic-model-instances, if available. So it makes sense to request "related" REST endpoints at the same time, e.g. venues and venuecategories and wait until both have been downloaded. The retrieval of a linked model in the database (if already requested/downloaded from the corresponding REST endpoint) is done automatically, e.g. the linked VenueCategory models from within a Venue models:

BSGenericModelSQLite *oneShopModel = venueModelsWithFilter.firstObject;
NSString *shopName = [oneShop stringForName:@"name"];

// references models with Type "VenueCategory" from REST endpoint /venuecategories
NSArray *shopCategories = [oneShopModel arrayForName:@"categories"];
BSGenericModelSQLite *firstShopCategory = shopCategories.firstObject;
NSString *shopCategoryDescription = [firstShopCategory stringForName:@"description"];

For all available attributes, it is best to look at the JSON that is returned for each REST endpoint.

One more thing: Before models from a REST endpoint are downloaded/updated, a query to the corresponding /lastmodified endpoint is made considering the language and scope-id and only if at least one model has changed, a download/update operation is performed. To save additional resources, the last-modified query is only performed at maximum every 30 minutes.

If it is required to perform an instant update-operation, you can call triggerContentUpdateFromServer in the BackspinSDKController and then call requestModelDownloadOrUpdateForRestEndpoint: In any case, while the update-operation is going on, all "old" models are still available.

Note
An existing BSGenericModelSQLite that is obtained from the model-store will NOT be updated with the new data if during its lifetime an update-operation changes its data. If it is inherently important to have the newest data, it is recommended to reload all models once the BackspinSDKRestEndpointModelRequestCompletionBlock is called.

5.2. Server API

Especially for the provided REST API for User Accounts it makes sense to download and upload "plain" JSON data. The Backspin iOS SDK offers functionality to download and upload data:

  • readBackspinJsonObjectFromEndpoint:

    • Allows to download a plain JSON from the given REST endpoint, deserialised into a NSDictionary or NSArray.

  • sendJsonObject:toPath:withHTTPMethod:

    • send a request to Backspin with the given HTTP method. Every HTTP-method is possible. The block contains the server-return-value as deserialised JSON object as NSDictionary or NSArray.

  • POSTJsonObject:toPath:

    • convenience method to send a POST request to Backspin

  • PUTJsonObject:toPath:

    • convenience method to send a PUT request to Backspin

6. Analytics

A list of supported analytics event types that are created and configurable out of the box can be found at Analytics. If custom analytics events are required, these can be queued and sent to the server by using the Backspin iOS SDK as well.

For custom events, the BSSDKAnalyticsTypeHandler protocol needs to be implemented, which can modify the data which is sent as analytics-event to the server.

Add your implementation to the set of handlers via [[BackspinSDKController sharedInstance] addAnalyticsTypeHandlerIfNotAlreadyAdded:] Once added, the handler will be called for every analytics-event that is about to be sent to the Backspin server, so make sure to check for the currentEventType if it is relevant for you.

Per default, an event has the following values:

{
	"type": "THE_TYPE",
    "timestamp": 1441283129969,
    "timezone": "Europe/Berlin",
    "timeoffset": "7200",
    "platform": {
        "device": "iPod Touch 6th Gen",
        "platform": "iPhone OS",
        "platformVersion": "8.4.1"
    }
}

All other values need to be provided by the BSSDKAnalyticsTypeHandler. You should put your data in payload.

One example of an internal analytics-manager for indoor-location events:

@implementation BSLocationAnalyticsManager

- (BOOL) respondsToEventType:(NSString *)currentEventType {
    return [currentEventType isEqualToString:@"location_updated"];
}

- (void) addFieldsToJsonObject:(NSMutableDictionary *)jsonObject forEventType:(NSString *)currentEventType andData:(NSDictionary *)analyticsData {

    if([self respondsToEventType:currentEventType]) {

        jsonObject[@"location"] = @{
                                    @"latitude": analyticsData[@"latitude"],
                                    @"longitude": analyticsData[@"longitude"]
                                    };
        jsonObject[@"payload"] = @{@"floor": analyticsData[@"floor"], @"isIndoors": analyticsData[@"isIndoors"]};
    }
}

@end

What you put in the payload is entirely up to you. These analytics-event might not show up in the Backspin dashboard, however.

Note
If your custom analytics-event is somehow related to an indoor-location, you might want to add the location-key with the latitude and longitude to your generated JSON object, as well as the keys floor and isIndoors in the payload.

7. Troubleshooting

If you cannot compile the project, some additional flags might need to be set. First, make sure all flags are set as described in Adjust Project Settings.

7.1. libswiftCore.dylib

dyld: Library not loaded: @rpath/libswiftCore.dylib
This error appears directly after start of the app:
dyld: Library not loaded: @rpath/libswiftCore.dylib

If this error shows up after starting the app, make sure that the Build-Setting flag “Embedded Content Contains Swift Code” is set to “Yes