WOVER™

Overview

WOVER is an artificial intelligence (AI) platform that helps individuals to minimize the impact of potential emergencies or to avoid them altogether, by identifying the emergencies as early as possible and notifying the right people to take action. WOVER’s AI engine synthesizes the individual’s motion signature using sensor data from the smartphone and wearables, and subsequently analyzes it for anomalies that may indicate emergencies.

Features

  • Synthesis of unique motion signature using activity data from smartphone and wearables.
  • Anomaly detection in motion signatures that may indicate emergency.
  • Optimized to maintain low power consumption.

Requirements

  • iOS 9.0 or later.
  • Xcode 8.0 or later.

Installation

Cocoapods

  1. Install CocoaPods 1.2.0 or later.
  2. Run pod repo update to make CocoaPods aware of the latest available WOVER version.
  3. In your Podfile, add use_frameworks! (Swift only projects) and pod 'WOVER' to your main targets.
  4. From the command line, run pod install.
  5. Use the .xcworkspace file generated by CocoaPods to work on your project. 🤘

Setup

Add Required Capabilities

Select the root project and under Capabilities enable the following:

  1. Background Modes and select Location Updates.
  2. Push Notification (optional, see Emergency/Safety Reporting section below).
  3. HealthKit (optional, used to monitor HealthKit store).

At the end, the Capabilities menu should be as following

Swift Project

Add the following WOVER initialization code to your AppDelegate.swift

import UIKit
import WOVER

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        // Setup WOVER with your api key and enable optional HealthKit data harvesting.
        WOVER.setup(apiKey: "<Your api key>", application: application, healthKit: true)
        return true
    }
}

Obj-C Project

Add the following WOVER initialization code to your AppDelegate.m

#import "AppDelegate.h"
@import WOVER;

@interface AppDelegate ()
@end

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Setup WOVER with your api key and enable optional HealthKit data harvesting.
    [WOVER setupWithApiKey:@"<Your api key>" application:application healthKit:@YES];
    return YES;
}

@end

WOVER functionalities are broken down into sections thus it will be easier for you to understand them, and decide to use them or not, based on your business requirements.

Authentication

The most important step is to authenticate the end user in the WOVER service. When end user is successfully authenticated, data harvesting will start automatically (see also the “Permissions” section) and you will be able to use emergency/safety reporting, contacts resolving and local emergency notification.

Swift

let wover = WOVER.sharedInstance()

//Authorise new or existing user in WOVER service
wover.userManager.authoriseUser(with: "<Unique id>", firstName: "first_name", middleName: nil, lastName: "last_name", phoneNumber: "e-164 mobile number") { (success, error) in
    //Success wover.userManager.isAuthorised => true
}

//Logout an authorised user
wover.userManager.logout { (success, error) in
    //Success wover.userManager.isAuthorised => false
}

Obj-C

WOVER *wover = [WOVER sharedInstance];

//Authorise new or existing user in WOVER service
[wover.userManager authoriseUserWith:@"<Unique id>" firstName:@"first_name" middleName:nil lastName:@"last_name" phoneNumber:@"e-164 mobile number" completion:^(BOOL success, NSError * _Nullable error) {
    //Success wover.userManager.isAuthorised => true
}];

//Logout an authorised user
[wover.userManager logoutWithCompletion:^(BOOL success, NSError * _Nullable error) {
    //Success wover.userManager.isAuthorised => false
}];

phoneNumber is used during contact resovling so other WOVER users can resolve with the end user.

Contacts

In WOVER the end user can create a safety network, i.e. the people who will be notified when the user reports an emergency or gets back to safety, by uploading his/her contact list. WOVER will resolve all the contacts that are already WOVER users. Of course uploaded contacts can also be removed.

Swift

let wover = WOVER.sharedInstance()

//Upload contact in order to find any resolved WOVER contacts.        
let contacts: [CNContact] = ...
_ = wover.userManager.upload(contacts) { (resolvedContacts, error) in
    // Contacts is an array of resolved WOVER contacts.
    //You can store them using NSCoding or dictionary representation.
}

//Remove uploaded contacts.
let contactsToDelete: [CNContact] = ...
_ = wover.userManager.removeContacts(contactsToDelete, completion: { (success, error) in
    // Contacts completely removed from WOVER
})

