Initial SDK Setup

Initial SDK Setup

This walkthrough shows how to add Storyly to your iOS application and show your Vertical Video Feed in it.

πŸ“˜

Before you begin

Please login into Storyly Dashboard and get your widget token.

Installation

🚧

Warning

Storyly SDK targets iOS 12 or higher.

πŸ“˜

Tips

You can find the latest version’s release notes here.

CocoaPods

Storyly SDK is available through CocoaPods. To integrate Storyly SDK into your Xcode project using CocoaPods, specify it in your Podfile:

use_frameworks!
pod 'Storyly'

Then run pod install.

❗️

Danger

Please note that you need to use Storyly with use_frameworks! option in Podfile. If you need to add it without using use_frameworks! option, add following lines to your Podfile before updating Pods or check Manual Installation.

dynamic_frameworks = ['Storyly', 'SDWebImage']
pre_install do |installer|
  installer.pod_targets.each do |pod|
    if dynamic_frameworks.include?(pod.name)
      def pod.dynamic_framework?;
        true
      end
      def pod.build_type;
        Pod::BuildType.dynamic_framework
      end
    end
  end
end

🚧

Warning

Please note that CocoaPods version should be 1.9+

Carthage

Storyly SDK is available through Carthage. To integrate Storyly SDK into your Xcode project using Carthage, specify it in your Cartfile:

binary "https://prod-storyly-media.s3.eu-west-1.amazonaws.com/storyly-sdk/Carthage/Storyly.json"
github "SDWebImage/SDWebImage" == 5.10.0

Then run carthage update --use-xcframeworks.

After, add the frameworks to your Xcode project: Go to targets and select your application. Click plus button from the Frameworks, Libraries, and Embedded Content section and add Storyly.xcframework and SDWebImage.xcframework. If you can't find it, add it from Add Other > Add files dialog. Frameworks will be located at Carthage/Build/.

🚧

Warning

Please note that Carthage version should be 0.38+

Swift Package Manager

Storyly SDK is available through SPM. To integrate Storyly SDK into your Xcode project using SPM, add and enter package repository in the Swift Packages tab of your project.

Manually

If you prefer not to use dependency managers, Storyly SDK releases are available through Storyly iOS SDK Releases.

  • Download and unzip both Storyly.xcframework and SDWebImage.xcframework files.
  • Add the frameworks to your Xcode project: Use Finder to drag them both Storyly.xcframework and SDWebImage.xcframework folders into your Xcode project and drop it onto your project in the Project navigator window.
  • Follow the prompts to copy items into the destination and to create folder references.

Add Vertical Feed View

Let's start with importing related modules to use Storyly:

import Storyly
@import Storyly;

There are 2 view types available for Vertical Feed which are StorylyVerticalFeedBarView and StorylyVerticalFeedView.

As seen on the left-hand side, StorylyVerticalFeedBarView is a bar-like design that enables users to scroll among available content horizontally.

As seen on the right-hand side, StorylyVerticalFeedView is a grid-like design that enables users to scroll among available content vertically.

You can add StorylyVerticalFeedView or StorylyVerticalFeedBarView from Storyboard or Programmatically. Please follow the next sections.

🚧

Warning

In the following sections of the documentation, StorylyVerticalFeedView is going to be used for code samples. However, the same applies while using the other view type StorylyVerticalFeedBarView.

Add Storyly Vertical Feed View from Storyboard

StorylyVerticalFeedView extends UIView so that you can use inherited functionality as it is. So, you can add StorylyVerticalFeedView to any of the appsStoryboards and XIB Files.

  • Add a UIView in your Storyboard(or XIB File)
  • Define Custom Class as StorylyVerticalFeedView in Identity Inspector.
  • Set height to 120 is suggested for a better experience for the default size

Add Storyly Vertical Feed View Programmatically

StorylyVerticalFeedView extends UIView so that you can use inherited functionality as it is. So, you can initialize StorylyVerticalFeedView using UIView’s constructors.

let StorylyVerticalFeedView = VerticalFeedView()
self.view.addSubview(StorylyVerticalFeedView)
StorylyVerticalFeedView *VerticalFeedView = [[StorylyVerticalFeedView alloc] init];
[self.view addSubview:VerticalFeedView];

🚧

Warning

Please note that if you use Auto Layout Constraints, you need to set translatesAutoresizingMaskIntoConstraints=false

Initialize Vertical Feed View

