Firework for Developers
One-to-one Virtual ShoppingBusiness Portal
  • Welcome to Firework for Developers
  • Firework Interactive Video and One-to-many Digital Showroom
  • Web
    • Getting Started (Web)
      • Shopify
      • Magento
      • Wordpress (WooCommerce)
      • Salesforce Commerce Cloud
      • BigCommerce
    • Integration Guide for Web
      • Components
        • Hero Unit
        • Carousel / Grid
        • Storyblock (Web)
        • Player (Floating)
        • Storylink
      • Styling
      • Feed Attributes
      • Player
        • Configuration
          • Appearance
      • Video customization
        • Video Factory
        • CTA Button
        • Product cards
      • Events
        • Embed Feed and Storyblock Events
        • Video player events
        • Live stream events
        • Shopping events
      • Shopping Integration (V2)
        • Introduction
        • Shopping APIs
        • Product Hydration
        • Product Factory
        • Cart Sync
        • Tracking
          • Purchase
          • Add to cart
          • Remove from cart
          • Page viewed
        • Shopping Integration FAQ
        • Migrate from V1
      • Web SDK
      • Enhanced Picture-in-Picture
      • Privacy settings
        • Tracking settings
        • Cookies management
        • Content Security Policy
    • Telemetry console
    • Firework Service Domains
    • FAQ & Troubleshooting (Web)
  • Android SDK
    • Integration Guide for Android SDK
      • Getting Started (Android)
      • Video Feed (Android)
        • Video Feed Layouts (Android)
        • Channel Feed (Android)
        • Discover Feed (Android)
        • Playlist Feed (Android)
        • Dynamic Content Feed
        • Channel Hashtags Feed
        • Sku Feed
        • Single Content Feed
        • Configure Video Feed
      • Customization
        • CTA
      • Analytics (Android)
      • Shoppable Videos (Android)
        • Product Hydration
      • Live Stream Support (Android)
      • Video Player (Android)
      • StoryBlock (Android)
      • Share & Video Deep linking
      • Ad Support (Android)
      • Configure Video Advertisements Source (Android)
      • In-app Language Switches
      • Compose support(Android)
    • Sample App (Android)
    • FAQ & Troubleshooting (Android)
    • Changelog (Android)
  • iOS SDK
    • Integration Guide for iOS SDK
      • Getting Started (iOS)
      • ATT compliance (iOS)
      • Video Feed (iOS)
        • Discover Feed(iOS)
        • Channel Feed (iOS)
        • Playlist Feed (iOS)
        • Playlist Group Feed (iOS)
        • Dynamic Content (iOS)
        • Hashtag Playlist (iOS)
        • SKU Playlist (iOS)
        • Video Ads (iOS)
        • Video Feed Layouts (iOS)
      • Story Block (iOS)
      • Customization (iOS)
        • Video feed configurations (iOS)
        • Player configurations (iOS)
        • Shopping configurations (iOS)
          • Customize product card on videos using the custom view (iOS)
        • Customize click behaviors (iOS)
      • Shopping (iOS)
      • Live Stream Support (iOS)
      • Analytics (iOS)
      • Share & Deeplinking(iOS)
      • Ad Support (iOS)
    • Sample App (iOS)
    • FAQ & Troubleshooting (iOS)
    • Changelog (iOS)
  • React Native SDK
    • Integration Guide for React Native SDK V2
      • Getting Started (React Native)
      • ATT compliance React Native (iOS)
      • Video Feed (React Native)
      • Story Block (React Native)
      • Customization (React Native)
        • Video feed configurations (React Native)
        • Player configurations (React Native)
        • Shopping configurations (React Native)
          • Customize product card on videos using the custom view (React Native)
        • Customize click behaviors (React Native)
      • Shopping (React Native)
      • Live Stream Support (React Native)
      • Ad Support (React Native)
      • Analytics (React Native)
      • App-level Language Setting (React Native)
      • Share & Video Deeplinking (React Native)
      • Android Style (React Native)
      • Inject Android Image Loader (React Native)
      • Integrate SDKs in Hybrid React Native and native Apps
      • Reference (React Native)
      • Sample App (React Native)
      • FAQ & Troubleshooting (React Native)
      • Changelog (React Native)
  • Flutter SDK
    • Integration Guide for Flutter SDK V2
      • Getting Started (Flutter)
      • ATT compliance Flutter (iOS)
      • Video Feed (Flutter)
      • Story Block (Flutter)
      • Customization (Flutter)
        • Video feed configurations (Flutter)
        • Player configurations (Flutter)
        • Shopping configurations (Flutter)
          • Customize product card on videos using the custom view (Flutter)
        • Customize click behaviors (Flutter)
      • Live Stream Support (Flutter)
      • Shopping (Flutter)
      • Ad Support (Flutter)
      • Analytics (Flutter)
      • App-level Language Setting (Flutter)
      • Share & Video Deeplinking (Flutter)
      • Inject Android Image Loader (Flutter)
      • Android Style (Flutter)
      • Integrate SDKs in Hybrid Flutter and native Apps
      • Reference (Flutter)
      • Sample App (Flutter)
      • FAQ & Troubleshooting (Flutter)
      • Changelog (Flutter)
  • Help Articles
    • Importing Products to Firework
    • Adding products to a video
    • Displaying product videos on product pages using hashtag filtering(Web)
    • Syncing Carts
    • Encoded IDs