//Fetch any resolved contacts
_ = wover.userManager.fetchResolvedContacts { (resolvedContacts, error) in
    // Contacts is an array of resolved WOVER contacts.
    //You can store them using NSCoding or dictionary representation.
}

Obj-C

WOVER *wover = WOVER.sharedInstance;

//Upload contact in order to find any resolved WOVER contacts.
NSArray<CNContact *> *contacts = [[NSArray alloc] init];    
[wover.userManager upload:contacts completion:^(NSArray<WOVContactObject *> * _Nullable resolvedContacts, NSError * _Nullable error) {
    // Contacts is an array of resolved WOVER contacts.
    //You can store them using NSCoding or dictionary representation.
}];

//Remove uploaded contacts.
NSArray<CNContact *> *contactsToDelete = [[NSArray alloc] init];
[wover.userManager removeContacts:contactsToDelete completion:^(BOOL success, NSError * _Nullable error) {
    // Contacts completely removed from WOVER
}];

//Fetch any resolved contacts
[wover.userManager fetchResolvedContactsWithCompletion:^(NSArray<WOVContactObject *> * _NullableresolvedContacts, NSError * _Nullable error) {
    // Contacts is an array of resolved WOVER contacts.
    //You can store them using NSCoding or dictionary representation.
}]

A WOVER contact that has been resolved should be assigned by the end user (see Emergency/Safety Reporting Section) in order to receive emergency/safety reporting.

Swift

let contact: WOVContactObject = ...
let dicForStoring = contact.dictionaryRepresentation()
//Store it.

// Assign        
let storedContact: WOVContactObject = WOVContactObject(parameters: dicForStoring)!
_ = wover.userManager.assign(contacts: [storedContact]) { (success, error) in
    // Mark your UI user is assigned or refetch resolved contacts.
    // ex. storedContact.assigned = success
}

// Deassign
_ = wover.userManager.deassign(contacts: [storedContact], completion: { (success, error) in
    //Mark your UI user is deassigned or refetch resolved contacts.
    // ex. storedContact.assigned = success
})

Obj-C

WOVContactObject *contact = [[WOVContactObject alloc] initWithParameters:...];
NSDictionary *dicForStoring = [contact dictionaryRepresentation];
//Store it.

WOVContactObject *storedContact = [[WOVContactObject alloc] initWithParameters:dicForStoring];

[wover.userManager assignWithContacts:@[storedContact] completion:^(BOOL success, NSError * _Nullable error) {
    // Mark your UI user is assigned or refetch resolved contacts.
    // ex. storedContact.assigned = success;
}];

[wover.userManager deassignWithContacts:@[storedContact] completion:^(BOOL success, NSError * _Nullable error) {
    //Mark your UI user is deassigned or refetch resolved contacts.
    // ex. storedContact.assigned = success;
}];

Emergency/Safety Reporting

A WOVER user can notify his/her safety network when he/she is in an emergency or gets back to safety. WOVER can automatically notify the user’s safety network if it detects an emergency. When one of these events occur, WOVER calls the backend hooks passing along relevant information (includes resolved/assinged contacts from your organization domain) and resolved/assigned contacts from WOVER domain.

Swift example

@IBAction func onButton(_ sender: UIButton) {
        let wover = WOVER.sharedInstance()
        // Reports user is in emergency via a UIButton
        wover.emergencyManager.reportEmergency(inEmergency: true,
                                               type: .button,
                                               text: nil) { (success, error) in
                                                //update UI or your logic
        }

        // Or you can check if user is in emergency or not and call the reporting
        // with the correct emergency state
        if wover.emergencyManager.userInEmergency == false {
            //Report emergency
            wover.emergencyManager.reportEmergency(inEmergency: true,
                                                   type: .button,
                                                   text: nil,
                                                   completion: { (success, error) in
                                                    //update UI or your logic
            })

        } else {
            //Report back in safety
            wover.emergencyManager.reportEmergency(inEmergency: false,
                                                   type: .button,
                                                   text: nil,
                                                   completion: { (success, error) in
                                                    //update UI or your logic
            })
        }
    }

Obj-C example