You are one step away from enjoying Storyly. You just need to init StorylyVerticalFeedView.

self.StorylyVerticalFeedView.verticalFeedInit = VerticalFeedInit(storylyId: WIDGET_TOKEN)
self.StorylyVerticalFeedView.verticalFeedInit = [[VerticalFeedInit alloc] initWithStorylyId: WIDGET_TOKEN];

πŸ“˜

Tip

Please do not forget to use your own token. You can get your token from the Storyly Dashboard -> Settings -> App Settings

Just hit the run. Now, you should be able to enjoy the Vertical Feed experienceπŸŽ‰!

🚧

Warning

While initializing the StorylyVerticalFeedView, extra settings should be done with Config parameter. The aim is to gather all of the listed methods under the Config parameter.

You can check the usage of config parameter as shown below and can check Configuration section for more details.

While initializing the StorylyVerticalFeedView, extra settings should be done with Config parameter. The aim is to gather all of the listed methods under the Config parameter.

Configuration

While initializing the StorylyVerticalFeedView, extra settings should be done with Config parameter. The aim is to gather all of the listed methods under the Config parameter.

🚧

Warning

Please check the relevant section for a detailed explanation.

self.StorylyVerticalFeedView.verticalFeedInit = VerticalFeedInit(
            storylyId: storylyToken,
            config: StorylyVerticalFeedConfig.Builder()
               .setVerticalFeedBarStyling(
                    styling: StorylyVerticalFeedBarStyling.Builder()
                        .build()
               )
               .setVerticalFeedGroupStyling(
                   styling: StorylyVerticalFeedGroupStyling.Builder()
                       .build()
                )
                .setVerticalFeedStyling(
                    styling: StorylyVerticalFeedCustomization.Builder()
                        .build()
                )
                .setMaxItemCount(count: Int)
                .setUserData(data: [String : String])
                .setLabels(labels: Set<String>?)
                .setCustomParameter(parameter: String?)
                .setLayoutDirection(direction: .LTR | .RTL)
                .setTestMode(isTest: true)
                .setLocale(locale: String?)
                .setProductConfig(
                    config: StorylyProductConfig.Builder()
                        .build()
                )
                .setStorylyPayload(payload: String?)
                .setShareConfig(
                    StorylyShareConfig.Builder()
                        .setShareUrl(url: String)
                        .setFacebookAppID(id: String)
                        .build()
                )
                .build()
        )

Set Up Delegate

This walkthrough shows you how to handle Storyly events in your app. Storyly events provide insight into what is happening on a Storyly widget such as loading states.

πŸ“˜

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 StorylyVerticalFeedDelegate
self.StorylyVerticalFeedView.delegate = self // Override event functions
// the class(indicated with self) extends StorylyVerticalFeedDelegate
self.StorylyVerticalFeedView.delegate = self; // Override event functions

To get notification about these basic events, you should override the following functions in StorylyVerticalFeedDelegate.

verticalFeedLoaded Event

This event will let you know that Storyly has completed its network operations, and the content list has just been shown to the user. To be notified about this event, use the following example:

func verticalFeedLoaded(_ view: Storyly.StorylyVerticalFeedView,
                   		  feedGroupList: [Storyly.VerticalFeedGroup],
                   			dataSource: StorylyDataSource) {}                            
- (void)verticalFeedLoaded:(StorylyVerticalFeedView *)view
       	     feedGroupList:(NSArray<VerticalFeedGroupList *> *)feedGroupList
       	        dataSource:(StorylyDataSource *)dataSource {}                       

verticalFeedLoadFailed Event

This event will let you know that Storyly has completed its network operations and had a problem while fetching your content. In this case, users will see four empty covers, which we call the skeleton view. To be notified about this event, use the following example:

func verticalFeedLoadFailed(_ view: Storyly.StorylyVerticalFeedView,
                      			errorMessage: String) {}
- (void)verticalFeedLoadFailed:(StorylyVerticalFeedView *)view
           				errorMessage:(NSString *)errorMessage {}

verticalFeedActionClicked Event

This guide shows how to handle Action Button (CTA) clicks from user.

When the end-user clicks on the an Action Button (CTA), redirection needs to be handled by the application itself. To handle this action, you must register StorylyVerticalFeedDelegate and override StorylyVerticalFeedDelegate function in it. You can register the delegate using the following code example:

