Model Management

Core ML Models need to be updated frequently. However, pushing app updates to distribute an updated version of the ML Model is not necessary. SAPML provides SAPMLModelManager APIs to remotely download, update, and keep track of models used by the app.

Core ML Model files are uploaded as client resources on the SAP Cloud Platform Mobile Services. The versioning support of client resources is essential to versioning of the Core ML Model files. SAPMLModelManager downloads the latest version of the model file hosted on the SAP Cloud Platform Mobile Services.

Initialization and Configuration

Create anSAPMLModel object that provides information about the Core ML model. SAPMLModel encapsulates model properties such as the name and URL of the model. SAPMLModelManager APIs take SAPMLModel instances to download and delete downloaded models. SAPMLModelManager also provides a list of downloaded SAPMLModel instances.

let helloCPMS = SAPMLModel(named:"HelloCPMSModel" , localURL: nil)

localURL is an optional parameter to use a local Core ML model as the initial version. Refer to Use a local Core ML Model File as the Initial Version for additional information.

You can use SAPMLModelManager to download, update, delete, and list downloaded ML models. Before using SAPMLModelManager all of its properties needs to be set. SAPMLModelManager follows a singleton design pattern. To invoke SAPMLModelManager APIs, use an SAPMLModelManager.shared instance.

SAPMLModelManager.shared.sapUrlSession = //set the fully configured SAPURLSession
SAPMLModelManager.shared.cpmsSettingsParameters = //set the cpmsSettingsParameters
SAPMLModelManager.shared.delegate = MyMLModelManagerDelegate() //set the delegate that will receive callbacks on events

Example Usage

//Configure `SAPMLModelManager` by setting the `sapUrlSession` and `cpmsSettingsParameters` properties, which will be used for downloading the Core ML Models from SAP Cloud Platform Mobile Services
   SAPMLModelManager.shared.sapUrlSession = //set the fully configured SAPURLSession
   SAPMLModelManager.shared.cpmsSettingsParameters = //set the cpmsSettingsParameters
   SAPMLModelManager.shared.delegate = MyMLModelManagerDelegate() //set the delegate that will receive a callback on download completion

//Specify the name of the Core ML model that needs to be downloaded from Mobile Services using SAPMLModel
   let helloCPMS = SAPMLModel(named:"HelloCPMSModel" , localURL: nil)

//Trigger download of the model
   SAPMLModelManager.shared.download(model: helloCPMS)

//Handle completion callback received on SAPMLModelManagerDelegate
func sapMLModelManager(_ manager: SAPMLModelManager, model: SAPMLModel?, didCompleteWithError error: SAPMLModelManagerError?) {
    if let err = error {
        switch err {
        case .compilationError(let compilationError):
            // Handle model compilation error
        case .downloadUnderway:
            // Handle model compilation error
        case .other(let otherError):
            // Handle otehr errors
        case .server(let serverError):
            // Handle server error
        case .cpmsSettingsMissing:
            // Handle CPMS Settings missing error
        case .modelNotFound:
            // Handle model not found error

        }
    }
    else {
        // Model downloaded/updated successfully
    }
}
//Access the downloaded and compiled ML model
    do {
       try SAPMLModelManager.shared.mlModel(for: helloCPMS)
    }
    catch _ {
       //Error Handling
    }

NOTE: SAPMLModelManager download and update complies with network synchronization policies specified by the SAP Cloud Platform Mobile Services administrator.

Modifications Required in AppDelegate

Because ML models can be quite large in size, the ML model files are downloaded in the background. It is recommended to invoke download of the SAPMLModel in the AppDelegate applicationWillEnterForeground lifecycle method, so that the app gets to use the latest version.

func applicationWillEnterForeground(_: UIApplication) {
    let helloCPMS = SAPMLModel(named:"HelloCPMSModel" , localURL: nil)
    SAPMLModelManager.shared.download(model: helloCPMS)
}
//Because the `SAPMLModelManager` performs the download of Core ML models in the background, the `handleEventsForBackgroundURLSession` event must be forwarded to the SDK to handle
completion of tasks when the application is launched or resumed in the background
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
    AppDelegateDispatcher.application(application, handleEventsForBackgroundURLSession: identifier, completionHandler: completionHandler)
}

Use a local Core ML Model File as the Initial Version

There is an option to use a local Core ML Model file that is bundled with the app. This is treated as the initial version of the Core ML Model and will be served by the SAPMLModelManager, until a client resource file with the same name is uploaded to SAP Cloud Platform Mobile Services. So, the application starts with a local Core ML model within the app, which is updated subsequently with the remotely distributed model from SAP Cloud Platform Mobile Services.

