Get ConsumerPhysics models info (name, ID, supported SCiO versions, etc.) and use them to analyze your scans.

Each model has a “supportedSCiOVersions” array property that contains all the supported SCiO versions for the specific model.

__weak typeof(&*self)weakSelf = self;
[[CPScioCloud sharedInstance] getCPModelsWithCompletion:^(BOOL success, NSArray *models, NSError *error) {
    if (success) {
        [weakSelf modelsScreenWithModels:models];
        return;
    }
    
    // Error
    dispatch_async(dispatch_get_main_queue(), ^{
        [weakSelf alertWithTitle:error.userInfo[NSLocalizedDescriptionKey]  mes-sage:error.userInfo[NSLocalizedFailureReasonErrorKey]];
    });
}];}

Get your model info (name, ID, etc.) and use it to analyze your scans.

    
__weak typeof(&*self)weakSelf = self;
 [[CPScioCloud sharedInstance] getModelsWithCompletion:^(BOOL success, NSArray *models, NSError *error) {
        if (success) {
            [weakSelf modelsScreenWithModels:models];
            return;
        }
        
        // Error
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf alertWithTitle:error.userInfo[NSLocalizedDescriptionKey]  mes-sage:error.userInfo[NSLocalizedFailureReasonErrorKey]];
        });
    }];

Once calibration data is taken, the user can scan. The following code sample takes a scan:

__weak typeof(&*self)weakSelf = self;
    [[CPScioDevice sharedInstance] isCalibrationValid:^(BOOL success) {
        if (!success) {
            [weakSelf alertWithTitle:@"Calibration is invalid" message:@"Calibrate before scan"];
            return;
        }
        [weakSelf toastWithTitle:@"scanAPI" message:@"Scanning"];
        [[CPScioDevice sharedInstance] scanWithCompletion:^(BOOL success, CPScioReading *reading, NSError *error) {
            NSLog(@"Scan: %i",success);
            if (!success) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self alertWithTitle:error.userInfo[NSLocalizedDescriptionKey] message:error.userInfo[NSLocalizedFailureReasonErrorKey]];
                });
                return;
            }
            weakSelf.scanReading = reading;
            if (![SASampleFileUtils storeToDisk:reading fileName:SALastScanFileName]) {
                [self alertWithTitle:@"Failure" message:@"Failed to save last scan"];
            }
            
            [self toastWithTitle:@"Scan Completed" message:@"You can analyze a model now."];
        }];
    }];

The battery status API retrieves the battery percentage and charging status.

The following code sample reads the battery status from the SCiO device.

__weak typeof(&*self)weakSelf = self;
[[CPScioDevice sharedInstance] getBatteryStatusWithCompletion:^(double percentage, BOOL isCharging, NSError *error) {
    if (error) {
        [weakSelf alertWithTitle:error.userInfo[NSLocalizedDescriptionKey]  message:error.userInfo[NSLocalizedFailureReasonErrorKey]];
        return;
    }
    
    [weakSelf alertWithTitle:@"Battery status" message:[NSString stringWithFormat:@"Status: %@\nPercentage: %.0f", isCharging ? @"Charging" : @"Not charging", percentage]];
}];

A SCiO device can be renamed using the renameDeviceWithName API call.

The following code sample sets a new name for the SCiO device.

__weak typeof(&*self)weakSelf = self;
 [[CPScioDevice sharedInstance] renameDeviceWithName:name completion:^(BOOL success, NSError *error) {
     if (success) {
         dispatch_async(dispatch_get_main_queue(), ^{
             weakSelf.scioNameLabel.text = name;
         });
         return;
     }
     
     [weakSelf alertWithTitle:error.userInfo[NSLocalizedDescriptionKey]  message:error.userInfo[NSLocalizedFailureReasonErrorKey]];
 }];

There are a few versions of SCiO, and models might be compatible across versions, but with degraded performance. As a developer, you may want to verify which SCiO version is used and block or approve its spectra prior to analysis.
The following code sample sets a new name for the SCiO device:

__weak typeof(&*self)weakSelf = self;
[[CPScioCloud sharedInstance] getSCiOVersionByDeviceID:[[CPScioDevice sharedInstance] getDeviceID] completion:^(NSString *SCiOVersion, NSError *error) {
    NSLog(@"SCiO version:%@", SCiOVersion);
    [weakSelf alertWithTitle:@"SCiO Version" message:SCiOVersion];
}];

Cached scans
Scans can be stored locally (for uploading for analysis in the server later).
SampleFileUtils class allows you to store a scan object, and read and remove from local storage, using the following methods:

