iOS

Getting Started

You should’ve received the following account details from us:

  • A base URL for your account, example: http://example.sensorberg.io
  • A client ID, required by the SDK in order to talk to the back-end
  • A user-name and password for your account
  • A download link for the iOS SDK
  • A private CocoaPods podspec URL for the iOS SDK
  • A private Carthage JSON URL for the iOS SDK

Integrating with Xcode

We support the following methods to integrate our SDK into your project:

  • Manual Xcode integration
  • Xcode integration using CocoaPods
  • Xcode integration using Carthage

Which one you choose, is up to you. If you are a beginner, CocoaPods integration is probably the easiest and fastest to get started.

You can use only one of the integration methods. They are not compatible with each other. If you want to switch from one integration method to another, please make sure to undo the previous integration steps first.

Manual Xcode Integration

  1. Download & unzip the SDK package where you’ll find the following contents:

    BlueIDSDKiOS.framework
    BlueIDSDKiOS.framework.dSYM
    LICENSE
    README
    SmartSpacesKit.xcframework
    
  2. Open your project in Xcode, select your app target, got to the General tab and drag the frameworks SmartSpacesKit.xcframework & BlueIDSDKiOS.framework into the Embedded Binaries section.

  3. Add the debug symbols BlueIDSDKiOS.framework.dSYM to your Xcode project, make sure to not add them to any targets. This step is optional but highly recommended.

  4. Make sure your app builds and runs in the iOS sumulator and on a device with no errors.

Xcode Integration Using CocoaPods

We support CocoaPods via private podspec URLs, which you should have received together with your account details from us. Use those to specify a specific version of the SDK to be used by your app. Your Podfile should look something like this:

use_frameworks!

target :YourApp do
  # ...
  pod 'SmartSpacesKit', podspec: 'https://sdk.sensorberg.com/smart-spaces/ios/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/cocoapods/SmartSpacesKit-iOS-0.4.5.podspec'
  # ...
end

Xcode Integration Using Carthage

We also support Carthage via a private URL, which you should have received together with your account details from us. Add that URL together with the desired version to your Cartfile. It should look something like this:

binary "https://sdk.sensorberg.com/smart-spaces/ios/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/carthage/SmartSpacesKit.json" ~> 0.4

You’ll have to add the SmartSpacesKit.xcframework and the BlueIDSDKiOS.framework to your target as a Carthage dependency, your Carthage build phase should look something like this:

Configuring Capabilities

The SmartSpacesKit requires Bluetooth support, which we’ll have to enable for your app as follows:

  1. Open your project in Xcode, select your app target and go to the Capabilities tab. Enable Background Modes and make sure Uses Bluetooth LE accessories as well as Acts as a Bluetooth LE accessory is checked.

  2. Add usage description for Bluetooth in your app’s Info.plist file (see Apple’s documentation for NSBluetoothAlwaysUsageDescription for more info)

  3. Make sure your app builds and runs in the iOS sumulator and on a device with no errors.

Configuring the SDK

Now we’ll have to configure the SDK by setting the following keys in your app’s Info.plist:

  • SmartSpacesClientID, type: String, value: <YOUR_CLIENT_ID>
  • kSWPlatformBaseURL, type: String, value: <YOUR_BASE_URL>
  • kSWEnableServerCertificatePinning, type: Boolean, value: YES
  • kSWEnableServerCertificatePublicKeySHA256, type: String, value depends on kSWPlatformBaseURL only the part after sha256/, more information about SSL certificate.

As mentioned in the beginning, you should’ve received your base URL and client ID together with your account details from us.

Again, make sure your app builds and runs in the iOS sumulator and on a device with no errors before proceeding to the next step.

Starting version 0.4.0 parameters kSWEnableServerCertificatePinning and kSWEnableServerCertificatePublicKeySHA256 are not needed, instead NSAppTransportSecurity must be specified. Up to iOS version 13.x, pinning works in compatibility mode in the SDK. Starting with iOS 14, pinning relies on the operating system (Identity Pinning).

