Shoppable Videos
Shoppable Videos enable your users to add products and services within the cart and checkout directly within the Vertical Feed without leaving the video-watching experience.
This walkthrough shows how to use Shoppable Videos in your app.
Set Up Product Delegate
This walkthrough shows you how to handle Shoppable content events in your app. Shoppable events provide insight into what is happening on the Storyly widget related to products.
Before you begin
You need to have the working Storyly integration as described in Initial SDK Setup
StorylyVerticalFeedView
notifies the application when an event occurs. You can register the delegate using the following code example and then override its functions to learn about specific events, which will be explained in the next sections.
// the class(indicated with self) extends StorylyVerticalFeedProductDelegate
self.StorylyVerticalFeedView.productDelegate = self // Override event functions
...
extension ViewController: StorylyVerticalFeedProductDelegate {
// Override event functions
}
To get notification about these basic events, you should override the following functions in StorylyVerticalFeedProductDelegate
.
verticalFeedUpdateCartEvent
This function will notify you about updates to the cart in a view
component.
STRCartItem
This class represents an individual item in the shopping cart. You can find the all properties of STRCartItem
here.
Info
You can get the
productId
,productGroupId
,price
,salesPrice
,currency
,desc
etc underchange.item
.
onSuccess
It represents a callback function that will be executed if the "update cart" operation is successful.
onSuccess?(STRCart((items: [STRCartItem],
totalPrice: Float,
oldTotalPrice: NSNumber?,
currency: String) ))
onFail
It represents a callback function that will be executed if the "update cart" operation fails.
onFail(STRCartEventResult("Insert Fail Message here"))
Usage of verticalFeedUpdateCartEvent
extension StorylyVerticalFeedViewController: StorylyVerticalFeedProductDelegate {
/*
* This function will notify you about updates the cart in a StorylyVerticalFeedView component
*
* verticalFeedView: StorylyVerticalFeedView widget in which the event is received
* event: event type which is received
* cart: Contains information about the items in the cart
* change: Represents the item being changed in the cart.
* onSuccess: It represents a callback function that will be executed if the "update cart" operation is successful
* onFail: It represents a callback function that will be executed if the "update cart" operation fails
*
*/
func verticalFeedUpdateCartEvent(view: StorylyVerticalFeedView,
event: VerticalFeedEvent,
cart: STRCart?,
change: STRCartItem?,
onSuccess: ((STRCart) -> Void)?,
onFail: ((STRCartEventResult) -> Void)?)
{
when (event){
verticalFeedEvent.VerticalFeedItemProductAdded -> {
print("Shopping VerticalFeedItemProductAdded")
//This event sent when a product is added.
}
verticalFeedEvent.VerticalFeedItemProductUpdated -> {
print("Shopping VerticalFeedItemProductUpdated")
//This event sent when a product is updated.
}
verticalFeedEvent.VerticalFeedItemProductRemoved -> {
print("Shopping VerticalFeedItemProductRemoved")
//This event sent when a product is removed.
}
}
print("Shoppable ShoppableEvent: \(event)")
print("Shoppable ShoppableCart: \(cart)")
print("Shoppable ShoppableChange: \(change)")
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(2_000), execute: {
onSuccess?(STRCart((items: [STRCartItem],
totalPrice: Float,
oldTotalPrice: NSNumber?,
currency: String) ))
})
onFail(STRCartEventResult("Insert Failed Message here"))
}
}
verticalFeedEvent
This function will notify you about all Vertical Feed related events so that you can make redirections accordingly. Also, you can send these events to your data platform to track user journeys on your end.
Usage of verticalFeedEvent
extension StorylyVerticalFeedViewController: StorylyVerticalFeedProductDelegate {
func verticalFeedEvent(_ view: StorylyVerticalFeedView,
event: VerticalFeedEvent,
product: STRProductItem?, extras: [String:String]) {
when (event){
verticalFeedEvent.VerticalFeedItemCheckoutButtonClicked -> {
print("Shopping VerticalFeedItemCheckoutButtonClicked")
}
verticalFeedEvent.VerticalFeedItemCartButtonClicked -> {
print("Shopping VerticalFeedItemCartButtonClicked")
}
verticalFeedEvent.VerticalFeedItemCartViewClicked -> {
print("Shopping VerticalFeedItemCartViewClicked")
}
verticalFeedEvent.VerticalFeedItemProductSelected -> {
print("Shopping VerticalFeedItemProductSelected")
}
}
}
}
VerticalFeedItemCheckoutButtonClicked Event
If isProductCartEnabled
is set to true, this event is sent when the "Go to Checkout" button is clicked.
VerticalFeedItemCartButtonClicked Event
This event is sent when the "Go to Cart" button is clicked from the success sheet.
VerticalFeedItemCartViewClicked Event
This event is sent when the cart icon on the content is clicked.
VerticalFeedItemProductSelected Event
This event is sent when the product is selected.
verticalFeedHydration
This function will notify you to get the products placed in Vertical Feed.
extension StorylyVerticalFeedViewController: StorylyVerticalFeedProductDelegate {
/**
* This function will notify you to get the products placed in the Vertical Feed.
*
* - Parameter view: StorylyVerticalFeedView widget in which the user interacted with a component
* - Parameter productIds: Data class that represents the product information
*/
func verticalFeedHydration(_ view: StorylyVerticalFeedView,
products: [STRProductInformation]) {
print("storylyHydration, products: \(products)")
}
}
Product Fallback for Hydration
There is a boolean parameter named setFallbackAvailability
which is used to determine whether the product data should be hydrated from the feed or not. By default, it is set to false, which means that product data will not be hydrated from the feed. However, when this parameter is set to true, product data will be hydrated from the feed.
You can set thesetFallbackAvailability
to true
if you want to enable product fallback from the feed.
self.StorylyVerticalFeedView.storylyVerticalFeedInit = StorylyVerticalFeedInit(
storylyId: storylyToken,
config: StorylyVerticalFeedConfig.Builder()
.setProductConfig(
config: StorylyProductConfig.Builder()
.setFallbackAvailability(isEnabled: Bool)
.build()
)
.build()
)
Supplemental Product Feed Handling
If you're using a multi-market Product Feed depending on language or country, to automate the Shoppable Story Group creation, you can define the version of the feed that you'd like to use per user on the client side.
That way without creating Story Groups per each region or language, you can serve the relevant content to each market with a single Story Group. To set the locale
, you need to use the IETF BCP 47 format as shown below:
self.StorylyVerticalFeedView.storylyVerticalFeedInit = StorylyVerticalFeedInit(
storylyId: storylyToken,
config: StorylyVerticalFeedConfig.Builder()
.setLocale(locale: String?)
)
.build()
)
Storyly Cart
There is a boolean parameter named setCartEnabled
which is added cart and cart icon to the top of the left of Shoppable videos. By default, it is set to false, but, when this parameter is set as true, the cart and the cart icon will be enabled on Shoppable videos.
self.StorylyVerticalFeedView.storylyVerticalFeedInit = StorylyVerticalFeedInit(
storylyId: storylyToken,
config: StorylyVerticalFeedConfig.Builder()
.setProductConfig(
StorylyProductConfig.Builder()
.setCartEnabled(isEnabled: Bool)
.build()
)
.build()
)
Update Storyly Cart
If you already have a cart in your application, you may sync your cart with Storyly cart. This function allows you to update your Storyly cart to sync with the already existing one.
self.StorylyVerticalFeedView.updateCart(cart: STRCart)
Product Hydration
This function allows you to hydrate your products while initializing the SDK to show products to end users in videos with the Shoppable feature.
With the verticalFeedHydration event, SDK will return the IDs of the products included in the content. With these IDs, you can use hydrateProduct
function to pass relevant products' data to the SDK.
self.StorylyVerticalFeedView.hydrateProducts(products: <STRProductItem>)
STRProductItem
represents products shown in videos.
STRProductVariant
represents variants of products shown in videos in terms of color, size, etc.
Here is an example of hydrateProducts
. We set the product data manually as an example, but you can set your data from your database as well.
let products = [
STRProductItem(
productId:"1",
productGroupId:"1",
title:"High-waist midi skirt",
url:"https://www.storyly.io/",
description:"High-waist midi skirt made of a viscose blend. Featuring a slit at the hem and invisible zip fastening.",
price: 25.99, salesPrice: 25.99,
currency:"USD",
imageUrls:["https://random-feed-generator.vercel.app/images/clothes/group-1/1-6D7868.jpg","https://random-feed-generator.vercel.app/images/clothes/group-1/2-6D7868.jpg","https://random-feed-generator.vercel.app/images/clothes/group-1/3-6D7868.jpg","https://random-feed-generator.vercel.app/images/clothes/group-1/4-6D7868.jpg"],
variants:[
STRProductVariant(name:"color",value:"#6D7868"),
STRProductVariant(name:"size",value:"XS")
]
),
STRProductItem(
productId:"3",
productGroupId:"1",
title:"High-waist midi skirt",
url:"https://www.storyly.io/",
description:"High-waist midi skirt made of a viscose blend. Featuring a slit at the hem and invisible zip fastening.",
price: 25.99, salesPrice: 25.99,
currency:"USD",
imageUrls:["https://random-feed-generator.vercel.app/images/clothes/group-1/1-6D7868.jpg","https://random-feed-generator.vercel.app/images/clothes/group-1/2-6D7868.jpg","https://random-feed-generator.vercel.app/images/clothes/group-1/3-6D7868.jpg","https://random-feed-generator.vercel.app/images/clothes/group-1/4-6D7868.jpg"],
variants:[
STRProductVariant(name:"color",value:"#6D7868"),
STRProductVariant(name:"size",value:"M")
]
),
STRProductItem(
productId:"4",
productGroupId:"1",
title:"High-waist midi skirt",
url:"https://www.storyly.io/",
description:"High-waist midi skirt made of a viscose blend. Featuring a slit at the hem and invisible zip fastening.",
price: 25.99, salesPrice: 25.99,
currency:"USD",
imageUrls:["https://random-feed-generator.vercel.app/images/clothes/group-1/1-6D7868.jpg","https://random-feed-generator.vercel.app/images/clothes/group-1/2-6D7868.jpg","https://random-feed-generator.vercel.app/images/clothes/group-1/3-6D7868.jpg","https://random-feed-generator.vercel.app/images/clothes/group-1/4-6D7868.jpg"],
variants:[
STRProductVariant(name:"color",value:"#6D7868"),
STRProductVariant(name:"size",value:"L")
]
),
]
...
self.StorylyVerticalFeedView.hydrateProducts(products: products)
Warning
For a content that needs product data, if that product data is not provided, the content is not displayed.
Please make sure that you pass the necessary product data to avoid any issue.
Updated 2 months ago