Powered by GitBook
On this page
  • Common Mistakes
  • View Controller Lifecycle Management
  • Attaching a View Controller in a Table or Collection Cell View
  • Safe Area Guides
  • Sibling Views
  • SDK Initialization
  • Video Feeds
  • Missing or Empty Video Feeds
  • Creating Feed with Circular Thumbnails

Was this helpful?

  1. iOS SDK

FAQ & Troubleshooting (iOS)

Common Mistakes

This section contains common mistakes that can lead to a FeedViewController to not behave correctly.

View Controller Lifecycle Management

Properly managing a view controller's lifecycle is easily overlooked because Xcode does not strictly enforce this. So when a subtle issue does arise the root cause may not be all that obvious and is hard to debug.

Attaching a View Controller

When add a view controller as a child of another view controller it is important to call the correct methods so that it will start to receive the normal view controller life cycle events.

The steps for attaching a child view controller are

  1. Add child to parent view controller

  2. Add add root view from child view controller to some view in the parent view controller

  3. Set constraints on child view controller view

  4. Inform the child view controller that it has been moved onto the parent view controller

The last step is really important and also overlooked as it will inform the child view controller that it that it can begin laying out its components.

Here is an example

let feedVC = //... 

parentViewController.addChild(feedVC)

parentViewController.view.addSubView(feedVC.view)

feedVC.view.translatesAutoresizingMaskIntoConstraints = false

// ... Set feed constraint
NSLayoutConstraint.activate(
    constraints
)

feedVC.didMove(toParent: parentViewController)

Detaching a View Controller

Similar to attaching a view controller we must also detach a view controller. Detaching is more straightforeward.

The steps to detach

  1. Inform the child view controller it will be moving from the parent view controller

  2. Remove the child view controller from the parent

  3. remove the child view controller view from super view

feedVC.willMove(toParent: nil) // Let's the child VC know it will be detached from the parent

feedVC.removeFromParent()

feedVC.view.removeSuperview()

Attaching a View Controller in a Table or Collection Cell View

Often times it is desirable to display a horizontal scrolling feed within a UITableView or UICollectionView.

There are two lifecycle events on the UITableView and UICollectionView that we can use to attach and deatch the FeedViewController. For details on attaching and detaching see View Controller Lifecycle Management section above.

The Table and Collection views have a delegate method that is called before a cell is going to be shown on a screen; table/collectionView(_:willDisplayCell:at:). When this method is called it is a good time to attach the feed view controller.

Conversely, the Table and Collection views have a method that is called just after a cell has left the screen; table/collectionView(_:didEndDisplayingCell:at:). WHen this method is called it is a good time to detach the feed view controller.

Safe Area Guides

Because the VideoFeedViewController is self contained it must be able to avoid safe areas. As such the VideoFeedViewController attaches its child view controller to the safeAreaGuide of its view.

There are some scenarios that may cause odd behaviors when the VideoFeedViewController is laid out.

Sibling Views

This scenario occurs when a the VideoFeedViewController is attached to a UIScrollView, UICollectionView or UITableView which has a sibling view. The safe area guides will propagate down to the VideoFeedViewController when the UIScrollView, UICollectionView or UITableView is not the first child in the view hierarchy.

