=============== iOS Quick Start =============== Requirements ============ The SafeRider SDK requires iOS 13 or higher. It is optimized for phones, not tablets. If these requirements are too limiting for you, contact us. Installation ============ CocoaPods --------- The SafeRider SDK for iOS is available via CocoaPods and supports iOS 13 and higher versions. In your Podfile, just add these lines: .. code-block:: perl platform :ios, '13.0' # set the iOS min version of your app ... pod 'SafeRider' ... post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| # if the iOS min version of your app is higher than 13.0, add to your Podfile the commented code lines below #if target.name == 'Swinject' || target.name == 'DeviceKit' # config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' #end ... end end end Then open a terminal and run this command: .. code-block:: shell pod install --repo-update Swift Package Manager (SPM) --------------------------- We are not currently available through Swift Package Manager. Tell us if this is required for you. Project Configuration ===================== You need to configure your XCode project as follows: * In your target settings, open the **Signing & Capabilities** tab * Locate the **Background Modes** section * Check the **“Location updates”** item This is required to detect accidents when the screen is locked or the app is in the background. Initialize the SDK ================== You need to initialize the SDK by providing your API key. You should only initialize the SafeRider SDK once, at the end of the app launching process. .. code-block:: swift func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool { do { LRSafeRider.initialize(apiKey: "your_api_key", accidentUiScreenLogo: UIImage(named: "your_rectangular_logo")!) } catch { log.error("fail to init SafeRider: \(error.localizedDescription)") } return true } If you do not initialize it as explained above, **you shall not be able to use it** in your app. Get the SDK instance ==================== You can get 2 different types of SDK instances, considering your programming habits or ways. LRSafeRiderDelegationProtocol ----------------------------- .. code-block:: swift :class: no-copybutton protocol LRSafeRiderDelegationProtocol: LRSafeRiderProtocol { var currentProtectionStatus: LRProtectionStatus { get } var protectionDelegate: LRProtectionDelegate? { get set } var protectionStartDelegate: LRProtectionStartDelegate? { get set } var problemReportDelegate: LRProblemReportDelegate? { get set } func startProtection(vehicleType: LRVehicleType, userId: String, phoneNumber: String, userFirstName: String?, userLastName: String?, metadata: [String : Any]?) func reportProblem() } You can get this protocol as explained below .. code-block:: swift var safeRiderInstance = LRSafeRider.getShared(LRSafeRiderDelegationProtocol.self)! The delegation protocol comes with some delegates that help you to know what happens. .. code-block:: swift protocol LRProtectionDelegate { func onProtectionStatusChange(_ status: LRProtectionStatus) func onProtectionError(_ error: LRSaferiderError?) func onFallSurveyAnswer(_ fallSurveyAnswer: LRFallSurveyAnswer?) } The :code:`LRProtectionDelegate` allows you to be notified of the changes of the :ref:`protection status `, the possible :ref:`SDK errors ` or the possible :ref:`user answer to the fall survey ` in case of accident alert. .. code-block:: swift protocol LRProtectionStartDelegate { func onProtectionStartSuccess() func onProtectionStartFailure(_ error: LRSaferiderError) } The :code:`LRProtectionStartDelegate` allows you to be notified if your call to the function :code:`startProtection(...)` of this protocol has succeeded or not (and the error if necessary) .. code-block:: swift protocol LRProblemReportDelegate { func onProblemReportSuccess() func onProblemReportFailure(_ error: LRSaferiderError) } The :code:`LRProblemReportDelegate` allows you to be notified if your call to the function :code:`reportProblem()` of this protocol has succeeded or not (and the error if necessary). LRSafeRiderReactiveProtocol --------------------------- .. code-block:: swift :class: no-copybutton protocol LRSafeRiderReactiveProtocol: LRSafeRiderProtocol { var currentProtectionStatus: LRProtectionStatus { get } var protectionStatusPublisher: AnyPublisher { get } var protectionErrorPublisher: AnyPublisher { get } var fallSurveyAnswerPublisher: AnyPublisher { get } func startProtection(vehicleType: LRVehicleType, userId: String, phoneNumber: String, userFirstName: String?, userLastName: String?, metadata: [String : Any]?) -> AnyPublisher func reportProblem() -> AnyPublisher } You can get this protocol as explained below .. code-block:: swift var safeRiderInstance = LRSafeRider.getShared(LRSafeRiderReactiveProtocol.self)! The reactive protocol provides basically the same services than the delegation one but exposing Combine publishers. Start a Protection Session ========================== After initializing the SDK, you can start a protection session by calling :code:`startProtection(...)`. For details about each parameter, look at the iOS Reference. This will start continuous processing to analyze sensor data and detect accidents. Only one session can be active on a device at a given time. Before calling :code:`startProtection(...)`, you must ensure that :doc:`user location updates could be received ` otherwise the SDK will return an error. Using the LRSaferiderDelegationProtocol --------------------------------------- .. code-block:: swift self.safeRiderInstance.protectionStartDelegate = self self.safeRiderInstance.startProtection(vehicleType: .motorcycle, userId: "0000-0000-0000-0001", phoneNumber: "+33600000000", firstName: "John", lastName: "DOE", metadata: { "trip_id": "00000-000-0000-0001", "autostart": true }) extension MyClass: LRProtectionStartDelegate { func onProtectionStartSuccess() { log.info("succeed to start protection") } func onProtectionStartFailure(_ error: LRSaferiderError) { log.error("fail to start protection: \(error.localizedDescription)") } } Using the LRSaferiderReactiveProtocol ------------------------------------- .. code-block:: swift var cancellableBag = Set() self.safeRiderInstance.startProtection(vehicleType: .motorcycle, userId: "0000-0000-0000-0001", phoneNumber: "+33600000000", firstName: "John", lastName: "DOE", metadata: { "trip_id": "00000-000-0000-0001", "autostart": true }) .sink { completion in switch completion { case .failure(let error): log.error("fail to start protection: \(error.localizedDescription)") default: break } } receiveValue: { _ in log.info("succeed to start protection") } .store(in: &self.cancellableBag) When you want to end the protection session, call :code:`stopProtection()`. Listen to the SDK Protection Status change ========================================== In order to be notified of the protection lifecycle, you have to listen to SDK :ref:`status change events `. Using the LRSaferiderDelegationProtocol --------------------------------------- .. code-block:: swift self.safeRiderInstance.protectionDelegate = self extension MyClass: LRProtectionDelegate { func onProtectionStatusChange(_ status: LRProtectionStatus) { log.debug("new protection status: \(status)") } } Using the LRSaferiderReactiveProtocol ------------------------------------- .. code-block:: swift var cancellableBag = Set() self.safeRiderInstance.protectionStatusPublisher .receive(on: DispatchQueue.main) .sink { status in log.debug("new protection status: \(status)") } .store(in: &self.cancellableBag)