//The Core ML model located at `localURL` will be available using the `mlModel(..)` function.
   let helloCPMS = SAPMLModel(named:"HelloCPMSModel" , localURL: Bundle.main.url(forResource: "myModel", withExtension: "mlmodelc"))
   SAPMLModelManager.shared.download(model: helloCPMS)
   try? SAPMLModelManager.shared.mlModel(for: helloCPMS) //returns local model

 //If a new version of the Core ML model is uploaded on Mobile Services Client Resources, it will be downloaded and compiled.
   let helloCPMS = SAPMLModel(named:"HelloCPMSModel" , localURL: Bundle.main.url(forResource: "myModel", withExtension: "mlmodelc"))
   SAPMLModelManager.shared.download(model: helloCPMS)
   try? SAPMLModelManager.shared.mlModel(for: helloCPMS) //returns remote model
  • SAPMLModel specifies the model that needs to be distributed from Mobile Services. SAPMLModel encapsulates model properties such as name, version, URL of the model. SAPMLModelManager APIs take SAPMLModel instances to download, delete and list downloaded models.

    See more

    Declaration

    Swift

    public struct SAPMLModel
  • The SAPMLModelManager is a convenience class for distributing new versions of Core ML models to the device and handling the local compilation and persistence of the Core ML models. The Core ML models are distributed from SAP Mobile Services as Client Resource files. The Core ML models are distributed remotely allowing the app to use the updated versions of the models, without requiring a re-distribution of the app itself. It is also possible to distribute the initial version of the model within the app and have subsequent versions distributed remotely. SAPMLModelManager provides APIs for performing operations like download, update, delete & list of Core ML models stored on File System.

    SAPMLModelManager follows singleton design pattern. So to invoke SAPMLModelManager APIs use SAPMLModelManager.shared instance.

    Example use

    //Configure `SAPMLModelManager` by setting the `sapUrlSession` and `cpmsSettingsParameters` properties which will be used for downloading the Core ML Models from SAP Mobile Services
       SAPMLModelManager.shared.sapUrlSession = //set the fully configured SAPURLSession
       SAPMLModelManager.shared.cpmsSettingsParameters = //set the cpmsSettingsParameters
       SAPMLModelManager.shared.delegate = MyMLModelManagerDelegate() //set the delegate that will receive a callback on download completion
    //Specify the name of the Core ML model that needs to be downloaded from Mobile Services using SAPMLModel
       let helloCPMS = SAPMLModel(named:"HelloCPMSModel" , localURL: nil)
    //Trigger download of the model
       SAPMLModelManager.shared.download(model: helloCPMS)
    //Handle completion callback received on SAPMLModelManagerDelegate
    func sapMLModelManager(_ manager: SAPMLModelManager, model: SAPMLModel?, didCompleteWithError error: SAPMLModelManagerError?) {
        if let err = error {
            switch err {
            case .compilationError(let compilationError):
                // Handle model compilation error
            case .downloadUnderway:
                // Handle model compilation error
            case .other(let otherError):
                // Handle otehr errors
            case .server(let serverError):
                // Handle server error
            case .cpmsSettingsMissing:
                // Handle CPMS Settings missing error
            case .modelNotFound:
                // Handle model not found error
    
            }
        }
        else {
            // Model downloaded/updated successfully
        }
    }
    //Access the downloaded and compiled ML model
        do {
           try SAPMLModelManager.shared.mlModel(for: helloCPMS)
        }
        catch _ {
           //Error Handling
        }
    

    Modifications required in AppDelegate

    //The SAPMLModelManager downloads the latest version of the Core ML model file that is available as a Client Resource on Mobile Services. It is recommended that the download call is hooked into the AppDelegate `applicationWillEnterForeground` lifecycle method so that the app gets to use the latest version.
        func applicationWillEnterForeground(_: UIApplication) {
            let helloCPMS = SAPMLModel(named:"HelloCPMSModel" , localURL: nil)
            SAPMLModelManager.shared.download(model: helloCPMS)
        }
    //As the `SAPMLModelManager` performs download of Core ML models in the background, the handleEventsForBackgroundURLSession event must be forwarded to the SDK to handle
    completion of tasks when the application is launched or resumed in the background
    func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
        AppDelegateDispatcher.application(application, handleEventsForBackgroundURLSession: identifier, completionHandler: completionHandler)
    }
    

    Example - Starting off with a local Core ML model within the app, updated subsequently with remotely distributed models.

    //The Core ML model located at `localURL` will be available using the `mlModel(..)` function.
       let helloCPMS = SAPMLModel(named:"HelloCPMSModel" , localURL: Bundle.main.url(forResource: "myModel", withExtension: "mlmodelc"))
       SAPMLModelManager.shared.download(model: helloCPMS)
       try? SAPMLModelManager.shared.mlModel(for: helloCPMS) //returns local model
    
     //If a new version of the Core ML model is uploaded on Mobile Services Client Resources, it will be downloaded and compiled.
       let helloCPMS = SAPMLModel(named:"HelloCPMSModel" , localURL: Bundle.main.url(forResource: "myModel", withExtension: "mlmodelc"))
       SAPMLModelManager.shared.download(model: helloCPMS)
       try? SAPMLModelManager.shared.mlModel(for: helloCPMS) //returns remote model
    
    See more

    Declaration

    Swift

    public class SAPMLModelManager
  • Enum which represents the error SAPMLModelManager can return

    See more

    Declaration

    Swift

    public enum SAPMLModelManagerError : Error
  • Delegate protocol to get events from SAPMLModelManager after model download has completed. No events are raised when there is no new version to be downloaded from Mobile services

    See more

    Declaration

    Swift

    public protocol SAPMLModelManagerDelegate