Typically, UIScrollView, UICollectionView or UITableView respects the safe area by adjusting the content size to allow the content to scroll above the safe area. Thus, UIKit does not pass the guides down into views that are within the content view of the UIScrollView. However, behavior suggests there is a bug within the UIKit logic.

Workarounds

To get around this issue simply make sure the UIScrollView, UICollectionView or UITableView is the first sibling of the parent view. In story board simply drag the view in question to the top of the subclasses. Or, if you are building views programmatically simply make sure to view.addSubview() the view in question first.

SDK Initialization

FireworkVideoSDK.initializeSDK accepts an optional delegate parameter that can receive any errors the SDK outputs during setup. This delegate can be any class that conforms to the FireworkVideoSDKDelegate protocol. See example code below that uses AppDelegate to print any errors to console.

import UIKit

/// Add the dependency SDK
import FireworkVideo

@main
class AppDelegate: UIResponder, UIApplicationDelegate, FireworkVideoSDKDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        FireworkVideoSDK.initializeSDK(delegate: self)
        return true
    }
    
    func fireworkVideoDidLoadSuccessfully() {
        print("FireworkVideo loaded successfully.")
    }
    
    func fireworkVideoDidLoadWith(error: FireworkVideoSDKError) {
        switch error {
        case .missingAppID:
            print("FireworkVideo loaded with error due to missing FireworkVideo app ID.")
        case .authenticationFailure:
            print("FireworkVideo loaded with error due to authentication failure.")
        @unknown default:
            break
        }
    }

Video Feeds

VideoFeedViewController exposes an optional delegate property that can receive any errors the SDK outputs when loading the video feed or a success when the video feed loaded successfully.

/// Add the dependency SDK
import FireworkVideo

class VideoFeedService: VideoFeedViewControllerDelegate {

    func videoFeedDidLoadFeed(_ viewController: FireworkVideo.VideoFeedViewController) {
        print("Video feed on view controller \(viewController) loaded.")
    }

    func videoFeed(_ viewController: FireworkVideo.VideoFeedViewController, didFailToLoadFeed error: FireworkVideo.VideoFeedError) {
        if case let FireworkVideo.VideoFeedError.contentSourceError(contentSourceError) =  error {
            print("Video feed on view controller \(viewController) loaded with error \(contentSourceError.errorDescription).")
        } else if case let FireworkVideo.VideoFeedError.unknownError(underlyingError) = error {
            print("Video feed on view controller \(viewController) loaded with error \(underlyingError.localizedDescription).")
        }        
    }
}

Missing or Empty Video Feeds

In the event the feed is empty or the SDK encounters an error when downloading videos, create a new instance and replace the existing instance in your view hierarchy. If the video feed source configured for the view controller does not have videos available, you may need to supply an alternative source when creating the new instance.

If VideoFeedViewController is a child view controller, make sure to call the view controller containment lifecycle methods when removing it from your apps view hierarchy to ensure proper cleanup.

/// Removing videoFeedViewController from it's parent view controller

videoFeedViewController.willMove(toParent: nil)
videoFeedViewController.view.removeFromSuperview()
videoFeedViewController.removeFromParent()

Creating Feed with Circular Thumbnails

A commonly asked question is how to create video feed with circular thumbnails. You can use the following logic to implement this

You can create a circular thumbnails by setting the cornerRadius property in viewConfiguration of a VideoFeedViewController.

Note: This would only work when the number of lines is fixed. This can be done on the VideoFeedItemContentConfiguration.title.numberOfLines

The following properties are needed identify the corner radius required for circular thumbnails.

  1. totalHeight = This will be the height you set for the VideoFeedViewController

  2. contentPadding = This value is found in the layout.contentInsets property of the VideoFeedViewController

  3. labelHeight = The size of the font used on the viewConfiguration.itemView.title.font

  4. titleSpacing = The spacing between the label and the thumbnail. This is located in the viewConfiguration.itemView.titleLayoutConfiguration.insets.top Putting it all together

imageSize = totalHeight - (contentPadding.top + contentPadding.bottom) + (labelHeight * numberOfLines) + titleSpacing

cornerRadius = imageSize / 2 

Now set the cornerRaidus property for your viewConfiguration and you are done!

PreviousSample App (iOS)NextChangelog (iOS)

Last updated 2 months ago

Was this helpful?