DataService

open class DataService<Provider> where Provider : DataServiceProvider

Encapsulates an OData data service. The generic type parameter indicates the type of data service provider.

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)
    // Alternate using generic DataService - allows provider-specific functions
    // and properties (e.g. traceRequests) to be accessed via `service` object.
    // let service: NorthwindService<OnlineODataProvider> = new 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 = AnyDataService(provider: provider)
    // Alternate using generic DataService - allows provider-specific functions
    // and properties (e.g. traceRequests) to be accessed via `service` object.
    // let service: DataService<OnlineODataProvider> = new DataService(provider: provider)
    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)
}
  • Obsolete: use backgroundQueueForFunction or backgroundQueueForAction.

    • OperationQueue instance to be used by this data service. By default the number of queued operations is maximized in 10.

    Declaration

    Swift

    @available(swift, deprecated: 4.2, message: "it is renamed to backgroundQueueForFunction, where the number of queued operations are maximized in 10 by default. If serial execution is sufficient then use the backgroundQueueForAction instead.")
    public var backgroundQueue: OperationQueue { get set }
  • OperationQueue instance 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 backgroundQueueForAction: OperationQueue { get set }
  • OperationQueue instance 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 backgroundQueueForFunction: OperationQueue { get set }
  • OperationQueue to be used for completion handlers.

    Declaration

    Swift

    public var completionQueue: OperationQueue { get set }
  • Obsolete: use addBackgroundOperationForFunction(operation:) or addBackgroundOperationForAction(operation:).

    • Execute operation on a parallel background queue.

    Declaration

    Swift

    @available(swift, deprecated: 4.2, message: "it is renamed to addBackgroundOperationForFunction(operation:﹚, which supports parallel execution of operations (on 10 threads by default﹚. If serial execution is sufficient then use the addBackgroundOperationForAction(operation:﹚ instead.")
    public func addBackgroundOperation(_ operation: @escaping () -> Void)
  • Execute operation on a background queue serially. (By default the maximum number of queued operations that can execute at the same time is 1.)

    Declaration

    Swift

    public func addBackgroundOperationForAction(_ operation: @escaping () -> Void)
  • Execute operation on a background queue parallel. (By default the maximum number of queued operations that can execute at the same time is 10.)

    Declaration

    Swift

    public func addBackgroundOperationForFunction(_ operation: @escaping () -> Void)
  • Async version of pingServer.

    Declaration

    Swift

    open func pingServer(completionHandler: @escaping (Error?) -> Void, headers : HTTPHeaders = HTTPHeaders.empty, options : RequestOptions = RequestOptions.none) -> Void
  • Async version of loadMetadata.

    Declaration

    Swift

    open func loadMetadata(completionHandler: @escaping (Error?) -> Void, headers : HTTPHeaders = HTTPHeaders.empty, options : RequestOptions = RequestOptions.none) -> Void
  • Async version of unloadMetadata.

    Declaration

    Swift

    open func unloadMetadata(completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of executeMethod.

    Declaration

    Swift

    open func executeMethod(_ method: DataMethod, parameters: ParameterList = ParameterList.empty, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (DataValue?, Error?) -> Void) -> Void
  • Async version of executeQuery.

    Declaration

    Swift

    open func executeQuery(_ query: DataQuery, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (QueryResult?, Error?) -> Void) -> Void
  • Async version of loadProperty.

    Declaration

    Swift

    open func loadProperty(_ property: Property, into: EntityValue, query: DataQuery? = nil, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of ‘loadEntity’.

    Declaration

    Swift

    open func loadEntity(_ entity: EntityValue, query: DataQuery? = nil, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of saveEntity.

    Declaration

    Swift

    open func saveEntity(_ entity: EntityValue, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of createEntity.

    Declaration

    Swift

    open func createEntity(_ entity: EntityValue, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of createRelatedEntity.

    Declaration

    Swift

    open func createRelatedEntity(_ entity: EntityValue, in parent: EntityValue, property: Property, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of updateEntity.

    Declaration

    Swift

    open func updateEntity(_ entity: EntityValue, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of deleteEntity.

    Declaration

    Swift

    open func deleteEntity(_ entity: EntityValue, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of deleteByQuery.

    Declaration

    Swift

    open func deleteByQuery(_ query: DataQuery, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of createLink.

    Declaration

    Swift

    open func createLink(from: EntityValue, property: Property, to: EntityValue, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of updateLink.

    Declaration

    Swift

    open func updateLink(from: EntityValue, property: Property, to: EntityValue, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of deleteLink.

    Declaration

    Swift

    open func deleteLink(from: EntityValue, property: Property, to: EntityValue = EntityValue.ofType(EntityType.undefined), headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of createMedia.

    Declaration

    Swift

    open func createMedia(entity: EntityValue, content: StreamBase, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of uploadMedia.

    Declaration

    Swift

    open func uploadMedia(entity: EntityValue, content: StreamBase, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of uploadStream.

    Declaration

    Swift

    open func uploadStream(entity: EntityValue, link: StreamLink, content: StreamBase, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of deleteStream.

    Declaration

    Swift

    open func deleteStream(entity: EntityValue, link: StreamLink, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of downloadMedia.

    Declaration

    Swift

    open func downloadMedia(entity: EntityValue, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Data?, Error?) -> Void) -> Void
  • Async version of downloadStream.

    Declaration

    Swift

    open func downloadStream(entity: EntityValue, link: StreamLink, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Data?, Error?) -> Void) -> Void
  • Async version of applyChanges.

    Declaration

    Swift

    open func applyChanges(_ changes: ChangeSet, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Async version of processBatch.

    Declaration

    Swift

    open func processBatch(_ batch: RequestBatch, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none, completionHandler: @escaping (Error?) -> Void) -> Void
  • Undocumented

    Declaration

    Swift

    public init(provider: Provider)
  • The provider for this data service (e.g. OnlineODataProvider, OfflineODataProvider).

    Declaration

    Swift

    public var provider: Provider { get }
  • 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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    Parameters

    changes

    The change set.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

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

    See also

    EntityValue.ofType, EntityValue.inSet.

    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 createEntityInSetExample() throws -> Void {
        let service = self.service
        let customer = Customer()
        customer.companyName = "Voyager Inc."
        customer.contactName = "Kathryn Janeway"
        try service.createEntity(customer.inSet(NorthwindServiceMetadata.EntitySets.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)
    }
    

    Example using dynamic API

    open func createEntityInSetExample() 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: "Voyager Inc.")
        contactNameProperty.setStringValue(in: customer, to: "Kathryn Janeway")
        try service.createEntity(customer.inSet(customersEntitySet))
    }
    

    Declaration

    Swift

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

    Parameters

    entity

    Entity to be created.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • 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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    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.

  • 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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    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.

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

    See also

    ChangeSet.createRelatedEntity.

    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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    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.

  • 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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    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). If the data method does not exist it indicates a fundamental implementation problem, therefore a non-catchable FatalException will be thrown, and the app intentionally crashes. The reason behind this drastic behaviour is to avoid mismatch between server and client. It is still possible to avoid the FatalException by looking up data methods before calling this function like in the following code snippet:

    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 {
        }
    }
    

    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 data method, which must exist.

  • Execute query to delete data from the target system.

    Declaration

    Swift

    open func deleteByQuery(_ query: DataQuery, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    Parameters

    query

    Data query specifying the information to be deleted.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • 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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    Parameters

    entity

    Entity to be deleted.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • Delete a link from a source entity to a target entity.

    Example using proxy classes

    open func deleteLinkExample1() throws -> Void {
        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 {
        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 {
        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 {
        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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    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.

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

    Declaration

    Swift

    open func deleteStream(entity: EntityValue, link: StreamLink, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    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.

  • 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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> ByteStream

    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.

  • 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("2E2E2E")))
        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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> ByteStream

    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 (or singleton entity) by name. If the entity set does not exist it indicates a fundamental implementation problem, therefore a non-catchable FatalException will be thrown, and the app intentionally crashes. The reason behind this drastic behaviour is to avoid mismatch between server and client. It is still possible to avoid the FatalException by looking up entity sets before calling this method like in the following code snippet: Note that OData singleton entities are represented by entity sets where EntitySet.isSingleton is true.

    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 {
        }
    }
    

    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 entity set, which must exist.

  • 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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) 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.

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

    Declaration

    Swift

    open func executeQuery(_ query: DataQuery, headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) 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.

  • Has service metadata been loaded.

    See also

    loadMetadata.

    Declaration

    Swift

    open var hasMetadata: Bool { get }
  • 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) throws -> Void

    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.

  • Load service metadata (if not already loaded).

    See also

    metadata, hasMetadata.

    Declaration

    Swift

    open func loadMetadata(headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    Parameters

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • 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 customers = try service.fetchCustomers(matching: query)
        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)
    }
    

    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 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 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
    }
    

    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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    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.

  • Service metadata.

    See also

    loadMetadata.

    Declaration

    Swift

    open var metadata: CSDLDocument { get }
  • Service name.

    Declaration

    Swift

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

    Declaration

    Swift

    open func pingServer(headers: HTTPHeaders = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    Parameters

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • 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)
        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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    Parameters

    batch

    The request batch.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • 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.

    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.

    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() throws
  • Create (if EntityValue.isNew) or update (if existing) an entity in the target system.

    Declaration

    Swift

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

    Parameters

    entity

    Entity to be created or updated.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • Unload service metadata (if previously loaded).

    See also

    metadata, hasMetadata.

    Declaration

    Swift

    open func unloadMetadata() throws
  • Update an entity in the target system.

    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 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)
    }
    

    Example using proxy classes

    open func updateEntityWithReplaceExample() 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()
        options.updateMode = UpdateMode.replace
        try service.updateEntity(customer, headers: HTTPHeaders.empty,
            options: options)
    }
    

    Example using dynamic API

    open func updateEntityWithReplaceExample() 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("Beverly Crusher"))
        let customer = try service.executeQuery(query).requiredEntity()
        contactNameProperty.setStringValue(in: customer, to: "William Riker")
        let options = RequestOptions()
        options.updateMode = UpdateMode.replace
        try service.updateEntity(customer, headers: HTTPHeaders.empty,
            options: options)
    }
    

    Declaration

    Swift

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

    Parameters

    entity

    Entity to be updated.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • 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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    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.

  • 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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    Parameters

    content

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

    entity

    Entity whose content is to be uploaded.

    headers

    Optional request-specific headers.

    options

    Optional request-specific options.

  • 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"
        let content = ByteStream.fromBinary(data: Base16Binary.convert("2E2E2E"))
        content.mediaType = "text/plain"
        try service.createEntity(video)
        let contentETagAfterCreate = video.content.entityTag
        assert(contentETagAfterCreate == nil)
        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 = HTTPHeaders.empty, options: RequestOptions = RequestOptions.none) throws -> Void

    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.

  • HTTP cookies that were returned by previous online requests.

    Declaration

    Swift

    public var httpCookies: HTTPCookies { get }
  • HTTP headers which should be sent in future online requests.

    Declaration

    Swift

    public var httpHeaders: HTTPHeaders { get }
  • Options for network communication, which for OData uses HTTP or HTTPS.

    Declaration

    Swift

    public var networkOptions: NetworkOptions { get }
  • Should traceWithData show pretty-printed JSON/XML content? Defaults to false.

    Declaration

    Swift

    public var prettyTracing: Bool { get set }
  • Options for this data service, both client-side and server-side.

    Declaration

    Swift

    public var serviceOptions: ServiceOptions { get }
  • Should all requests for this data service be traced? Defaults to false.

    Declaration

    Swift

    public var traceRequests: Bool { get set }
  • If traceRequests is also true, should all requests for this data service be traced with data? Defaults to false. Note that care must be taken when enabling tracing with data, as the resulting log files may contain sensitive information. On the other hand, tracing with data may sometimes be invaluable for troubleshooting purposes.

    Declaration

    Swift

    public var traceWithData: Bool { get set }
  • If this data service requires a security token, then acquire it now. SeeAlso: ServiceOptions.requiresToken.

    Declaration

    Swift

    public func acquireToken() throws