C8yAssetCollection

public class C8yAssetCollection : ObservableObject

Class to allow you to manage an abritary collection of groups or devices from the users device e.g.

let myCollection = C8yAssetCollection()

do {
    try myCollection.load(conn, c8yReferencesToLoad: ["9403", "9102", "2323"], includeSubGroups: true)
        .receive(on: RunLoop.main)
        .sink(receiveCompletion: { (completion) in

                print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>> SINK LOAD ENDED")
            }, receiveValue: { (objects) in

                // both devices and group, which can also be referenced via myColletion.objects, which in turn is a Published attribute and hence can
                // be referenced directly from a swiftui View if myCollection is defined either as a @StateObject or @ObservedObject

                let devicesAndGroup: [AnyC8yObject] = objects

               ...
        })
} catch {
    print ("load failed \(error.localizedDescription)")
}

Devices and groups can be added to the collection using either the add(_:) or addGroupReference(c8yId:includeSubGroups:completionHandler:) methods e.g.

myCollection.add(device)
myCollection.addGroupReference(c8yId: "4343", includeSubgroups: true) { (group, error) in

    if (group != nil) {
        // success, group represents the managed object that has been fetched from c8y and added to your collection
        ...
    } else {
        // lookup failed, probably due to invalid reference, refer to error object for precision
        ...
}

You can reference the devices and groups via the objects attribute directly from your SwiftUI views. Ensure that you prefix the reference to you collection attribute with @ObservedObject or @StateObject to ensure that the view automatically updates if your collection changes e.g.

struct MyAssetsView: View {

    @Binding var conn: C8yCumulocityConnection
    @Binding var referenecs: [String]

    @StateObject var myCollection:C8yAssetCollection = C8yAssetCollection()
    @State var isLoading: Bool = false

    var body some View {
        VStack {
            ForEach(myCollection.objects) { r in
                Text("asset is \(r.name)")
            }
        }.onAppear {
            myCollection.load(self.conn, c8yReferencesToLoad: self.references, includeSubGroups: true)
                .sink(receiveCompletion: { (completion) in
                    self.isLoading = false
            }
        }
    }
}
  • Objects that published from this collection. Devices and Groups are wrapped in an AnyC8yObject instance to avoid collection ambiguity errors.

    Declaration

    Swift

    @Published
    public var objects: [AnyC8yObject] { get set }
  • The connection reference that was last used to load the collection via load(_:c8yReferencesToLoad:includeSubGroups:)

    Declaration

    Swift

    public internal(set) var connection: C8yCumulocityConnection? { get }
  • List of available network providers

    Declaration

    Swift

    public var networks: C8yNetworks { get }
  • Undocumented

    Declaration

    Swift

    public private(set) var groupCount: Int { get }
  • Undocumented

    Declaration

    Swift

    public private(set) var deviceCount: Int { get }
  • Default constructor, use from SwiftUI Views with the prefix @StateObject. You will need to call the load(:c8yReferencesToLoad:includeSubGroups) method to populate the collection

    WARNING

    Do not invoke the load() method from a SwiftUI View constructor as this will introduce severe performance issues, due to the fact the constructor can be called many times by SwiftUI. Instead invoke the method from the View’s onAppear lifecycle event emitter to ensure that it will only be called once.

    Declaration

    Swift

    public init()
  • Established a background thread to automatically refresh all of the assets in the collection i.e. detect changes made in Cumulocity automatically.

    Declaration

    Swift

    public func setRefresh(_ interval: Double, includeSubGroups: Bool)

    Parameters

    interval

    Interval in seconds

    includeSubGroups

    if true, sub groups are treated as unique entities, if false all subgroups are flattened i.e. any assets found in sub group will be added to top level group and sub group references ignored.

  • Disables background refresh thread Only applicable if the thread was started via setRefresh(:includeSubGroups:)

    Declaration

    Swift

    public func stopRefresh()
  • Force refresh the given asset, i.e. retrieve latest version from Cumulocity If the asset doesn’t yet exist in the collection it will added after the fetch

    Declaration

    Swift

    public func refreshAsset<T>(_ asset: T) where T : C8yObject

    Parameters

    asset

    device or group to be refreshed

  • Force a refresh of all assets in the collection

    Declaration

    Swift

    public func doRefresh(includeSubGroups: Bool, completionHandler: @escaping () -> Void)

    Parameters

    includeSubGroups

    if true, sub groups are treated as unique entities, if false all subgroups are flattened

    completionHandler

    Called once refresh has been completed

  • Call this method to populate your collection with the required assets. You can add and remove assets afterwards using the methods add(:), addGroupReference(c8yId:includeSubgroups:) or remove(c8yId:)

    Declaration

    Swift

    public func load(_ conn: C8yCumulocityConnection?, c8yReferencesToLoad: [String], includeSubGroups: Bool) throws -> AnyPublisher<[AnyC8yObject], JcConnectionRequest<C8yCumulocityConnection>.APIError>

    Parameters

    conn

    Connection to be used to used to download assets with

    c8yReferencesToLoad

    String array of c8y internal id’s to be fetched, can refresent either devices or group

    includeSubGroups

    if true, sub groups are treated as unique entities, if false all subgroups are flattened i.e. any sub-assets are added to top level group and sub group is ignored

  • Similar to load(:c8yReferencesToLoad:includeSubGroups) call this method to repopulate your collection with the required assets.

    Declaration

    Swift

    public func reload(_ c8yReferencesToLoad: [String], includeSubGroups: Bool) throws -> AnyPublisher<[AnyC8yObject], JcConnectionRequest<C8yCumulocityConnection>.APIError>?

    Parameters

    c8yReferencesToLoad

    String array of c8y internal id’s to be fetched, can refresent either devices or group

    includeSubGroups

    if true, sub groups are treated as unique entities, if false all subgroups are flattened i.e. any sub-assets are added to top level group and sub group is ignored

  • Clears out the collection, all assets will be removed locally

    Declaration

    Swift

    public func clear()
  • Returns true if the given group is referenced in the collection at the top-level

    Declaration

    Swift

    public func isInCollection(_ group: C8yGroup) -> Bool

    Parameters

    group

    The group to be looked up

    Return Value

    true if the group is referenced

  • Returns true if an asset with the given id is referenced in the collection at the top-level

    Declaration

    Swift

    public func isInCollection(_ c8yId: String) -> Bool

    Parameters

    c8yId

    c8y internal id of the asset

    Return Value

    true if asset is referenced

  • Returns the group for the given id, or nil if not found. The group can be a sub-group of one of the referenced groups.

    NOTE - Only checks the local cache, if you want to look up devices in cumulocity use one of the lookupGroup(c8yId:completionHandler:) methods

    Declaration

    Swift

    public func groupFor(c8yId: String) -> C8yGroup?

    Parameters

    c8yId

    c8y internal id of the group to be found.

    Return Value

    the group object or nil if not found

  • Returns the first group with a name that contains the given fragment or nil if not found. The group can be a sub-group of one of the referenced groups.

    NOTE - Only checks the local cache, if you want to look up devices in cumulocity use one of the lookupGroup(c8yId:completionHandler:) methods

    Declaration

    Swift

    public func groupFor(name: String) -> C8yGroup?

    Parameters

    name

    name fragment

    Return Value

    the group object or nil if not found

  • Returns the device for the given id, or nil if not found. The device can be in a sub-group somewhere of one of the referenced groups.

    NOTE - Only checks the local cache, if you want to look up devices in cumulocity use one of the lookupDevice(c8yId:completionHandler:) methods

    Declaration

    Swift

    public func deviceFor(_ ref: String) -> C8yDevice?

    Parameters

    c8yId

    c8y internal id of the device to be found.

    Return Value

    the device object or nil if not found

  • Returns the device for the given external id, or nil if not found. The device can be in a sub-group somewhere of one of the referenced groups.

    NOTE - Only checks the local cache, if you want to look up devices in cumulocity use one of the lookupDevice(c8yId:completionHandler:) methods

    Declaration

    Swift

    public func deviceFor(externalId: String, ofType type: String) -> C8yDevice?

    Parameters

    externalId

    externall id of the device to be found.

    ofType

    code descrbing external id type e.g. ‘c8y_Serial’

    Return Value

    the device object or nil if not found

  • Returns the asset for the given id, or nil if not found. The asset can be in a sub-group somewhere of one of the referenced groups. Currently two asset types are supported, namely devices or groups. In either case the returned object is contained in a AnyCV8yObject object.

    NOTE - Only checks the local cache, if you want to look up assets in cumulocity use one of the lookupDevice(c8yId:completionHandler:) or lookupGroup(c8yId:completionHandler:)methods

    Declaration

    Swift

    public func objectFor(_ ref: String) -> (path: [String]?, object: AnyC8yObject?)

    Parameters

    c8yId

    c8y internal id of the asset to be found.

    Return Value

    the asset object or nil if not found

  • Replaces an existing asset with the given asset using the object c8y internal id.

    Declaration

    Swift

    public func replaceObjectFor<T>(_ obj: T) -> Bool where T : C8yObject

    Parameters

    obj

    The asset to be replaced

    Return Value

    If the asset is not found, no change is effected and false is returned.

  • Adds an asset to the collection NOTE - This has no impact on the back-end, assumption is that the asset already exists, otherwise use the create(:completionHandler:) method

    Declaration

    Swift

    public func add<T>(_ object: T) where T : C8yObject

    Parameters

    object

    The asset to be added to the collection.

  • Removes the asset with the given id it from the local collection regardles of where it is in the hireachy of groups.

    NOTE - This has no impact on the back-end, use the delete(:completionHandler:) method if you want to really delete the asset from cumulocity

    Declaration

    Swift

    public func remove(c8yId: String) -> Bool

    Parameters

    c8yId

    c8y internal id for object to be deleted

  • Fetches the group asset from c8y and adds it to the local collection.

    Declaration

    Swift

    public func addGroupReference(c8yId: String, includeSubGroups: Bool, completionHandler: @escaping (C8yGroup?, Error?) -> Void)

    Parameters

    c8yId

    the c8y internal id of the group to be added to the local collection.

    includeSubGroups

    if true, sub groups are treated as unique entities, if false all subgroups are flattened i.e. any found sub-assets will be added to the top level group and sub group is ignored

    completionHandler

    Called once fetch has completed, includes either group object if fetched successfully or the error description if it failed.

  • Creates the new asset in Cumulocity and then adds it to the local collection if successful Creation might fail if connection access rights are insufficient or a mandatory attribute is missing.

    Throws

    Invalid object i.e. mandatory field missing

    Declaration

    Swift

    public func create<T>(_ object: T, completionHandler: @escaping (T?, Error?) -> Void) throws where T : C8yObject

    Parameters

    object

    The cumulocity asset to be created and then referenced locally

    completionHandler

    Called once insert has completed, includes either asset object if insert successful or the error description if it failed.

  • Saves any changes to the asset in Cumulocity NOTE: Will NOT update any changed external id’s, use the register(externalId:ofType:forId:) method to register or replace an existing external id

    Throws

    Invalid object i.e. mandatory field missing

    Declaration

    Swift

    public func saveObject<T>(_ object: T, completionHandler: @escaping (Bool, Error?) -> Void) throws where T : C8yObject

    Parameters

    object

    The cumulocity asset to be created and then referenced locally

    completionHandler

    Called once save has completed, returns a boolean indicating if save was successful.

  • Deletes the existing asset from Cumulocity and then removed it from the local collection if necessary Deletion might fail if either the asset doesn’t exist or connection access rights are insufficient

    Declaration

    Swift

    public func delete(c8yId: String, completionHandler: ((Bool) -> Void)? = nil)

    Parameters

    c8yId

    c8y internal id for object to be deleted

    completionHandler

    Called once delete has completed, returns true if delete was done, false if not

  • Convenience method that allows a new device or group to be created and then added to an existing group or sub-group. Following which, it then ensures that the local collection is updated to reflect any changes.

    Throws

    Invalid object i.e. mandatory field missing

    Declaration

    Swift

    public func createInGroup<T>(_ object: T, c8yOfGroup: String, completionHandler: @escaping (T?, Error?) -> Void) throws where T : C8yObject

    Parameters

    object

    The asset to be created in Cumulocity

    c8yOfGroup

    The group to which it should be assigned once the object has been created.

    completinoHandler

    Called when operation has been completed to indicate success or failure

  • Convenience method that allows an existing device or group to be added to an existing group or sub-group. Following which, it then ensures that the local collection is updated to reflect any changes.

    Declaration

    Swift

    public func assignToGroup<T>(_ object: T, c8yOfGroup: String, completionHandler: @escaping (T?, Error?) -> Void) where T : C8yObject

    Parameters

    object

    The asset to be created in Cumulocity

    c8yOfGroup

    The group to which it should be assigned once the object has been created.

    completinoHandler

    Called when operation has been completed to indicate success or failure

  • Returns the group for the given c8y internal id, or nil if not found. It first checks in the local cache and if not found queries the back-end cumulocity tenant The group is NOT added to the local collection if not found locally.

    Declaration

    Swift

    public func lookupGroup(c8yId id: String, completionHandler: @escaping (C8yGroup?, Error?) -> Void)

    Parameters

    c8yId

    c8y internal id of the group to be found.

    completionHandler

    callback that received the fetched group or error if failed

  • Returns the device for the given c8y internal id, or nil if not found. It first checks in the local cache and if not found queries the back-end cumulocity tenant The device is NOT added to the local collection if not found locally.

    Declaration

    Swift

    public func lookupDevice(c8yId id: String, completionHandler: @escaping (C8yDevice?, Error?) -> Void)

    Parameters

    c8yId

    c8y internal id of the device to be found.

    completionHandler

    callback that received the fetched device or error if failed

  • Returns the device for the given external id and type, or nil if not found. It first checks in the local cache and if not found queries the back-end cumulocity tenant The device is NOT added to the local collection if not found locally.

    Declaration

    Swift

    public func lookupDevice(forExternalId id: String, type: String, completionHandler: @escaping (Result<C8yDevice, Error>) -> Void)

    Parameters

    id

    external id of the device to be found.

    type

    code descrbing external id type e.g. ‘c8y_Serial’

    completionHandler

    callback that receives the fetched device, nil if not found or error if failed

  • Returns the group for the given external id and type, or nil if not found. It first checks in the local cache and if not found queries the back-end cumulocity tenant The group is NOT added to the local collection if not found locally.

    Declaration

    Swift

    public func lookupGroup(forExternalId id: String, type: String, completionHandler: @escaping (Result<C8yGroup, Error>) -> Void)

    Parameters

    id

    external id of the group to be found.

    ofType

    code descrbing external id type e.g. ‘c8y_Serial’

    completionHandler

    callback that receives the fetched group, nil if not found or error if failed