DataServiceAsync

@available(swift 5.5)
open class DataServiceAsync : ObjectBase

Encapsulates an OData data service.

See also

DataQuery.

Example using proxy classes

open func dataServiceExample() throws -> Void {
    let provider = OnlineODataProvider(serviceName: "NorthwindService",
        serviceRoot: "http://services.odata.org/V4/Northwind/Northwind.svc/")
    let service = NorthwindService(provider: provider)
    let query = DataQuery()
        .select(Customer.customerID, Customer.companyName, Customer.contactName)
        .orderBy(Customer.companyName)
    let customers = try service.fetchCustomers(matching: query)
    self.showCustomers(customers)
    let customer = customers.first!.copy()
    customer.companyName = "Created Inc."
    try service.createEntity(customer)
    customer.companyName = "Updated Inc."
    try service.updateEntity(customer)
    try service.deleteEntity(customer)
}

Example using dynamic API

open func dataServiceExample() throws -> Void {
    let provider = OnlineODataProvider(serviceName: "NorthwindService",
        serviceRoot: "http://services.odata.org/V4/Northwind/Northwind.svc/")
    let service = DataService(provider: provider)
    try service.loadMetadata()
    let customersEntitySet = service.entitySet(withName: "Customers")
    let customerEntityType = customersEntitySet.entityType
    let customerIDProperty = customerEntityType.property(withName: "CustomerID")
    let companyNameProperty = customerEntityType.property(withName: "CompanyName")
    let contactNameProperty = customerEntityType.property(withName: "ContactName")
    let query = DataQuery()
        .select(customerIDProperty, companyNameProperty, contactNameProperty)
        .from(customersEntitySet).orderBy(companyNameProperty)
    let customers = try service.executeQuery(query).entityList()
    self.showCustomers(customers)
    let customer = customers.first().copyEntity()
    companyNameProperty.setStringValue(in: customer, to: "Created Inc.")
    try service.createEntity(customer)
    companyNameProperty.setStringValue(in: customer, to: "Updated Inc.")
    try service.updateEntity(customer)
    try service.deleteEntity(customer)
}
  • Operation queue to be used by this data service for actions (e.g. create / update / delete methods). By default the maximum number of queued operations that can execute at the same time is 1 (serial execution).

    Declaration

    Swift

    public var actionQueue: OperationQueue { get set }
  • Operation queue to be used by this data service for functions (e.g. query methods). By default the maximum number of queued operations that can execute at the same time is 10 (parallel execution).

    Declaration

    Swift

    public var functionQueue: OperationQueue { get set }
  • Operation queue to be used for completion handlers. Defaults to main (UI) thread.

    Declaration

    Swift

    public var completionQueue: OperationQueue { get set }
  • Execute task asynchronously on actionQueue.

    Declaration

    Swift

    open func asyncAction(_ task: @escaping () -> Void)
  • Execute task asynchronously on functionQueue.

    Declaration

    Swift

    open func asyncFunction(_ task: @escaping () -> Void)
  • Undocumented

    Declaration

    Swift

    public var backgroundQueueForAction: OperationQueue { get set }
  • Undocumented

    Declaration

    Swift

    public var backgroundQueueForFunction: OperationQueue { get set }
  • Undocumented

    Declaration

    Swift

    open func addBackgroundOperationForAction(_ operation: @escaping () -> Void)
  • Undocumented

    Declaration

    Swift

    open func addBackgroundOperationForFunction(_ operation: @escaping () -> Void)
  • Construct a new data service using a specified provider.

    Declaration

    Swift

    public init(provider: DataServiceProvider)

    Parameters

    provider

    Data service provider.

  • (Asynchronous) Activate a draft entity.

    See also

    makeDraftCopy, EntityValue.withCreate, EntityValue.withUpdate, EntityValue.withDeepCreate, EntityValue.withDeepUpdate.

    Example using proxy classes

    open func activateDraftExample() throws -> Void {
        let service = self.healthService
        var patient = Patient()
        patient.firstName = "Sherlock"
        patient.lastName = "Holmes"
        try service.createEntity(patient.asDraft())
        // Upload pending requests, but not the draft patient.
        try service.upload()
        // Associate a new draft appointment with the draft patient.
        let appointment = Appointment()
        appointment.purpose = "General Checkup"
        try service.createRelatedEntity(appointment.asDraft(), in: patient,
            property: Patient.appointments)
        // Some time later... Activate the patient (and related appointments).
        patient = try (service.activateDraft(patient.withDeepCreate(Patient.appointments)) as! Patient)
        // Some time later... Upload the create of patient (and deep-created appointments).
        try service.upload()
    }
    

    Declaration

    Swift

    open func activateDraft(_ entity: EntityValue, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) async throws -> EntityValue

    Parameters

    entity

    Draft entity.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

    Return Value

    Newly activated copy of the draft entity.

  • (Asynchronous) Apply the changes from a change set to the target system.

    See also

    processBatch.

    Example using proxy classes

    open func applyChangesExample() throws -> Void {
        let service = self.service
        let suppliers = try service.fetchSuppliers(matching: DataQuery().top(2))
        let products = try service.fetchProducts(matching: DataQuery().top(3))
        let product1 = products[0].copy()
        let product2 = products[1].copy()
        let product3 = products[2].copy()
        product1.productName = "Blueberry Muffins"
        product2.productName = "Strawberry Yoghurt"
        product3.productName = "Raspberry Pie"
        let entityCreates = ChangeSet()
        entityCreates.createEntity(product1)
        entityCreates.createEntity(product2)
        entityCreates.createEntity(product3)
        try service.applyChanges(entityCreates)
        let entityChanges = ChangeSet()
        product2.productName = "Blackberry Yoghurt"
        entityChanges.updateEntity(product2)
        entityChanges.deleteEntity(product3)
        try service.applyChanges(entityChanges)
        let linkChanges = ChangeSet()
        let supplier1 = suppliers[0]
        let supplier2 = suppliers[1]
        linkChanges.createLink(from: product1, property: Product.supplier,
            to: supplier1)
        linkChanges.updateLink(from: product1, property: Product.supplier,
            to: supplier2)
        linkChanges.deleteLink(from: product1, property: Product.supplier)
        try service.applyChanges(linkChanges)
    }
    

    Example using dynamic API

    open func applyChangesExample() throws -> Void {
        let service = self.service
        let suppliersEntitySet = service.entitySet(withName: "Suppliers")
        let productsEntitySet = service.entitySet(withName: "Products")
        let productEntityType = productsEntitySet.entityType
        let productNameProperty = productEntityType.property(withName: "ProductName")
        let supplierProperty = productEntityType.property(withName: "Supplier")
        let suppliers = try service.executeQuery(DataQuery().from(suppliersEntitySet)
            .top(2))
            .entityList()
        let products = try service.executeQuery(DataQuery().from(productsEntitySet)
            .top(3))
            .entityList()
        let product1 = products.item(at: 0).copyEntity()
        let product2 = products.item(at: 1).copyEntity()
        let product3 = products.item(at: 1).copyEntity()
        productNameProperty.setStringValue(in: product1, to: "Blueberry Yoghurt")
        productNameProperty.setStringValue(in: product2, to: "Strawberry Yoghurt")
        productNameProperty.setStringValue(in: product3, to: "Raspberry Pie")
        let entityCreates = ChangeSet()
        entityCreates.createEntity(product1)
        entityCreates.createEntity(product2)
        entityCreates.createEntity(product3)
        try service.applyChanges(entityCreates)
        let entityChanges = ChangeSet()
        productNameProperty.setStringValue(in: product2, to: "Blackberry Yoghurt")
        entityChanges.updateEntity(product2)
        entityChanges.deleteEntity(product3)
        try service.applyChanges(entityChanges)
        let linkChanges = ChangeSet()
        let supplier1 = suppliers.item(at: 0)
        let supplier2 = suppliers.item(at: 1)
        linkChanges.createLink(from: product1, property: supplierProperty,
            to: supplier1)
        linkChanges.updateLink(from: product1, property: supplierProperty,
            to: supplier2)
        linkChanges.deleteLink(from: product1, property: supplierProperty)
        try service.applyChanges(linkChanges)
    }
    

    Declaration

    Swift

    open func applyChanges(_ changes: ChangeSet, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    changes

    The change set.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • Check if token has been marked for cancellation. If it has, throw RequestCancelledException.

    Declaration

    Swift

    open func checkIfCancelled(_ token: CancelToken?) throws

    Parameters

    token

    Cancellation token.

  • (Asynchronous) Create an entity in the target system. Automatically calls CsdlDocument.resolveEntity to ensure that EntityValue.entitySet is available.

    See also

    EntityValue.ofType, EntityValue.inSet, createRelatedEntity, Create Related Entities When Creating an Entity.

    Example using proxy classes

    open func createEntityExample() throws -> Void {
        let service = self.service
        let customer = Customer()
        customer.companyName = "Enterprise Inc."
        customer.contactName = "Jean-Luc Picard"
        try service.createEntity(customer)
    }
    

    Example using proxy classes

    open func deepCreateExample() throws -> Void {
        let service = self.service
        let customer = Customer()
        customer.companyName = "Enterprise Inc."
        customer.contactName = "LeVar Burton"
        let order1 = Order()
        let order2 = Order()
        customer.bindEntity(order1, to: Customer.orders)
        customer.bindEntity(order2, to: Customer.orders)
        try service.createEntity(customer.withDeepCreate())
    }
    

    Example using proxy classes

    open func createInSetExample() throws -> Void {
        let service = self.service
        let customer = Customer()
        customer.companyName = "Voyager Inc."
        customer.contactName = "Kathryn Janeway"
        try service.createEntity(customer.inSet(NorthwindService.customers))
    }
    

    Example using dynamic API

    open func createEntityExample() throws -> Void {
        let service = self.service
        let customersEntitySet = service.entitySet(withName: "Customers")
        let customerEntityType = customersEntitySet.entityType
        let companyNameProperty = customerEntityType.property(withName: "CompanyName")
        let contactNameProperty = customerEntityType.property(withName: "ContactName")
        let customer = EntityValue.ofType(customerEntityType)
        companyNameProperty.setStringValue(in: customer, to: "Enterprise Inc.")
        contactNameProperty.setStringValue(in: customer, to: "Jean-Luc Picard")
        try service.createEntity(customer)
    }
    

    Declaration

    Swift

    open func createEntity(_ entity: EntityValue, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    entity

    Entity to be created.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Create a link from a source entity to a target entity in the target system.

    Example using proxy classes

    open func createLinkExample() throws -> Void {
        let service = self.service
        let category = try service.fetchCategory(matching: DataQuery().skip(1).top(1))
        let product = try service.fetchProduct(matching: DataQuery().top(1))
        try service.createLink(from: category, property: Category.products,
            to: product)
    }
    

    Example using dynamic API

    open func createLinkExample() throws -> Void {
        let service = self.service
        let categoriesEntitySet = service.entitySet(withName: "Categories")
        let productsEntitySet = service.entitySet(withName: "Products")
        let categoryEntityType = categoriesEntitySet.entityType
        let productsProperty = categoryEntityType.property(withName: "Products")
        let category = try service.executeQuery(DataQuery().from(categoriesEntitySet)
            .skip(1).top(1))
            .requiredEntity()
        let product = try service.executeQuery(DataQuery().from(productsEntitySet)
            .top(1))
            .requiredEntity()
        try service.createLink(from: category, property: productsProperty,
            to: product)
    }
    

    Declaration

    Swift

    open func createLink(from: EntityValue, property: Property, to: EntityValue, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    from

    Source entity for the link to be created.

    property

    Source navigation property for the link to be created.

    to

    Target entity for the link to be created.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Create a media entity with the specified content. If the entity has non-stream structural properties in addition to the key properties and media content, such as label in the examples below, then this function will send two requests to the server: a first request to upload (POST) the media stream, and a second request (PATCH/PUT) to update the non-stream properties. It is not currently supported to make these two calls atomic. Caution: Having too many threads simultaneously creating streams may result in out-of-memory conditions on memory-constrained devices.

    Example using proxy classes

    open func createMediaExample() throws -> Void {
        let service = self.service
        let image = Image()
        image.label = "Smiley"
        let content = ByteStream.fromBinary(data: Base16Binary.convert("3A2D29"))
        content.mediaType = "text/plain"
        try service.createMedia(entity: image, content: content)
    }
    

    Example using dynamic API

    open func createMediaExample() throws -> Void {
        let service = self.service
        let imagesEntitySet = service.entitySet(withName: "Images")
        let imageEntityType = imagesEntitySet.entityType
        let labelProperty = imageEntityType.property(withName: "label")
        let image = EntityValue.ofType(imageEntityType)
        labelProperty.setStringValue(in: image, to: "Smiley")
        let content = ByteStream.fromBinary(data: Base16Binary.convert("3A2D29"))
        content.mediaType = "text/plain"
        try service.createMedia(entity: image, content: content)
    }
    

    Declaration

    Swift

    open func createMedia(entity: EntityValue, content: StreamBase, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    entity

    Entity to be created.

    content

    Initial content. Must be a ByteStream or CharStream. Will be closed before this function returns.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Create an entity in the target system, related to an existing parent entity via a parent navigation property.

    Example using proxy classes

    open func createRelatedEntityExample() throws -> Void {
        let service = self.service
        let customer = try service.fetchCustomer(matching: DataQuery().top(1)
            .filter(Customer.customerID.equal("ALFKI")))
        let orders = try service.fetchOrders(matching: DataQuery().top(1))
        let newOrder = orders.first!.copy()
        try service.createRelatedEntity(newOrder, in: customer,
            property: Customer.orders)
    }
    

    Example using dynamic API

    open func createRelatedEntityExample() throws -> Void {
        let service = self.service
        let customersEntitySet = service.entitySet(withName: "Customers")
        let ordersEntitySet = service.entitySet(withName: "Orders")
        let customerEntityType = customersEntitySet.entityType
        let customerIDProperty = customerEntityType.property(withName: "CustomerID")
        let ordersProperty = customerEntityType.property(withName: "Orders")
        let customers = try service.executeQuery(DataQuery().from(customersEntitySet)
            .filter(customerIDProperty.equal("ALFKI")))
            .entityList()
        let orders = try service.executeQuery(DataQuery().from(ordersEntitySet)
            .top(1))
            .entityList()
        let customer = customers.first()
        let newOrder = orders.first().copyEntity()
        try service.createRelatedEntity(newOrder, in: customer,
            property: ordersProperty)
    }
    

    Declaration

    Swift

    open func createRelatedEntity(_ entity: EntityValue, in parent: EntityValue, property: Property, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    entity

    Entity to be created.

    parent

    Previously created parent entity.

    property

    Parent’s navigation property.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Create an media entity in the target system, related to a parent entity via a parent navigation property.

    Example using proxy classes

    open func createRelatedMediaExample() throws -> Void {
        let service = self.service
        let artist = Artist()
        artist.firstName = "Salvador"
        artist.lastName = "Dali"
        artist.dateOfBirth = LocalDate.of(year: 1904, month: 5, day: 11)
        artist.placeOfBirth = GeographyPoint.with(latitude: 42.266667,
            longitude: 2.965)
        try service.createEntity(artist)
        let image = Image()
        image.label = "Dream"
        let content = ByteStream.fromBinary(data: Base16Binary.convert("447265616D204361757365642062792074686520466C69676874206F662061204265652061726F756E64206120506F6D656772616E6174652061205365636F6E64204265666F7265204177616B656E696E67"))
        content.mediaType = "text/plain"
        try service.createRelatedMedia(entity: image, content: content, in: artist,
            property: Artist.images)
    }
    

    Example using dynamic API

    open func createRelatedMediaExample() throws -> Void {
        let service = self.service
        let artistsEntitySet = service.entitySet(withName: "Artists")
        let artistEntityType = artistsEntitySet.entityType
        let firstNameProperty = artistEntityType.property(withName: "firstName")
        let lastNameProperty = artistEntityType.property(withName: "lastName")
        let dateOfBirthProperty = artistEntityType.property(withName: "dateOfBirth")
        let placeOfBirthProperty = artistEntityType.property(withName: "placeOfBirth")
        let imagesProperty = artistEntityType.property(withName: "images")
        let imagesEntitySet = service.entitySet(withName: "Images")
        let imageEntityType = imagesEntitySet.entityType
        let labelProperty = imageEntityType.property(withName: "label")
        let artist = EntityValue.ofType(artistEntityType)
        firstNameProperty.setStringValue(in: artist, to: "Maurits")
        lastNameProperty.setStringValue(in: artist, to: "Escher")
        dateOfBirthProperty.setDataValue(in: artist,
            to: LocalDate.of(year: 1898, month: 6, day: 17))
        placeOfBirthProperty.setDataValue(in: artist,
            to: GeographyPoint.with(latitude: 53.2, longitude: 5.783333))
        try service.createEntity(artist)
        let image = EntityValue.ofType(imageEntityType)
        labelProperty.setStringValue(in: image, to: "Hands")
        let content = ByteStream.fromBinary(data: Base16Binary.convert("44726177696E672048616E6473"))
        content.mediaType = "text/plain"
        try service.createRelatedMedia(entity: image, content: content, in: artist,
            property: imagesProperty)
    }
    

    Declaration

    Swift

    open func createRelatedMedia(entity: EntityValue, content: StreamBase, in parent: EntityValue, property: Property, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    entity

    Entity to be created.

    content

    Initial content. Must be a ByteStream or CharStream. Will be closed before this function returns.

    parent

    Previously created parent entity.

    property

    Parent’s navigation property.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • Lookup a data method by qualified name (for function/action definitions) or by unqualified name (for function/action imports). Panic if the data method does not exist.

    Example checking if a data method exists

    open func checkDataMethodExistsExample() throws -> Void {
        let service = self.service
        let csdlDocument = service.metadata
        if csdlDocument.dataMethods.containsValue(forKey: "Microsoft.OData.Service.Sample.TrippinInMemory.Models.Person.UpdatePersonLastName") {
            _ = service.dataMethod(withName: "Microsoft.OData.Service.Sample.TrippinInMemory.Models.Person.UpdatePersonLastName")
        } else {
            // The data method UpdatePersonLastName does not exists, add logic to handle the issue/throw an Exception, etc..
        }
    }
    

    See also

    metadata.dataMethods, for looking up data methods that might not exist.

    Declaration

    Swift

    open func dataMethod(withName name: String) -> DataMethod

    Parameters

    name

    Name of the data method to be returned.

    Return Value

    The requested data method.

  • (Asynchronous) Execute query to delete data from the target system.

    Declaration

    Swift

    open func deleteByQuery(_ query: DataQuery, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    query

    Data query specifying the information to be deleted.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Delete an entity from the target system.

    Example using proxy classes

    open func deleteEntityExample() throws -> Void {
        let service = self.service
        let query = DataQuery().top(1).selectKey().filter(Customer.contactName.equal("William Riker"))
        let customer = try service.fetchCustomer(matching: query)
        try service.deleteEntity(customer)
    }
    

    Example using dynamic API

    open func deleteEntityExample() throws -> Void {
        let service = self.service
        let customersEntitySet = service.entitySet(withName: "Customers")
        let customerEntityType = customersEntitySet.entityType
        let contactNameProperty = customerEntityType.property(withName: "ContactName")
        let query = DataQuery().top(1).selectKey().from(customersEntitySet)
            .filter(contactNameProperty.equal("William Riker"))
        let customer = try service.executeQuery(query).requiredEntity()
        try service.deleteEntity(customer)
    }
    

    Declaration

    Swift

    open func deleteEntity(_ entity: EntityValue, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    entity

    Entity to be deleted.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Delete a link from a source entity to a target entity.

    Example using proxy classes

    open func deleteLinkExample1() throws -> Void {
        // Delete link from many-to-one relationship.
        let service = self.service
        let product = try service.fetchProduct(matching: DataQuery().top(1))
        try service.deleteLink(from: product, property: Product.supplier)
    }
    

    Example using proxy classes

    open func deleteLinkExample2() throws -> Void {
        // Delete link from one-to-many relationship.
        let service = self.service
        let category = try service.fetchCategory(matching: DataQuery().skip(1).top(1))
        let product = try service.fetchProduct(matching: DataQuery().top(1))
        try service.deleteLink(from: category, property: Category.products,
            to: product)
    }
    

    Example using dynamic API

    open func deleteLinkExample1() throws -> Void {
        // Delete link from many-to-one relationship.
        let service = self.service
        let productsEntitySet = service.entitySet(withName: "Products")
        let productEntityType = productsEntitySet.entityType
        let supplierProperty = productEntityType.property(withName: "Supplier")
        let product = try service.executeQuery(DataQuery().from(productsEntitySet)
            .top(1))
            .requiredEntity()
        try service.deleteLink(from: product, property: supplierProperty)
    }
    

    Example using dynamic API

    open func deleteLinkExample2() throws -> Void {
        // Delete link from one-to-many relationship.
        let service = self.service
        let categoriesEntitySet = service.entitySet(withName: "Categories")
        let productsEntitySet = service.entitySet(withName: "Products")
        let categoryEntityType = categoriesEntitySet.entityType
        let productsProperty = categoryEntityType.property(withName: "Products")
        let category = try service.executeQuery(DataQuery().from(categoriesEntitySet)
            .skip(1).top(1))
            .requiredEntity()
        let product = try service.executeQuery(DataQuery().from(productsEntitySet)
            .top(1))
            .requiredEntity()
        try service.deleteLink(from: category, property: productsProperty,
            to: product)
    }
    

    Declaration

    Swift

    open func deleteLink(from: EntityValue, property: Property, to: EntityValue = EntityValue.ofType(EntityType.undefined), headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    from

    Source entity for the link to be deleted.

    property

    Source navigation property for the link to be deleted.

    to

    Target entity for the link to be deleted. Can be omitted for a single-valued navigation property.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Delete the content of a stream property from the target system.

    Declaration

    Swift

    open func deleteStream(entity: EntityValue, link: StreamLink, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    entity

    Entity containing the stream property whose content is to be deleted.

    link

    Stream link for the stream to be deleted.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Obtain a stream for downloading the content of a media entity from the target system. Caution: streams are often used for large content that may not fit (all at once) in available application memory. Having too many threads simultaneously downloading streams, or using ByteStream.readAndClose, may result in out-of-memory conditions on memory-constrained devices.

    Example using proxy classes

    open func downloadMediaExample() throws -> Void {
        let service = self.service
        let query = DataQuery().filter(Image.label.equal("Smiley")).top(1)
        let image = try service.fetchImage(matching: query)
        let stream = try service.downloadMedia(entity: image)
        let data = try stream.readAndClose()
        assert(BinaryOperator.equal(data, Base16Binary.convert("3B2D29")))
        assert(OptionalString.hasValue(stream.mediaType, "text/plain"))
    }
    

    Example using dynamic API

    open func downloadMediaExample() throws -> Void {
        let service = self.service
        let imagesEntitySet = service.entitySet(withName: "Images")
        let imageEntityType = imagesEntitySet.entityType
        let labelProperty = imageEntityType.property(withName: "label")
        let query = DataQuery().from(imagesEntitySet).filter(labelProperty.equal("Smiley"))
            .top(1)
        let image = try service.executeQuery(query).requiredEntity()
        let stream = try service.downloadMedia(entity: image)
        let data = try stream.readAndClose()
        assert(BinaryOperator.equal(data, Base16Binary.convert("3B2D29")))
        assert(OptionalString.hasValue(stream.mediaType, "text/plain"))
    }
    

    Declaration

    Swift

    open func downloadMedia(entity: EntityValue, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws -> Data

    Parameters

    entity

    Entity whose content is to be downloaded.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

    Return Value

    A stream for downloading the content of a media entity. This must be closed by the caller, or else a resource leak may occur.

  • (Asynchronous) Obtain a stream for downloading the content of a stream property from the target system. Caution: streams are often used for large content that may not fit (all at once) in available application memory. Having too many threads simultaneously downloading streams, or using ByteStream.readAndClose, may result in out-of-memory conditions on memory-constrained devices.

    See also

    Property.getStreamLink.

    Example using proxy classes

    open func downloadStreamExample() throws -> Void {
        let service = self.service
        let query = DataQuery().filter(Video.label.equal("Happier")).top(1)
        let video = try service.fetchVideo(matching: query)
        let stream = try service.downloadStream(entity: video, link: video.content)
        let data = try stream.readAndClose()
        assert(BinaryOperator.equal(data, Base16Binary.convert("68617070792D7374756666")))
        assert(OptionalString.hasValue(stream.mediaType, "text/plain"))
    }
    

    Example using dynamic API

    open func downloadStreamExample() throws -> Void {
        let service = self.service
        let videosEntitySet = service.entitySet(withName: "Videos")
        let videoEntityType = videosEntitySet.entityType
        let labelProperty = videoEntityType.property(withName: "label")
        let contentProperty = videoEntityType.property(withName: "content")
        let query = DataQuery().from(videosEntitySet).filter(labelProperty.equal("Happier"))
            .top(1)
        let video = try service.executeQuery(query).requiredEntity()
        let link = contentProperty.streamLink(from: video)
        let stream = try service.downloadStream(entity: video, link: link)
        let data = try stream.readAndClose()
        assert(BinaryOperator.equal(data, Base16Binary.convert("2E2E2E")))
        assert(OptionalString.hasValue(stream.mediaType, "text/plain"))
    }
    

    Declaration

    Swift

    open func downloadStream(entity: EntityValue, link: StreamLink, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws -> Data

    Parameters

    entity

    Entity containing the stream property whose content is to be downloaded.

    link

    Stream link for the stream to be downloaded.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

    Return Value

    A stream for downloading the content of a stream property. This must be closed by the caller, or else a resource leak may occur.

  • Lookup an entity set by name. Panic if the entity set does not exist.

    Example checking if an entity set exists

    open func checkEntitySetExistsExample() throws -> Void {
        let service = self.service
        if service.metadata.entitySets.containsValue(forKey: "Categories") {
            _ = service.entitySet(withName: "Categories")
        } else {
            // The entity set Categories does not exists, add logic to handle the issue/throw an Exception, etc..
        }
    }
    

    See also

    metadata.entitySets, for looking up entity sets that might not exist.

    Declaration

    Swift

    open func entitySet(withName name: String) -> EntitySet

    Parameters

    name

    Name of the entity set to be returned.

    Return Value

    The requested entity set.

  • (Asynchronous) Execute a data method (action or function) in the target system. Actions may have backend side-effects. Functions should not have backend side-effects.

    Declaration

    Swift

    open func executeMethod(_ method: DataMethod, parameters: ParameterList = ParameterList.empty, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws -> DataValue?

    Parameters

    method

    Data method.

    parameters

    Method parameters.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

    Return Value

    The method result, or nil if the method has no result.

  • (Asynchronous) Execute a data query to get data from the target system.

    Declaration

    Swift

    open func executeQuery(_ query: DataQuery, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws -> QueryResult

    Parameters

    query

    Data query specifying the information to be returned.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

    Return Value

    The query result.

  • (Asynchronous) Fetch latest service metadata and return it, but don’t change the metadata property.

    See also

    loadMetadata.

    Declaration

    Swift

    open func fetchMetadata(headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws -> CSDLDocument

    Parameters

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

    Return Value

    Latest service metadata.

  • Has service metadata been loaded.

    See also

    loadMetadata.

    Declaration

    Swift

    open var hasMetadata: Bool { get }
  • Checks locally whether a previous registerClient call successfuly created a client registration for the remote OData service.

    Declaration

    Swift

    open func isClientRegistered() throws -> Bool

    Return Value

    true if a registration was already established.

  • (Asynchronous) Reload an existing entity from the target system.

    Example using proxy classes

    open func loadEntityExample() throws -> Void {
        let service = self.service
        let customer = Customer()
        customer.customerID = "ALFKI"
        try service.loadEntity(customer)
        self.showCustomer(customer)
    }
    

    Example using dynamic API

    open func loadEntityExample() throws -> Void {
        let service = self.service
        let customersEntitySet = service.entitySet(withName: "Customers")
        let customerEntityType = customersEntitySet.entityType
        let customerIDProperty = customerEntityType.property(withName: "CustomerID")
        let customer = EntityValue.ofType(customerEntityType)
        customerIDProperty.setStringValue(in: customer, to: "ALFKI")
        try service.loadEntity(customer)
        self.showCustomer(customer)
    }
    

    Declaration

    Swift

    open func loadEntity(_ entity: EntityValue, query: DataQuery? = nil, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) async throws

    Parameters

    entity

    Previously loaded entity, whose properties will be modified to reflect the loaded state.

    query

    Optional data query, to specify loading criteria (especially for navigation properties).

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Load service metadata into provider (if not already loaded).

    See also

    metadata, hasMetadata.

    Declaration

    Swift

    open func loadMetadata(headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Load the value of a property into an existing entity. This can be applied to both structural and navigation properties.

    Example using proxy classes

    open func loadPropertyExample() throws -> Void {
        let service = self.service
        let query = DataQuery()
            .select(Customer.customerID, Customer.companyName, Customer.contactName)
            .filter(Customer.customerID.equal("ALFKI").or(Customer.customerID.equal("ANATR")))
        let responseHeaders = HTTPHeaders()
        let requestOptions = RequestOptions()
        requestOptions.captureResponseHeaders = responseHeaders
        let customers = try service.fetchCustomers(matching: query, headers: nil,
            options: requestOptions)
        var countOrders = 0
        for customer in customers {
            self.showCustomer(customer)
            try service.loadProperty(Customer.orders, into: customer)
            let orders = customer.orders
            for order in orders {
                let orderID = order.orderID
                try Example.show("  Order ", Example.formatInt(orderID))
                countOrders = countOrders + 1
            }
        }
        assert(countOrders > 0)
        assert(self.checkContentTypeJson(headers: responseHeaders))
    }
    

    Example using proxy classes (in request batch)

    open func loadPropertyInBatchExample() throws -> Void {
        let service = self.service
        let query = DataQuery()
            .select(Customer.customerID, Customer.companyName, Customer.contactName)
            .filter(Customer.customerID.equal("ALFKI").or(Customer.customerID.equal("ANATR")))
        let customers = try service.fetchCustomers(matching: query)
        let customer1 = customers[0]
        let customer2 = customers[1]
        let query1 = DataQuery().load(customer1, Customer.orders)
        let query2 = DataQuery().load(customer2, Customer.orders)
        let secondResponseHeaders = HTTPHeaders()
        let secondRequestOptions = RequestOptions()
        secondRequestOptions.captureResponseHeaders = secondResponseHeaders
        let batch = RequestBatch()
        batch.addQuery(query1)
        batch.addQuery(query2, headers: nil, options: secondRequestOptions)
        try service.processBatch(batch)
        let result1 = batch.queryResult(for: query1)
        let result2 = batch.queryResult(for: query2)
        let orders1 = try Order.array(from: result1.entityList())
        let orders2 = try Order.array(from: result2.entityList())
        assert(orders1.count != 0)
        assert(orders2.count != 0)
        customer1.orders = orders1
        customer2.orders = orders2
        assert(self.checkContentTypeJson(headers: secondResponseHeaders))
    }
    

    Example using dynamic API

    open func loadPropertyExample() throws -> Void {
        let service = self.service
        let customersEntitySet = service.entitySet(withName: "Customers")
        let customerEntityType = customersEntitySet.entityType
        let customerIDProperty = customerEntityType.property(withName: "CustomerID")
        let companyNameProperty = customerEntityType.property(withName: "CompanyName")
        let contactNameProperty = customerEntityType.property(withName: "ContactName")
        let ordersProperty = customerEntityType.property(withName: "Orders")
        let orderIDProperty = ordersProperty.itemEntityType.property(withName: "OrderID")
        let query = DataQuery()
            .select(customerIDProperty, companyNameProperty, contactNameProperty)
            .from(customersEntitySet)
            .filter(customerIDProperty.equal("ALFKI").or(customerIDProperty.equal("ANATR")))
        let customers = try service.executeQuery(query).entityList()
        var countOrders = 0
        for customer in customers {
            self.showCustomer(customer)
            try service.loadProperty(ordersProperty, into: customer)
            let orders = ordersProperty.entityList(from: customer)
            for order in orders {
                let orderID = orderIDProperty.intValue(from: order)
                try Example.show("  Order ", Example.formatInt(orderID))
                countOrders = countOrders + 1
            }
        }
        assert(countOrders > 0)
    }
    

    Example using dynamic API (in request batch)

    open func loadPropertyInBatchExample() throws -> Void {
        let service = self.service
        let customersEntitySet = service.entitySet(withName: "Customers")
        let customerEntityType = customersEntitySet.entityType
        let customerIDProperty = customerEntityType.property(withName: "CustomerID")
        let companyNameProperty = customerEntityType.property(withName: "CompanyName")
        let contactNameProperty = customerEntityType.property(withName: "ContactName")
        let ordersProperty = customerEntityType.property(withName: "Orders")
        let query = DataQuery()
            .select(customerIDProperty, companyNameProperty, contactNameProperty)
            .from(customersEntitySet)
            .filter(customerIDProperty.equal("ALFKI").or(customerIDProperty.equal("ANATR")))
        let customers = try service.executeQuery(query).entityList()
        let customer1 = customers.item(at: 0)
        let customer2 = customers.item(at: 1)
        let query1 = DataQuery().load(customer1, ordersProperty)
        let query2 = DataQuery().load(customer2, ordersProperty)
        let batch = RequestBatch()
        batch.addQuery(query1)
        batch.addQuery(query2)
        try service.processBatch(batch)
        let result1 = batch.queryResult(for: query1)
        let result2 = batch.queryResult(for: query2)
        let orders1 = try result1.entityList()
        let orders2 = try result2.entityList()
        assert(orders1.length != 0)
        assert(orders2.length != 0)
        ordersProperty.setEntityList(in: customer1, to: orders1)
        ordersProperty.setEntityList(in: customer2, to: orders2)
    }
    

    See also

    DataQuery.load.

    Declaration

    Swift

    open func loadProperty(_ property: Property, into: EntityValue, query: DataQuery? = nil, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    property

    Property to load.

    into

    Existing entity.

    query

    Optional data query, to specify loading criteria (especially for navigation properties).

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Create a draft copy of an entity. If the draft copy is intended to be subsequently activated to update (edit) the original entity, use EntityValue.forUpdate or EntityValue.forDeepUpdate to indicate this. If the draft copy is intended to be subsequently activated to create a clone of the original entity, use EntityValue.forCreate or EntityValue.forDeepCreate to indicate this.

    See also

    activateDraft, EntityValue.forCreate, EntityValue.forUpdate, EntityValue.forDeepCreate, EntityValue.forDeepUpdate.

    Example using proxy classes

    open func makeDraftCopyExample() throws -> Void {
        let service = self.healthService
        var patient = self.selectPatient()
        patient = try (service.makeDraftCopy(patient.forDeepUpdate(Patient.appointments)) as! Patient)
        patient.address = "221B Baker Street"
        try service.updateEntity(patient)
        try service.loadProperty(Patient.appointments, into: patient)
        for appointment in patient.appointments {
            appointment.dateTime = appointment.dateTime.plusDays(7)
            try service.updateEntity(appointment)
        }
        // Some time later... Activate the draft copy of patient (and related appointments).
        patient = try (service.activateDraft(patient.withDeepUpdate(Patient.appointments)) as! Patient)
        // Some time later... Upload the update of patient (and deep-updated appointments).
        try service.upload()
    }
    

    Declaration

    Swift

    open func makeDraftCopy(_ entity: EntityValue, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) async throws -> EntityValue

    Parameters

    entity

    Original entity.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

    Return Value

    Newly created draft copy of the original entity.

  • Service metadata.

    See also

    loadMetadata.

    Declaration

    Swift

    open var metadata: CSDLDocument { get }
  • A readers/writer lock that can be used to prevent readers from using the data service while the metadata is being refreshed.

    See also

    refreshMetadata.

    Declaration

    Swift

    open var metadataLock: MetadataLock { get }
  • Service name.

    Declaration

    Swift

    open var name: String { get }
  • (Asynchronous) Ping the server.

    Declaration

    Swift

    open func pingServer(headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Execute a request batch in the target system.

    See also

    RequestBatch.

    Example using proxy classes

    open func processBatchExample() throws -> Void {
        let service = self.service
        let supplier1 = try service.fetchSupplier(matching: DataQuery().top(1))
        let supplier2 = supplier1.copy()
        let supplier3 = supplier1.copy()
        let supplier4 = supplier1.copy()
        supplier2.companyName = "Alpha Inc."
        supplier3.companyName = "Beta Inc."
        try service.createEntity(supplier2)
        try service.createEntity(supplier3)
        supplier3.companyName = "Gamma Inc."
        let product1 = try service.fetchProduct(matching: DataQuery().top(1))
        let product2 = product1.copy()
        product2.productName = "Delta Cake"
        let batch = RequestBatch()
        let changes = ChangeSet()
        changes.createEntity(supplier4)
        changes.updateEntity(supplier3)
        changes.deleteEntity(supplier2)
        changes.createEntity(product2)
        changes.createLink(from: product2, property: Product.supplier, to: supplier4)
        changes.updateLink(from: product2, property: Product.supplier, to: supplier3)
        changes.deleteLink(from: product2, property: Product.supplier, to: supplier3)
        let query = DataQuery().from(NorthwindServiceMetadata.EntitySets.suppliers)
        batch.addChanges(changes)
        batch.addQuery(query)
        try service.processBatch(batch)
        let suppliers = try Supplier.array(from: batch.queryResult(for: query)
            .entityList())
        try Example.show("There are now ", Example.formatInt(suppliers.count), " suppliers.")
    }
    

    Example using dynamic API

    open func processBatchExample() throws -> Void {
        let service = self.service
        let suppliersEntitySet = service.entitySet(withName: "Suppliers")
        let productsEntitySet = service.entitySet(withName: "Products")
        let supplierEntityType = suppliersEntitySet.entityType
        let companyNameProperty = supplierEntityType.property(withName: "CompanyName")
        let productEntityType = productsEntitySet.entityType
        let productNameProperty = productEntityType.property(withName: "ProductName")
        let supplierProperty = productEntityType.property(withName: "Supplier")
        let supplier1 = try service.executeQuery(DataQuery().from(suppliersEntitySet)
            .top(1))
            .requiredEntity()
        let supplier2 = supplier1.copyEntity()
        let supplier3 = supplier1.copyEntity()
        let supplier4 = supplier1.copyEntity()
        companyNameProperty.setStringValue(in: supplier2, to: "Alpha Inc.")
        companyNameProperty.setStringValue(in: supplier3, to: "Beta Inc.")
        try service.createEntity(supplier2)
        try service.createEntity(supplier3)
        companyNameProperty.setStringValue(in: supplier3, to: "Gamma Inc.")
        let product1 = try service.executeQuery(DataQuery().from(productsEntitySet)
            .top(1))
            .requiredEntity()
        let product2 = product1.copyEntity()
        productNameProperty.setStringValue(in: product2, to: "Delta Cake")
        let batch = RequestBatch()
        let changes = ChangeSet()
        changes.createEntity(supplier4)
        changes.updateEntity(supplier3)
        changes.deleteEntity(supplier2)
        changes.createEntity(product2)
        changes.createLink(from: product2, property: supplierProperty, to: supplier4)
        let query = DataQuery().from(suppliersEntitySet)
        batch.addChanges(changes)
        batch.addQuery(query)
        try service.processBatch(batch)
        let suppliers = try batch.queryResult(for: query).entityList()
        try Example.show("There are now ", Example.formatInt(suppliers.length), " suppliers.")
    }
    

    Declaration

    Swift

    open func processBatch(_ batch: RequestBatch, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    batch

    The request batch.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • The data service provider.

    Declaration

    Swift

    open var provider: DataServiceProvider { get }
  • (Asynchronous) Reload latest metadata from the backend server. If the metadata was previously loaded (or was obtained from generated proxy classes), then a compatibility check is performed. If the latest metadata is not compatible with the previous metadata, CsdlException will be thrown. If the latest metadata is compatible with the previous metadata, the latest metadata will be applied. It is generally recommended to use this function during application startup to check if the server’s metadata has been updated since the client application was constructed. If an application wishes to use the data service for actions or updates, while refreshing the metadata in another thread, the code using the data service for actions or updates should perform those operations while holding a read lock on the metadataLock. Execution of functions or queries will automatically obtain a read lock on metadataLock.

    Compatible metadata changes include:

    • Adding structural/navigation properties to complex/entity types.
    • Adding new types (enumeration, simple, complex, entity).
    • Adding new entity sets or singletons.
    • Adding new actions or functions.
    • Adding an action parameter that is nullable to the end of the parameter list.

    Other additions, changes, and removals are considered incompatible by default, including:

    • Adding members to an enumeration type.
    • Changing the base type for any type.
    • Changing the value of an enumeration member.
    • Changing the type (or nullability) of any structural/navigation property.
    • Changing the type (or nullability) of any action/function parameter or result.
    • Removing the definition of a model element.
    • Removing members from an enumeration type.
    • Removing structural/navigation properties from a complex/entity type.

    Addition of enumeration members can be pre-approved by a caller using the dynamic API before calling refreshMetadata (see CsdlDocument.hasOpenEnumerations). If an application uses generated proxy classes, then generating them with the “-open:enumerations” option will automate the necessary pre-approval. The hasOpenEnumerations flag should only be explicitly set when using the dynamic API. Explicitly setting the hasOpenEnumerations flag when using generated proxy classes (generated without the “-open:enumerations” option) could result in runtime exceptions.

    Changes to model elements can be pre-approved by a caller using the dynamic API before calling refreshMetadata (see CsdlDocument.canChangeAnything). Applications using generated proxy classes should not pre-approve such changes, as they are likely to result in application instability. For example, if a property’s data type is changed, it could result in runtime exceptions since proxy class properties have a pre-determined type that is embedded into the application’s compiled code.

    Removal of model elements can be pre-approved by the caller before calling refreshMetadata (see CsdlDocument.canRemoveAnything), or preferably by setting the canBeRemoved flag on model elements that the application is prepared for the removal of. Application developers should take care not to pre-approve the removal of model elements unless the application is coded to check at runtime for the possible removal of those elements. The allowance for removals is intended to support “newer” versions of client applications communicating with “older” service implementations but in the general case may require the application to have some embedded knowledge of the changes that were made to the service metadata between the older and newer service implementations. If a newer client application makes unconditional use of a model element that did not exist in an older service implementation, then the non-existence of that model element after calling refreshMetadata could result in runtime exceptions.

    If refreshMetadata succeeds, then any added model elements will have isExtension == true, and any removed model elements will have isRemoved == true. Changed model elements will not be distinguishable.

    Declaration

    Swift

    open func refreshMetadata() async throws
  • (Asynchronous) If isClientRegistered would return false, create a new client registration and record its key (ClientID property of type GUID) in local file ~/ClientRegistration/<ServiceName>.json. Otherwise just load the previously locally-saved registration ID into the ServiceOptions.clientInstanceID. The server’s metadata is expected to include a ClientRegistrationSet entity set with entity type ClientRegistration, a key property named ClientID of type long (Edm.Int64), and a property named ClientGUID of type guid (Edm.Guid). If a new registration is successfully created, ServiceOptions.clientInstanceID is set, and will subsequently be used to populate the Client-Instance-ID HTTP header for all OData calls. The purpose of creating such a client registration is to enable the server to associate various resources with the current instance of the current client application. A “current instance” can survive multiple restarts of the client application so long as the same Client-Instance-ID header value is provided for each OData call to the remote service. This is particularly useful for offline applications which rely on server-side OData change tracking implementations that store per-client server-side state to facilitate change tracking.

    Declaration

    Swift

    open func registerClient(_ client: EntityValue? = nil) async throws

    Parameters

    client

    Instance of ClientRegistration entity type. If omitted, a default instance will be created.

  • (Asynchronous) Create (if EntityValue.isNew) or update (if existing) an entity in the target system.

    Declaration

    Swift

    open func saveEntity(_ entity: EntityValue, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    entity

    Entity to be created or updated.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • Lookup a singleton by name. Panic if the singleton does not exist. Note: OData singleton entities are represented by EntitySet objects where EntitySet.isSingleton is true.

    See also

    metadata.singletons, for looking up singletons that might not exist.

    Declaration

    Swift

    open func singleton(withName name: String) -> EntitySet

    Parameters

    name

    Name of the singleton to be returned.

    Return Value

    The requested singleton.

  • (Asynchronous) Unload service metadata provider (if previously loaded).

    See also

    metadata, hasMetadata.

    Declaration

    Swift

    open func unloadMetadata() async throws
  • (Asynchronous) Forget any client registration previously established by registerClient. Also attempts to make a call to the server to delete the associated entity, if the deleteFromServer parameter is true.

    Declaration

    Swift

    open func unregisterClient(deleteFromServer: Bool = false) async throws

    Parameters

    deleteFromServer

    Specify a value of true to request the server to also delete the corresponding entity.

  • (Asynchronous) Update an entity in the target system.

    See also

    EntityValue.withDeepUpdate, Update Related Entities When Updating an Entity.

    Example using proxy classes

    open func updateEntityExample() throws -> Void {
        let service = self.service
        let query = DataQuery().top(1).filter(Customer.contactName.equal("Jean-Luc Picard"))
        let customer = try service.fetchCustomer(matching: query)
        customer.contactName = "Beverly Crusher"
        try service.updateEntity(customer)
    }
    

    Example with proxy classes

    open func deepUpdateExample() throws -> Void {
        let service = self.service
        let query = DataQuery().top(1).expand(Customer.orders)
            .filter(Customer.contactName.equal("Beverly Crusher"))
        let customer = try service.fetchCustomer(matching: query)
        let orders = customer.orders
        let firstOrder = orders[0]
        let nextOrder = orders[1]
        let newOrder = Order()
        newOrder.orderDate = GlobalDateTime.now()
        customer.unbindEntity(firstOrder, from: Customer.orders)
        nextOrder.requiredDate = GlobalDateTime.now().plusDays(7)
        customer.bindEntity(newOrder, to: Customer.orders)
        customer.deepUpdateDelta = true
        try service.updateEntity(customer.withDeepUpdate())
    }
    

    Example using proxy classes

    open func updateReplaceExample() throws -> Void {
        let service = self.service
        let query = DataQuery().top(1).filter(Customer.contactName.equal("Beverly Crusher"))
        let customer = try service.fetchCustomer(matching: query)
        customer.contactName = "William Riker"
        let options = RequestOptions().update(UpdateMode.replace)
        try service.updateEntity(customer, headers: nil, options: options)
    }
    

    Example using dynamic API

    open func updateEntityExample() throws -> Void {
        let service = self.service
        let customersEntitySet = service.entitySet(withName: "Customers")
        let customerEntityType = customersEntitySet.entityType
        let contactNameProperty = customerEntityType.property(withName: "ContactName")
        let query = DataQuery().top(1).from(customersEntitySet)
            .filter(contactNameProperty.equal("Jean-Luc Picard"))
        let customer = try service.executeQuery(query).requiredEntity()
        contactNameProperty.setStringValue(in: customer, to: "Beverly Crusher")
        try service.updateEntity(customer)
    }
    

    Declaration

    Swift

    open func updateEntity(_ entity: EntityValue, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    entity

    Entity to be updated.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Update a link from a source entity to a target entity.

    Example using proxy classes

    open func updateLinkExample() throws -> Void {
        let service = self.service
        let product = try service.fetchProduct(matching: DataQuery().top(1))
        let category = try service.fetchCategory(matching: DataQuery().skip(2).top(1))
        try service.updateLink(from: product, property: Product.category,
            to: category)
    }
    

    Example using dynamic API

    open func updateLinkExample() throws -> Void {
        let service = self.service
        let productsEntitySet = service.entitySet(withName: "Products")
        let categoriesEntitySet = service.entitySet(withName: "Categories")
        let productEntityType = productsEntitySet.entityType
        let categoryProperty = productEntityType.property(withName: "Category")
        let product = try service.executeQuery(DataQuery().from(productsEntitySet)
            .top(1))
            .requiredEntity()
        let category = try service.executeQuery(DataQuery().from(categoriesEntitySet)
            .skip(2).top(1))
            .requiredEntity()
        try service.updateLink(from: product, property: categoryProperty,
            to: category)
    }
    

    Declaration

    Swift

    open func updateLink(from: EntityValue, property: Property, to: EntityValue, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    from

    Source entity for the link to be updated.

    property

    Source navigation property for the link to be updated. This must be a one-to-one navigation property.

    to

    Target entity for the link to be updated.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Upload content for a media entity to the target system. Caution: Having too many threads simultaneously uploading streams may result in out-of-memory conditions on memory-constrained devices. Note: this function cannot be used to create a media entity. See DataService.createMedia.

    Example using proxy classes

    open func uploadMediaExample() throws -> Void {
        let service = self.service
        let query = DataQuery().filter(Image.label.equal("Smiley")).top(1)
        let image = try service.fetchImage(matching: query)
        let content = ByteStream.fromBinary(data: Base16Binary.convert("3B2D29"))
        content.mediaType = "text/plain"
        try service.uploadMedia(entity: image, content: content)
    }
    

    Example using dynamic API

    open func uploadMediaExample() throws -> Void {
        let service = self.service
        let imagesEntitySet = service.entitySet(withName: "Images")
        let imageEntityType = imagesEntitySet.entityType
        let labelProperty = imageEntityType.property(withName: "label")
        let query = DataQuery().from(imagesEntitySet).filter(labelProperty.equal("Smiley"))
            .top(1)
        let image = try service.executeQuery(query).requiredEntity()
        let content = ByteStream.fromBinary(data: Base16Binary.convert("3B2D29"))
        content.mediaType = "text/plain"
        try service.uploadMedia(entity: image, content: content)
    }
    

    Declaration

    Swift

    open func uploadMedia(entity: EntityValue, content: StreamBase, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    entity

    Entity whose content is to be uploaded.

    content

    Upload stream content. Will be closed before this function returns.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • (Asynchronous) Upload content for a stream property to the target system. Caution: Having too many threads simultaneously uploading streams may result in out-of-memory conditions on memory-constrained devices.

    See also

    Property.getStreamLink.

    Example using proxy classes

    open func uploadStreamExample() throws -> Void {
        let service = self.service
        let video = Video()
        video.label = "Happy"
        try service.createEntity(video)
        let contentETagAfterCreate = video.content.entityTag
        assert(contentETagAfterCreate == nil)
        let content = ByteStream.fromBinary(data: Base16Binary.convert("68617070792D7374756666"))
        content.mediaType = "text/plain"
        try service.uploadStream(entity: video, link: video.content,
            content: content)
        try service.loadEntity(video)
        let contentETagAfterUpload = video.content.entityTag
        assert(contentETagAfterUpload != nil)
        video.label = "Happier"
        try service.updateEntity(video)
        let contentETagAfterUpdate = video.content.entityTag
        assert(OptionalString.equal(contentETagAfterUpdate, contentETagAfterUpload))
    }
    

    Example using dynamic API

    open func uploadStreamExample() throws -> Void {
        let service = self.service
        let videosEntitySet = service.entitySet(withName: "Videos")
        let videoEntityType = videosEntitySet.entityType
        let labelProperty = videoEntityType.property(withName: "label")
        let contentProperty = videoEntityType.property(withName: "content")
        let video = EntityValue.ofType(videoEntityType)
        labelProperty.setStringValue(in: video, to: "Happy")
        let content = ByteStream.fromBinary(data: Base16Binary.convert("2E2E2E"))
        content.mediaType = "text/plain"
        try service.createEntity(video)
        let link = contentProperty.streamLink(from: video)
        let contentETagAfterCreate = link.entityTag
        assert(contentETagAfterCreate == nil)
        try service.uploadStream(entity: video, link: link, content: content)
        try service.loadEntity(video)
        let contentETagAfterUpload = link.entityTag
        assert(contentETagAfterUpload != nil)
        labelProperty.setStringValue(in: video, to: "Happier")
        try service.updateEntity(video)
        let contentETagAfterUpdate = link.entityTag
        assert(OptionalString.equal(contentETagAfterUpdate, contentETagAfterUpload))
    }
    

    Declaration

    Swift

    open func uploadStream(entity: EntityValue, link: StreamLink, content: StreamBase, headers: HTTPHeaders? = nil, options: RequestOptions? = nil) async throws

    Parameters

    entity

    Entity containing the stream property whose content is to be uploaded.

    link

    Stream link for the stream to be uploaded.

    content

    Upload stream content. Will be closed before this function returns.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.