We will be changing root certificates (different Certificate Authority) in the near future, this configuration is for a smooth transition. The documentation will be changed after the transition.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSPinnedDomains</key>
    <dict>
        <key>sensorberg.io</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSPinnedCAIdentities</key>
            <array>
                <dict>
                    <key>SPKI-SHA256-BASE64</key>
                    <string>i7WTqTvh0OioIruIfFR4kMPnBqrS2rdiVPl/s2uC/CY=</string>
                </dict>
                <dict>
                    <key>SPKI-SHA256-BASE64</key>
                    <string>C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHFr8M=</string>
                </dict>
            </array>
        </dict>
        <key>sensorberg.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSPinnedCAIdentities</key>
            <array>
                <dict>
                    <key>SPKI-SHA256-BASE64</key>
                    <string>r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=</string>
                </dict>
                <dict>
                    <key>SPKI-SHA256-BASE64</key>
                    <string>C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHFr8M=</string>
                </dict>
            </array>
        </dict>
    </dict>
</dict>

Getting Locks to Unlock

We are now ready to write some code. Our SDK is written in Objective-C and supports Swift as well.

In order to be able to discover and unlock locks, you’ll have to:

  1. Import the SmartSpacesKit
  2. Login via the SWUserSessionManager
  3. Register user’s iOS device by synchronizing SWUserDeviceManager (needs to be done only once)
  4. Register a delegate for the shared SWSmartLockManager
  5. Begin discovery of locks by synchronizing the shared SWSmartLockManager
  6. Get notified about discovered SWLocks via the SWSmartLockManagerDelegate protocol
  7. Open an SWLock using the open() method of the shared SWSmartLockManager

Here is a minimal Swift example:

import UIKit
import SmartSpacesKit

@UIApplicationMain
class AppDelegate: UIResponder {

    var window: UIWindow?

    var locksOpened = false

}

extension AppDelegate: UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        SWSmartLockManager.shared().delegate = self
        
        // TODO: insert your username password below:
        SWUserSessionManager.shared().login(
            withUsername: "<YOUR_USERNAME_HERE>",
            password: "<YOUR_PASSWORD_HERE>",
            additionalData: nil
        ) { userData, error in
            if let error = error { print("[ERROR] Failed to log-in: \(error)"); return }
            print("[DEBUG] Logged in, user data: \(userData.debugDescription)")

            UserDeviceManager.shared().synchronize { error in
                if let error = error { print("[ERROR] Failed to synchronize user device manager: \(error)"); return }

                SWSmartLockManager.shared().synchronize { error in
                    if let error = error { print("[ERROR] Failed synchronizing smart lock manager: \(error)"); return }
                    print("[DEBUG] Synchronizing smart lock manager finished")
                }
            }
        }

        return true
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        SWSmartLockManager.shared().pause()
        SWSmartLockManager.shared().automaticOpen = false
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        SWSmartLockManager.shared().automaticOpen = true
        SWSmartLockManager.shared().synchronize { error in
            if let error = error { print("[ERROR] Failed synchronizing smart lock manager: \(error)"); return }
            print("[DEBUG] Synchronizing smart lock manager finished")
        }
    }

}

extension AppDelegate: SWSmartLockManagerDelegate {

    func manager(_ manager: SWSmartLockManager, didDiscover locks: [SWLock]?) {
        guard let locks = locks else { print("[WARNING] Locks are nil, aborting."); return }
        guard !locksOpened else { return }

        for lock in locks {
            print("[DEBUG] Discovered lock: '\(lock.name ?? "unknown")', actions: \(lock.actions ?? [])")
            manager.open(lock)
        }

        locksOpened = true
    }

    func manager(_ manager: SWSmartLockManager, didOpen lock: SWLock, error: Error?) {
        print("[DEBUG] Did open lock: \(lock), error: \(String(describing: error))")
    }

}

Make sure to replace <YOUR_USERNAME_HERE> and <YOUR_PASSWORD_HERE> with your own credentials. Build & run the app on an iOS device, you should see your locks printed to the console and unlocked once. 🎉

Conclusion

Your app is now properly configured with the SmartSpacesKit. You should now be able to build your UI on top of it, enabling your users to interact with various smart space devices. Happy coding!

Troubleshooting

We’ll add common issues to this section later on. If you have any trouble setting up the SDK in your app, please get in touch. We are always happy to help. ❤️