Skip to content

Media Resources

You can download media resources (also known as media streams) of media entities during store open and download.

This is done by setting the automaticallyRetrieveStream parameter to true when constructing the OfflineODataDefiningQuery. There are three types of OfflineODataDefiningQuery:

  • Type 1: A defining query that identifies one or more entities where the automaticallyRetrievesStreams parameter is set to false. In this case, even if the defining query identifies media entities, the media streams will not be downloaded.

  • Type 2: A defining query that identifies one or more entities, some of which may be media entities, and the automaticallyRetrievesStreams parameter is set to true. In this case, the media streams will be downloaded as well for media entities.

  • Type 3: A defining query that identifies a single media entity and the automaticallyRetrieveStreams parameter is set to true. The URL specified in this case MUST be the read link of the media entity, not the read link of the media stream. For example, if the media entity's read link is Documents(101) and the media stream's read link is Documents(101)/$value, the expected URL of the defining query is Documents(101).

You can add defining queries of type 1 and 2 before or after the offline store is opened. Essentially, they can be added at any time. However, you can only remove defining queries of these types before the store is initially opened. After the first open, removal is not allowed.

You can add defining queries of type 3 before or after the offline store has been opened. Defining queries of type 3 can be removed after the offline store has been opened to stop future download of the media streams. See the sample below for constructing various types of defining queries.

/// Type 1 defining query with media entity set Photos.
/// Set automaticallyRetrieveStream to false to skip downloading media
/// streams for photos when opening the offline store.
/// Adding such defining queries can be done before or after initial open of the offline store
try offlineODataProvider.add(definingQuery: OfflineODataDefiningQuery(name: "Photos", query: "/Photos", automaticallyRetrievesStreams: false))

/// Open the offline store

/// Type 3 defining query to download media streams of specific photos
let photo1dq = OfflineODataDefiningQuery(name: "Photo1", query: "/Photos(1)", automaticallyRetrievesStreams: true)
let photo2dq = OfflineODataDefiningQuery(name: "Photo2", query: "/Photos(2)", automaticallyRetrievesStreams: true)
try offlineODataProvider.add(definingQuery: photo1dq)
try offlineODataProvider.add(definingQuery: photo2dq)

Then, you can perform download to get the media streams.

/// Perform download using the subset feature to only download the newly
/// added media stream defining queries [photo1dq, photo2dq], completionHandler: {(_ error: OfflineODataError?) *  Void in
    if let error = error {
        /// Handle the error
    } else {
        /// Download completed successfully.
        /// Notify application for appropriate action

When a media resource is no longer needed, you can remove it by removing the defining query:

try offlineODataProvider.remove(definingQuery: photo1dq)

The application can create new media streams, and then update them even if automaticallyRetrieveStream is false. You can also delete a media stream (by deleting the media entity) if automaticallyRetrieveStream is false. However, you cannot update the media stream of a media entity when the defining query has automaticallyRetrieveStream set to false since the media stream is not available in the offline store. In this case, you would have to perform an online request to update the media stream itself.


Defining queries added without opening offline store will not be persisted. If the application terminates, they will be lost.

Offline OData does not support stream property. Stream related methods such as uploadStream(), deleteStream() and downloadStream() will ensure that they operate on a media entity stream. The method deleteStream() does the same as the deleteEntity() method.

Last update: October 30, 2020