Enterprise Client Quick Start

The following steps must be taken to run an enterprise-client application.

  • Initialize enterprise client
do {
    try EnterpriseClient.newClient(appName.text,
        performWithECL: { eclClient in
            do {
                try performWithECL(eclClient)
            }               
            catch { }
        },
        errorHandler: self.errorMessage)
}       
catch { }

func performWithECL(eclClient: EnterpriseClient) throws { 
    // ... 
}

func errorMessage() {
    print("Create new client failed.")
}

  • Enumerate device models available in the application
try eclClient.getDeviceModels({ dmIterator in
        performWithDeviceModelIterator(dmIterator)
    })

func performWithDeviceModelIterator(iterator: DeviceModelIterator) {
    // ...
    var isDMIterator = iterator.hasMore()
    while isDMIterator == true {
        // ...
        try iterator.next({ returnList in
                // ...
                isDMIterator = returnList.hasMore()
            })
        }               
        catch { }
    } 
}

  • Get device model details
try eclClient.getDeviceModel(urn,
            deviceModelResponse: { dmResponse in
                    performWithDeviceModel(dmResponse)
                })

func performWithDeviceModel(deviceModel: DeviceModel) { 
    // ... 
}

  • Enumerate active devices
do {
    try ecl.getActiveDevices(dm.getURN(), 
        deviceEnumerator: { enumerationResponse in
                performWithActiveDevices(enumerationResponse)
            })
}
catch { }

performWithActiveDevices(deviceIterator: DeviceEnumerator) {
    // ...
    var isDeviceIterator = deviceIterator.hasMore()
    while isDeviceIterator == true {
        // ...
        try deviceIterator.next({ returnList in
                // ...
                isDeviceIterator = returnList.hasMore()
            })
    }               
    // ...
}

  • Create a virtual device for the target device and model
let virtualDevice: VirtualDevice = ecl.createVirtualDevice(dId, deviceModel: dm)

  • Monitor the device

    virtualDevice.setOnChange({ (event: ChangeEvent) in
        let device = event.getVirtualDevice()
        // update the device with the attribute value
        var namedValue = event.getNamedValue()
        var attribute = namedValue.getName()
        var value = namedValue.getValue()!.stringValue

        // check namedValue.next() to see if there are
        // more values in the chain
        // ...

    })


    virtualDevice.setOnAlert({ (event: AlertEvent) in
        let device = event.getVirtualDevice()
        // update the device with the alert
        let longUrn = event.getURN()
        var namedValue = event.getNamedValue()

        // update sample UI according to alert content
        // ...

    })


    virtualDevice.setOnError({ (event: ErrorEvent) in
        let device = event.getVirtualDevice()
        // log error here
    })

  • Control the device
do {
    let newValue = NSNumber(int: newHumidityThreshold)
    try virtualDevice.set(HUMIDITY_MAXTHRESHOLD, 
        attributeValue: newValue as AnyObject)
    }
catch { }

  • Dispose the enterprise client
ecl.close()

Storage Cloud Quick Start

This shows how to use a virtual device attribute to upload content to, or download content from, the Oracle Storage Cloud Service.

To upload or download content from a virtual device, there must be an attribute, field, or action in the device model with type URI. For the Oracle Storage Cloud Service, the URI type corresponds to the class StorageObject. When the attribute, field, or action of type URI is set to a StorageObject instance, the content is automatically synchronized with the Storage Cloud Service.

  • Uploading content

An instance of StorageObject is first needed to upload a file from a device client or from an enterprise client. The StorageObject is created using the createStorageObject API in DeviceLib.Client, which is the base class for EnterpriseLib.EnterpriseClient, DeviceLib.DirectlyConnectedDevice, and DeviceLib.GatewayDevice. The StorageObject names the object in storage, and provides the mime-type of the content. To set the input file, StorageObject API setInputPath(String) is used.

This example shows the typical use case from a DirectlyConnectedDevice. But the code for a GatewayDevice or `EnterpriseClient. is the same.

    let storageObject:StorageObject =
        directlyConnectedDevice.createStorageObject(name:"mediaSnapshot.jpg",
                                                    contentType:"image/jpg")
    storageObject.setInputPath(inputPath:"../images/mediaSnapshot.jpg");
    virtualDevice.set(attributeName:"snapshot", attributeValue:storageObject);

A StorageObject may also be set on an Alert field, or as an Action parameter, provided the type in the device model is URI.

  • Downloading content

In the virtualization API, the client is notified through an onChange event, onAlert event, or a call callback for an action. The value in the event is a StorageObject. To download the content, the output path is set on the StorageObject, and the content is synchronized by calling the StorageObject.sync() API.

This example shows the typical use case from an onChange event. The code for an onAlert or for an action callback is much the same.

    virtualDevice.setOnChange(attributeName:"snapshot", 
                              callback: { (event) in
            let namedValue:NamedValue = event.getNamedValue()
            let storageObject:StorageObject = namedValue.getValue() as? StorageObject
            // only download if image is less than 4M
            if storageObject.getLength() < 4 * 1024L * 1024L {
                do {
                    storageObject.setOutputPath(outputPath: "../downloads/" + storageObject.getName())
                    storageObject.sync()
                } catch {
                    print("cannot create file for download")
                }
            }
        }
    })
  • Checking synchronization status

A StorageObject is a reference to some content in the Storage Cloud. The content can be in sync with the storage cloud, not in sync with the storage cloud, or in process of being sync’d with the storage cloud. The synchronization happens on a separate thread, but can be monitored by setting a SyncCallback with setOnSync.

For the upload case, set the SyncCallback on the storage object before setting the virtual device attribute. For the download case, set the SyncCallback on the storage object from within the onChange callback.

    storageObject.setOnSync(callback: { (event) in
        let storageObject:StorageObject = event.getStorageObject()
        if storageObject.getSyncStatus() == SyncStatus.inSync {
             // image was uploaded and can be deleted
        } else if storageObject.getSyncStatus() == SyncStatus.syncFailed {
             // image was not uploaded, take action!
        }
     })