Skip to Content
Technical Articles
Author's profile photo Daniel Van Leeuwen

Getting Started with the SAP Cloud Platform SDK for iOS – Part 4 – Online OData

Previous (Logging)   Home   Next (Offline OData)

OData stands for Open Data Protocol and is a common way of accessing data from an SAP or other backend using RESTful APIs. The SAP Cloud Platform SDK for iOS can be used to generate proxy classes from a backend that provides an OData interface.

The following are some additional sources of documentation on OData and generating and using proxy classes to access OData.
OData in the Getting Started with Kapsel
SAPOData Reference
Developing Online Applications
Online OData with Native iOS Mobile Interactive Tutorial

The following instructions demonstrate how to create proxy classes that represent the entity types of the sample SAP Cloud Platform Mobile Services sample OData service such as a Product or SalesOrder. These classes will then be used to return data to the application.

  1. Download the metadata document for the service to the project folder and name it metadata.xml. The URL is the OData service URL + /$metadata.
    https://hcpms-XXXXXXtrial.hanatrial.ondemand.com/SampleServices/ESPM.svc/$metadata

    Note that the XML content is not shown in Safari unless the preference Show Develop menu in menu bar is enabled under Advanced.

  2. Create a folder in the project where the proxy OData classes will be generated such as GettingStarted/GettingStarted/ProxyClasses.
    mkdir ~/Documents/iOSSDKProjects/GettingStarted/GettingStarted/ProxyClasses/
  3. Generate the proxy OData classes by executing the following command in a terminal. Note the tools can be installed via the Install Tools menu of the Assistant.
    sapcpsdk-proxygenerator -m ~/Documents/iOSSDKProjects/GettingStarted/metadata.xml -d ~/Documents/iOSSDKProjects/GettingStarted/GettingStarted/ProxyClasses
  4. Add the proxy classes to the Xcode project by dragging and dropping the generated ProxyClasses folder into the project.

  5. Add the following import to the top of ViewController.
    import SAPOData
    
  6. Add the following method which will make a request to the OData service to return products.
    // MARK: - OData queries
    private func getProducts(_ serviceRoot: URL, _ urlSession: SAPURLSession) {
    	let oDataProvider = OnlineODataProvider(serviceName: "ESPMContainer", serviceRoot: serviceRoot, sapURLSession: urlSession)
    	let espmContainer = ESPMContainer(provider: oDataProvider)
    	espmContainer.fetchProducts() { products, error in
    		guard let products = products else {
    			print("Error fetching products:  \(error!.localizedDescription)")
    			return
    		}
    		print("Got \(products.count) products and the first product name is \(products[0].name!)")
    	}
    }
    
  7. At the end of the buttonPressed method call the method.
    getProducts(serviceURL, myContext.sapURLSession)

    The result is displayed in the All Output area of Xcode.

  8. Below is a slightly different example that makes use of a query to sort the results and only bring back the product names that are in the Notebooks category. Also note that it has enabled debug output and tracing for the OData component.
    private func getProductNamesOnly(_ serviceRoot: URL, _ urlSession: SAPURLSession) {
    	let oDataProvider = OnlineODataProvider(serviceName: "ESPMContainer", serviceRoot: serviceRoot, sapURLSession: urlSession)
    	Logger.shared(named: "SAP.OData").logLevel = LogLevel.debug
    	oDataProvider.traceRequests = true
    	oDataProvider.traceWithData = true
    	oDataProvider.prettyTracing = true
    	let espmContainer = ESPMContainer(provider: oDataProvider)
    	let query = DataQuery()
    					.select(Product.name)
    					.where(Product.category.equal("Notebooks"))
    					.orderBy(Product.name)
    	espmContainer.fetchProducts(matching: query) { products, error in
    		guard let products = products else {
    			self.logger.error("Error fetching products:  \(error!.localizedDescription)")
    			return
    		}
    		print("Got \(products.count) products names only and the first product name is \(products[0].name!)")
    	}
    }
    
  9. The following is a subset of the debug/trace output from the above query.
  10. The previously generated project using the Assistant contains a more complete example that demonstrates create and update operations.

Previous (Logging)   Home   Next (Offline OData)

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Mike Doyle
      Mike Doyle

      Hi Dan, we can use the assistant to create an app for us, including the proxy classes but your example is a good way to get a better understanding of what the assistant is doing.  Is your approach here the only way to build an app that uses multiple OData services?  It seems that the assistant is tied to referencing one service only.

       

      Author's profile photo Daniel Van Leeuwen
      Daniel Van Leeuwen
      Blog Post Author

      In the assistant, I believe you can specify more than one destination.  The generated app will have the proxy classes generated for both destinations.

      In the example above, I needed to specify a prefix (click on the settings icon beside the + and - icons as both of my services had an entity name Product.

       

      The assistant will only generate UI based off of one destination.

       

      Hope that helps,

      Dan

      Author's profile photo Vikas Mule
      Vikas Mule

      Hello Dan,

      I followed this article and created proxy classes and written Code to Call OData Services using proxy classes and getting connection lost error.

       

      few things i need to know:

      1. Need to know which the serviceRoot URl to use.
      2. what should be the urlSession configuration.

      Thanks