SpotSense SDK
需求
- iOS 10+
- Swift 4.2+
入门
创建应用
-
在 SpotSense Dashboard 中创建应用
-
通过以下方法通过 GitHub 或 CocoaPods 下载 SpotSense SDK
-
创建 XCode 项目
-
在终端中,导航到 Xcode 项目的目录
-
通过运行
pod init
创建 PodFile -
在 Xcode 或文本编辑器中打开 PodFile
-
将以下代码添加到 PodFile 中
target 'your-app' do # Pods for your-app pod 'SpotSense', '~>1.0.2' end
-
运行
pod install
-
打开您的应用的
.xcworkspace
文件,以启动 Xcode
-
-
import spotsense
并使用仪表板中的 Client ID 和 Secret 初始化 SpotSense
import UIKit
import CoreLocation
import SpotSense
let spotsense = SpotSense(clientID: "client-id", clientSecret: "client-secret")
class ViewController: UIViewController, CLLocationManagerDelegate, SpotSenseDelegate {...}
- 请求使用用户的位置并添加代理以处理位置更新 注:Apple 要求开发者在 Info.plist 中添加关于为何使用用户位置的描述
let locationManager : CLLocationManager = CLLocationManager()
let notificationCenter = UNUserNotificationCenter.current()
override func viewDidLoad() {
super.viewDidLoad()
txtLog = UITextView(frame: CGRect(x: 0, y: 0, width: 100, height: 10))
txtLog.isScrollEnabled = true
txtLog.textColor = UIColor.white
txtLog.backgroundColor = UIColor.black
txtLog.isEditable = false
self.view.addSubview(txtLog)
txtLog.translatesAutoresizingMaskIntoConstraints = false
txtLog.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 0).isActive = true
txtLog.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 55).isActive = true
txtLog.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: 0).isActive = true
txtLog.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -55).isActive = true
// get notification permission, only required if sending notifications with SpotSense
notificationCenter.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
spotsense.notificationStatus(enabled: granted);
}
// get location permissions
locationManager.delegate = self
locationManager.activityType = .automotiveNavigation
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.distanceFilter = 5.0
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
spotsense.delegate = self; // attach spotsense delegate to self
if (CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorizedWhenInUse) {
if CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) { // Make sure region monitoring is supported.
}
}
let logg = Logger()
logg.log("App started")
if let fileURL = logg.logFile {
do{
self.txtLog.text = try String(contentsOf: fileURL, encoding: .utf8)
}
catch {/* error handling here */}
}
spotsense.delegate = self
}
func ruleDidTrigger(response: NotifyResponse, ruleID: String) {
if let segueID = response.segueID { // performs screenchange
performSegue(withIdentifier: segueID, sender: nil)
} else if (response.getActionType() == "http") {
_ = response.getHTTPResponse()
}
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
spotsense.handleRegionState(region: region, state: .inside)
let logg = Logger()
if let fileURL = logg.logFile {
do {
self.txtLog.text = try String(contentsOf: fileURL, encoding: .utf8)
}
catch {/* error handling here */}
}
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
spotsense.handleRegionState(region: region, state: .outside)
let logg = Logger()
logg.log("didExitRegion : \(region.identifier)")
if let fileURL = logg.logFile {
//reading
do {
self.txtLog.text = try String(contentsOf: fileURL, encoding: .utf8)
}
catch {/* error handling here */}
}
}
func didUpdateBeacon(beaconScanner: SpotSense, beaconInfo: BeaconInfo, data: NSDictionary) {
}
func didFindBeacon(beaconScanner: SpotSense, beaconInfo: BeaconInfo, data: NSDictionary) {
NSLog("FIND: %@", beaconInfo.description)
spotsense.handleBeaconEnterState(beaconScanner: beaconScanner, beaconInfo: beaconInfo, data: data)
DispatchQueue.main.async {
let logg = Logger()
logg.log("FIND : \(beaconInfo.description)")
if let fileURL = logg.logFile {
do {
self.txtLog.text = try String(contentsOf: fileURL, encoding: .utf8)
}
catch {/* error handling here */}
}
}
}
func didLoseBeacon(beaconScanner: SpotSense, beaconInfo: BeaconInfo, data: NSDictionary) {
NSLog("LOST: %@", beaconInfo.description)
spotsense.handleBeaconExitState(beaconScanner: beaconScanner, beaconInfo: beaconInfo, data: data)
DispatchQueue.main.async {
let logg = Logger()
logg.log("LOST : \(beaconInfo.description)")
if let fileURL = logg.logFile {
do {
self.txtLog.text = try String(contentsOf: fileURL, encoding: .utf8)
}
catch {/* error handling here */}
}
}
}
func didUpdateBeacon(beaconScanner: SpotSense, beaconInfo: BeaconInfo) {
//NSLog("UPDATE: %@", beaconInfo.description)
}
func didObserveURLBeacon(beaconScanner: SpotSense, URL: NSURL, RSSI: Int) {
//NSLog("URL SEEN: %@, RSSI: %d", URL, RSSI)
}
class Logger {
var logFile: URL? {
guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return nil }
let formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy"
let dateString = formatter.string(from: Date())
let fileName = "\(dateString).log"
return documentsDirectory.appendingPathComponent(fileName)
}
func log(_ message: String) {
guard let logFile = logFile else {
return
}
let formatter = DateFormatter()
formatter.dateFormat = "h:mm a"
let timestamp = formatter.string(from: Date())
guard let data = (timestamp + ": " + message + "\n").data(using: String.Encoding.utf8) else { return }
if FileManager.default.fileExists(atPath: logFile.path) {
if let fileHandle = try? FileHandle(forWritingTo: logFile) {
fileHandle.seekToEndOfFile()
fileHandle.write(data)
fileHandle.closeFile()
}
} else {
try? data.write(to: logFile, options: .atomicWrite)
}
}
}
extension UIViewController {
func presentAlert(withTitle title: String, message : String) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default) { action in
print("You've pressed OK Button")
}
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion: nil)
}
}
- 选择您的应用并在 SpotSense Dashboard 中创建规则
- 在真实世界或在 iOS 模拟器中测试您的规则!
有问题或遇到困难?请在SpotSense Slack社区中告诉我们,或发送电子邮件([email protected])。很高兴为您提供帮助!