storeToDisk
This method has the following parameters:

  • Object- this is the scan object (CPScioReading).
  • fileName- to store the scan.

The method returns a boolean response for success/failure.

readArchiveWithFileName
This method has only one parameter:

  • fileName- of the scan that had been stored earlier.

The method returns a CPScioReading object of the scan.

removeFromDiskFileName
This method has only one parameter:

  • fileName- of the scan that had been stored earlier.

The method returns an NSError object that contains the error in case of a failure, or nil for success.

The following code sample stored a CPScioReading object (“_reading”)

[SampleFileUtils storeToDisk:_reading fileName:weakSelf.scanFileName];

The following code sample loads a CPScioReading object

CPScioReading *lastScan = [SampleFileUtils readArchiveWithFileName:self.scanFileName];

There are two CPScioCloud analyzeReading methods:

Single Model Analysis

This method has the following parameters:

  • CPScioReading: The sample data retrieved after a successful scan.
  • CPScioModelInfo identifier (NSString *): The predefined model identifier to compare the scan data with.

The method returns the following results:

  • success: Whether the method returns a valid analysis of the sample.
  • A CPScioModel: The model which match the sample scanned by the user.
  • NSError: on failure the method returns the relevant error message.  

The following code sample sends the CPScioReading to the cloud for single analysis, retrieves a CPScioModel and displays the information on the screen.

Note: In case of outlier detection, the attributeValue return “null”

weak typeof(&*self)weakSelf = self;
    [[CPScioCloud sharedInstance] analyzeReading:lastScan modelIdentifier:self.currentModel.identifier completion:^(BOOL success, CPScioModel *model, NSError *error) {
        NSLog(@"analyze succeded: %i",success);
        if (success) {
            NSString *message = [NSString stringWithFormat:@"Type: %@\nValue: %@\n%@", model.modelType == CPScioModelTypeClassification ? @"Classification" : @"Estimation", model.attributeValue, model.modelType == CPScioModelTypeClassification ? [NSString stringWithFormat:@"Confidence: %.2lf\n", model.confidence] : @""];
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf alertWithTitle:@"Results" message:message];
            });
        } else {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self alertWithTitle:[error.userInfo objectForKey:NSLocalizedDescriptionKey] message:[error.userInfo objectForKey:NSLocalizedFailureReasonErrorKey]];
            });
        }
    }];

 

Multiple Model Analysis

This method has the following parameters:

  • CPScioReading: The sample data retrieved after a successful scan.
  • CPScioModelInfo identifiers list (NSArray of NSString): The predefined models identifiers to compare the scan data with.

The method returns the following results:

  • success: Whether the method returns a valid analysis of the sample.
  • A list of CPScioModels: The models which match the sample scanned by the user.
  • NSError: on failure the method returns the relevant error message.

The following code sample sends the CPScioReading with a list of models identifiers to the cloud for multiple analysis and retrieves a list of CPScioModels.

Note: In case of outlier detection, the attributeValue return “null”

[CPScioCloud sharedInstance] analyzeReading:_reading modelIdentifiers:@[model1Identifier1, model2Identifier] completion:^(BOOL success, NSArray<CPScioModel *> *models, NSError *error) {
    if (success) {
         // models is an array of CPScioModel elements
   }
}

							
													

The SCiO device class enables the application to register a few callback functions, to receive notifications for various events:

  • setDeviceButtonBlock()

Pressing on the SCiO device’s button triggers the setDeviceButtonBlock event. The application can register an event handler for a button press and initiate actions upon it, for example, to scan a sample.

- (void)viewDidLoad {
     [super viewDidLoad];
     _models = [NSArray array];
     [[CPScioDevice sharedInstance] setDeviceButtonBlock:^{
     // Enter code for handling the button press event here
     }];
  }

Before initiating a scan, you must make sure the SCiO device is calibrated. Call the CPScioDevice.isCalibrationValid to verify whether the sensor needs to be calibrated. When calibrating the sensor, the user should put the SCiO into the cover and the app calls the calibrateWithCompletion method.

The calibration data is stored in the device memory of the iOS device and is available until the app is closed.  

The following code sample calibrates a SCiO sensor:

__weak typeof(&*self)weakSelf = self;
 [[CPScioDevice sharedInstance] calibrateWithCompletion:^(BOOL success) {
     NSLog(@"calibration: %i",success);
     
     if (!success) {
         dispatch_async(dispatch_get_main_queue(), ^{
             [weakSelf alertWithTitle:@"Calibration Failed" message:@"Please try again."];
         });
         return;
     }
     [self toastWithTitle:@"Calibration Completed" message:@"You can scan now"];
 }];