Skip to main content
Version: iOS SDK v1.3.0

Playlists

Playlists are reactive lists of videos that can be played and observed efficiently, with built-in support for pagination, caching and preloading. This is the recommended way of fetching and playing videos through our player.

As with querying videos, the start point is the video store (VideoKit.videos()). Also, to fetch playlist you will need a valid session or the call will return an error.

Inspecting playlists

Every playlist holds a list of videos in memory. At first, this list represent the first "page" of results that were retrieved from server. These videos can be retrieved with the indexed subscript playlist[index]:

let playlist: Playlist = ...

// number of available videos
let count: Int = playlist.count

// number of available videos in the backend
let totalCount: Int = playlist.totalCount

let firstVideo: Video? = playlist[0]

Pagination

If a video is accessed with an index bigger than playlist.count, it will return a nil value. If you need more videos than those available at the moment, you can request a new batch of results by using Playlist.loadMore():

playlist.loadMore { err in 
// handle error
}

Async users can use loadMore() async too.

Note that if Playlist.loadMoreOnAccess is true (default), the playlist will automatically load new pages as you consume the playlist with the subscripts (e.g. playlist[0]), checking if you are getting close enough to the last available video. This makes it easy to show a list of videos without worrying about dynamic contents.

In case you want to access a video without triggering the "load more" logic, you have two choices:

  • set playlist.loadMoreOnAccess to false
  • access playlist.videos directly

Observing playlists

At any time, you can use Playlist.videos and Playlist.videosPublisher to retreive the current list of videos and, in case of the publisher, to observe changes in it.

let playlist = ...
let videos: [Video] = playlist.videos // won't trigger pagination
let publisher = playlist.videosPublisher // combine publisher

In addition, updates can be received by registering a PlaylistObserver.

public class CustomObserver : PlaylistObserver {
func videosChanged(old: [Video], new: [Video]) {
// Handle change in videos
}
}

Obtain playlists

As with other APIs, we use objects to define the query parameters. All such objects for playlists extend the PlaylistSpec interface. We expose several types of specs, each one with different configuration options.

Once you have the spec, just call getPlaylist:

let videos: VideoStore = VideoKit.videos()
let playlist = videos.getPlaylist(spec)

A similar function called loadPlaylist will act just like getPlaylist, but will also ensure that the first batch of videos is loaded from network (or local database) before returning a result.

Loading is of course asynchronous. Swift concurrency projects can use try await loadPlaylist(spec) as well.

By user

You can filter by user using UserPlaylistSpec:

var spec = UserPlaylistSpec(identity: userIdentity)
spec.order = SortOrder.desc
spec.pageSize = 50

By metadata and tags

You can filter by metadata and tags using FilteredPlaylistSpec:

var spec = FilteredPlaylistSpec(tags: tags, metadata: metadata)
spec.title = "Target title"
spec.safeContent = true
spec.order = SortOrder.desc
spec.pageSize = 50

Custom playlists

You can create a playlist with custom videos using CustomPlaylistSpec:

let spec = CustomPlaylistSpec(name: "OwnVideos", ids: ["videoId1", "videoId2"])

This is a special type of playlist which can be controlled by the user. As you can imagine, the playlist is mutable. You can use add, remove, set functions to mutate the set of desired ids and missing videos will be loaded accordingly.

var playlist: CustomPlaylist = ...

// add already loaded Video object
playlist.add(video, at: 0)

// add video by ID. This is asynchronous
playlist.add(id: "videoId", at: 1) { err in
// handle error
}

Custom playlists have no built-in concept of pagination, so by default loadMore() does nothing. You can, however, pass a custom loader to playlist.loader: in this case, the playlist will trigger the loader whenever it thinks that a new page is needed, using the same triggering logic that is used by other playlists.