TestsTested | ✗ |
LangLanguage | SwiftSwift |
License | MIT |
ReleasedLast Release | May 2016 |
SPMSupports SPM | ✗ |
Maintained by Tanner Nelson.
To run the example project, clone the repo, and run pod install
from the Example directory first.
escaKit is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod "escaKit"
Getting started with escaKit is easy.
import escaKit
If your app has not already requested Location Services, you will need to do this before escaKit can work in the real world. escaKit provides a helper function to request Location Services.
escaKit.requestLocation(.Always) //or .WhenInUse
Just make sure to include the appropriate Usage Description in your Info.plist
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
If you want to send notifications from escaKit while the app is in the background, you will need to request notifications.
escaKit.requestNotificationsForApplication(UIApplication.sharedApplication())
Once the appropriate permissions have been requested, you can start escaKit.
escaKit.start(delegate: self, appKey: "escakit-demo-key")
Get the appKey
from the esca Dashboard. It should look something like asTyjGFHcDmgr23ICZuKGS4wTKDwnmIHx0B3RFga
.
When you create an experience in escaKit, it will show up in the esca Dashboard automatically. From there, you can assign content to be delivered to the app.
To create an experience, create a new subclass of escaKit.Experience
. In your experience, add subclasses of escaKit.Payload
and make properties on the experience to hold these payloads.
You can have as many payloads as you want in one experience, and you can even have multiple properties with the same payload type.
import Foundation
import escaKit
class InStoreExperience: escaKit.Experience {
var currentSale = PromotionPayload()
class PromotionPayload: escaKit.Payload {
var imageUrl: String = ""
var about: String = ""
var name: String = ""
}
}
Important: You must make sure that any payload properties (such as currentSale
) are assigned an empty payload of the desired type.
After you have created your experience, you need to tell escaKit about it. Anywhere after the escaKit.start(...)
call, you can register your experience.
escaKit.registerExperience(InStoreExperience)
This will upload the structure of the experience and payloads to the esca Dashboard. Next time you login, you will be able to start assigning content to the experience.
The delegate for escaKit, usually a ViewController or your AppDelegate, will need to conform to escaKit.DiscoveryDelegate
protocol escaKit.DiscoveryDelegate {
func escaKitDidDiscoverExperience(experience: Experience)
func escaKitDidDiscoverObject(object: Object)
}
Use the Experience
callback to display the relevant experience when your application enters a beacon region or other context.
func escaKitDidDiscoverExperience(experience: Experience) {
if let experience = experience as? InStoreExperience {
print("Loading In Store Experience with Sale: \(experience.currentSale.name)")
self.modalWindow.experience = experience
self.modelWindow.open(animated: true)
}
}
You can use the Object
callback to start tracking which Objects are in range and to set the Object’s delegate.
func escaKitDidDiscoverObject(object: Object) {
print("\(object) discovered")
object.delegate = self
self.objects.append(object)
}
Each beacon has one Object assigned to it at a given time. The Object has information such as identifiers and distance.
The identifier is a 32 bit integer and will be the same number written on the beacon’s box.
The distance is a floating point number that becomes closer to 0
as the beacon gets closer to the scanning device. You can use this number to figure out which Object is closest, or to set boundaries for when an Object should trigger a certain action.
The delegate will be called when certain events on the Object take place, such as updating distance or disappearing. See the ObjectDelegate
protocol.
escaKit.ObjectDelegate
protocol escaKit.ObjectDelegate {
func escaKitObjectDidDisappear(object: Object)
func escaKitObjectDidChange(object: Object)
}
This is called when the scanning device no longer sees the Object. This happens if the Beacon associated with that Object is out of range. You can use this callback as a chance to remove the Object from your array of tracked Objects.
func escaKitObjectDidDisappear(object: Object) {
print("\(object) did disappear")
self.objects = self.objects.filter { currentObject in
currentObject != object
}
}
This is called when a property on the Object changed, such as distance
. You can use this callback to change the order of a list of Object items, or to check if a distance threshold has been met.
func escaKitObjectDidChange(object: Object) {
print("\(object) changed.")
if object.distance < 100.0 {
print("\(object) is close.")
}
//sort the objects by closest at
//the beginning of the list
let objectsByDistance = self.objects.sort { object1, object2 in
//put 0s at the end of the list
if object1.distance == 0 {
return false
}
if object2.distance == 0 {
return true
}
return object1.distance < object2.distance
}
if let closestObject = objectsByDistance.first {
print("\(object) is closest.")
}
}
If you don’t have any esca Beacons to test with, you can simulate Objects to test your code.
escaKit.simulateObject(after: 2, lastingFor: 10, withId: 10130482)
escaKit.simulateObject(after: 2, lastingFor: 10) //defaults to id 10000000
escaKit includes some helper functions, like this one for sending a notification:
escaKit.sendNotificationForApplication(UIApplication.sharedApplication(), title: "Test Alert", message: test, sound: true)
iOS limits that amount of beacons that can be tracked in the background to a maximum of 20. Because of this, you must explicitly tell escaKit which beacon identifiers you would like to discover while in the background.
escaKit.enableBackgroundDiscoveryForObject(identifier: 10130482)
When the Object is seen in the background, the DiscoveryDelegate
will be called as usual. Use this in conjunction wtih the sendNotification
helper function to alert the user when they are near a beacon if the app is not open.
Note: you must have also requested .Always
location usage to detect beacons while in the background.
escaKit comes with a smoothing algorithm to prevent erratic fluctuations in distance
measurements due to inconsistencies caused by Bluetooth interference. Although this smoothing is useful in ensuring accurate measurements, it decreases the responsiveness of your application to changes in nearby beacon position.
The default smoothing is 20
. To prevent smoothing, use 1
.
//faster, but more erratic beacon distances
escaKit.Beacon.smoothing = 10
Get access to helpful information from escaKit by enabling logging.
escaKit.logging = true
To stop escaKit from scanning for beacons, call escaKit.stop()
at any time.
Tanner Nelson, [email protected]
escaKit is available under the MIT license. See the LICENSE file for more info.