- (IBAction)onButton:(UIButton *)sender {

    WOVER *wover = [WOVER sharedInstance];

    // Reports user is in emergency via a UIButton
    [wover.emergencyManager reportEmergencyInEmergency:YES
                                                  type:VerificationTypeButton
                                                  text:nil
                                            completion:^(BOOL success, NSError * _Nullable error) {
                                                //update UI or your logic
                                            }];

    // Or you can check if user is in emergency or not and call the reporting
    // with the correct emergency state
    if (wover.emergencyManager.userInEmergency != YES) {
        //Report emergency
        [wover.emergencyManager reportEmergencyInEmergency:YES
                                                      type:VerificationTypeButton
                                                      text:nil
                                                completion:^(BOOL success, NSError * _Nullable error) {
                                                    //update UI or your logic
                                                }];
    } else {
        //Report back in safety
        [wover.emergencyManager reportEmergencyInEmergency:NO
                                                      type:VerificationTypeButton
                                                      text:nil
                                                completion:^(BOOL success, NSError * _Nullable error) {
                                                    //update UI or your logic
                                                }];
    }
}

Emergency local notification

WOVER enables you to show a local notification on lock screen for faster emergency reporting. This notification is shown only when the user is authenticated and not in an emergency state.

To enable emergency local notification, use the following code:

Swift

let wover: WOVER = WOVER.sharedInstance()
wover.emergencyManager.localNotifTitle = "Your custom title"
wover.emergencyManager.localNotifBody = "Your custom body"
wover.emergencyManager.showLocalNotification = true

Obj-C

WOVER *wover = [WOVER sharedInstance];
wover.emergencyManager.localNotifTitle = @"Your custom title";
wover.emergencyManager.localNotifBody = @"Your custom body";
wover.emergencyManager.showLocalNotification = YES;

To handle the emergency local notification, use the following code:

Swift

func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
        let wover: WOVER = WOVER.sharedInstance()

        if notification.userInfo?[wover.emergencyManager.EmergencyNotificationKey] != nil {
            wover.emergencyManager.reportEmergency(inEmergency: true,
                                                   type: .notification,
                                                   text: nil,
                                                   completion: { (success, error) in
                                                    // Update UI or any business logic
            })
        }
    }

Obj-C

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    WOVER *wover = WOVER.sharedInstance;
    if (notification.userInfo[wover.emergencyManager.EmergencyNotificationKey] != nil) {
        [wover.emergencyManager reportEmergencyInEmergency:YES
                                                      type:VerificationTypeNotification
                                                      text:nil
                                                completion:^(BOOL success, NSError * _Nullable error) {
                                                    //Update UI or other business logic
                                                }];
    }
}

Note: Your app should have Push Notifications capability enabled and request the user’s permission to show notifications using UIApplication’s method registerUserNotificationSettings with at least alert as setting option.

Permissions

When authentication with WOVER service is successful, all data harvesting functions start asking the end user for permissions through native iOS dialogs.

WOVER requires to set the following permission messages at Info.plist:

  1. NSLocationAlwaysUsageDescription (compulsory)
  2. NSMotionUsageDescription (compulsory)
  3. NSHealthShareUsageDescription (only if you use Health kit)

In case you have an on boarding process (ex. tutorial, etc) you can explicity ask for these permissions prior to authentication. If your app has already asked for such permissions (location, motion and health kit), WOVER will not show the corresponding permission request dialogs (silent success/failure).

Swift

//Request location permissions
WOVER.sharedInstance().requestLocationPermission()

//Request motion permissions
WOVER.sharedInstance().requestMotionPermission()

//Request healthkit permissions
WOVER.sharedInstance().requestHealthPermission()

Obj-C

//Request location permissions
[[WOVER sharedInstance] requestLocationPermission];

//Request motion permissions
[[WOVER sharedInstance] requestMotionPermission];

//Request healthkit permissions
[[WOVER sharedInstance] requestHealthPermission ];

In iOS10, accessing any functionality such as location, motion etc., is compulsory requires to set the permissions messages in Info.plist otherwise the application will crash. See here for more details.

Note: Apple is very sensetive on asking HealthKit permissions and relative Capability is not enabled. In that case a log will show up like this one:

Error Domain=com.apple.healthkit Code=4 "Missing com.apple.developer.healthkit entitlement." UserInfo={NSLocalizedDescription=Missing com.apple.developer.healthkit entitlement.}

Feedback

We very much value your feedback. Please submit your suggestions to support@wover.me.

License

Commercial

Mobiltron, Inc.