func verticalFeedActionClicked(_ view: Storyly.StorylyVerticalFeedView,
                            	 rootViewController: UIViewController,
                               feedItem: Storyly.VerticalFeedItem) {
    // verticalFeed.actionUrl is the field that contains the CTA URL
}

How to Show/Hide Widget

This guide shows use cases for showing or hiding the widget in your app. To increase user experience when there is no content available or content is not loading using Storyly event handling.

πŸ“˜

Before you begin

You need to have the working Storyly setup as described in Initial SDK Setup

Show Widget

Use case for showing Storyly if StorylyVerticalFeedView is loaded and content is available.

Add StorylyVerticalFeedView to a UIViewController with parameter isHidden as true. Initialize StorylyVerticalFeedView with the token from the dashboard.

Not to show the already visible StorylyVerticalFeedView, check if initially loaded and verticalFeedGroupList size. Set StorylyVerticalFeedView parameter isHidden to false.

πŸ“˜

Event handling

verticalFeedLoaded event triggers first for available cached content and second for request response with current stories. Detailed information about Set Up Delegate

extension ShowStorylyVerticalFeedViewController: StorylyVerticalFeedDelegate {
    func verticalFeedLoaded(_ view: Storyly.StorylyVerticalFeedView,
                       			feedGroupList: [Storyly.VerticalFeedGroup]) {
       	 if initialLoad {
            initialLoad = false
            StorylyVerticalFeedView.isHidden = false
        }
    }
}
- (void)verticalFeedLoaded:(StorylyVerticalFeedView *)view
						 feedGroupList:(NSArray<VerticalFeedGroup *> *)feedGroupList {
   	 if (!self.initialLoad) {
        self.initialLoad = true;
        [self.StorylyVerticalFeedView setHidden:NO];
   }
}

Hide Widget

Use case for hiding Storyly if StorylyVerticalFeedView is not loaded and content is not available.

Not to show already visible StorylyVerticalFeedView, check if initially loaded and verticalFeedGroupList size. Set StorylyVerticalFeedView property isHidden to false.

Loading cached content triggers verticalFeedLoaded event before verticalFeedLoadFailed event. Check for if the cache loaded and verticalFeedGroupList size. If the cache is not loaded set the StorylyVerticalFeedView parameter isHidden to true.

πŸ“˜

Event handling

verticalFeedLoaded event triggers first for available cached stories and later for up to date stories.
verticalFeedLoaded for cached stories will trigger before verticalFeedLoadFailed.

extension HideStorylyVerticalFeedViewController: StorylyVerticalFeedDelegate {
     func verticalFeedLoaded(_ view: Storyly.StorylyVerticalFeedView, 
                             feedGroupList: [Storyly.VerticalFeedGroup]) {
        initialLoad = true
    }

    func verticalFeedLoadFailed(_ view: Storyly.StorylyVerticalFeedView,
                                errorMessage: String) {
        if !initialLoad {
            self.StorylyVerticalFeedView.isHidden = true
        }
    }
}
- (void)verticalFeedLoaded:(StorylyVerticalFeedView *)view
       			 feedGroupList:(NSArray<VerticalFeedGroup *> *)feedGroupList {
    self.initialLoad = true;
}

- (void)verticalFeedLoadFailed:(StorylyVerticalFeedView *)view
             			errorMessage:(NSString *)errorMessage {
    if (!self.initialLoad) {
        [self.StorylyVerticalFeedView setHidden:YES];
    }
}

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 under change.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)")
    }
}

Test Mode

πŸ“˜

Before you begin

You need to have the working Storyly integration as described in Initial SDK Setup

This guide shows how to show the test content created in Storyly Dashboard to the specific devices. The default value of isTestMode is false, you need to explicitly define to set test devices.

self.StorylyVerticalFeedView.verticalFeedInit = VerticalFeedInit(
            storylyId: storylyToken,
            config: StorylyVerticalFeedConfig.Builder()
                .setTestMode(isTest: true)
                .build()
)

Localization

This guide will walk you through the process of localizing all Storyly-related texts and content. You can deliver the appropriate content to each language/country pair by passing the locale parameter on the client side.

To set the locale, you need to use the IETF BCP 47 format as shown below:

self.StorylyVerticalFeedView.verticalFeedInit = VerticalFeedInit(
            storylyId: storylyToken,
            config: StorylyVerticalFeedConfig.Builder()
                .setLocale(locale: "tr-TR")
                .build()
)

πŸ“˜

Tip

If you use the Localization feature on the Storyly Dashboard, end user will see the content in their own locale.