Initial SDK Setup

SDK Installation

🚧

Warning

JOIN Stories SDK targets iOS 12 or higher.

Cocoapods

JOIN Stories SDK is available through CocoaPods. To install it, simply add the following lines to your Podfile:

use_frameworks!

target 'your-demo-project' do
  pod 'JOINStoriesSDK'
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
    end
  end
end

This will download the SwiftLint binaries and dependencies in Pods/ during your next pod install execution.

In your terminal (root folder of the project where Podfile file is located), run pod repo update and then pod install

Run your project through your_project_name.xcworkspace

Swift Package Manager

The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler.

Once you have your Swift package set up, adding JoinStoriesSDK as a dependency is as easy as adding it to the dependencies value of your Package.swift.

dependencies: [  
    .package(url: "https://github.com/teamjoin/join-stories-sdk-ios-binary", .upToNextMajor(from: "<latest_version>"))  
]

Manually

If you prefer not to use any of the aforementioned dependency managers, you can integrate JOINStoriesSDK into your project manually.

Embedded Framework

  • Download the zip file from the Package.swift under binaryTarget up Terminal,
  • Unzip the file appearing as an xcframework file
  • Drag JOINStoriesSDK.xcframework into your project

SDK Initialization

πŸ“˜

TeamId and widget alias

You will need your team id and the widgets' alias you want to integrate. You can find both of them in the Integration tab of your widget mobile on studio.

To create a widget, check the documentation. Make sure to choose Mobile app environment.

Before using any feature offered by the JOIN Stories SDK, you have to initialize it in your AppDelegate method :

import UIKit
import JOINStoriesSDK

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        JOINStoriesConfiguration.setValues(teamId: "<your_join_team_id>")
        return true
    }
}

Add Bubble Trigger View

You can add BubbleTriggerView to your app either from UIKit or SwiftUI layout :

🚧

Warning

When integrating, you need to be aware of the widget's lifecycle, as the widget may send request several times during use if it is destroyed and recreated, in the case of a dynamic list.
Destroying and recreating the view will generate a loaded widget, which will be counted towards your pricing

let bubbleTriggerView = BubbleTriggerView(alias: "<your_join_alias>")    
view.addSubview(bubbleTriggerView)
import JOINStoriesSDK

public struct BubbleView: UIViewRepresentable {
    public func makeUIView(context: Context) -> BubbleTriggerView {
        let bubbleTriggerView = BubbleTriggerView(alias: "<your_join_alias>") 
        return bubbleTriggerView
    }
    public func updateUIView(_ uiView: BubbleTriggerView, context: Context) { }
}

struct YourView : View {
 
    var body: some View {
        BubbleView()
    }
}

πŸ‘

Good job !

You have integrated your first trigger and you are ready to see stories in your application.

πŸ“˜

Info

You can use others trigger format like Card. For more info : UI Customizations

Player Standalone Mode

If you want to open the player to display stories following an action (event, button click, etc.), you can use the player in standalone mode. Simply call a method to open the player as follows :

import JOINStoriesSDK

final class ViewController: UIViewController {
 
    private var playerView: JoinStoriesPlayer!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        playerView = JoinStoriesPlayer(alias: "<your_join_alias>")
    }

    func showPlayer() {
        self.playerView.show()
    }
    
}

Additional Methods

Max stories

You can customise the number of stories you want to display in the trigger by using the maxStories parameter at initialization (by default it will display all stories):

JoinStoriesBubbleConfigurations(maxStories: Int)

Dismiss Player Manually

If you want to dismiss the player manually, use can use the dismissPlayer method :

trigger.dismissPlayer()
player.dismissPlayer()

Also, you can use the static function :

JOINStories.dismissPlayer()

Set Up Listener

The JOIN Stories SDK exposes a delegate JOINStoriesListenerDelegate who notifies the application when an event occurs. You can register the listener using the following code example and then override its functions to learn about specific events, which will be explained in the next sections.

import JOINStoriesSDK

class YourViewController: UIViewController {

   override func viewDidLoad() {
        super.viewDidLoad()
       JOINStoriesListener.setDelegate(delegate: self)
   }
}

extension YourViewController: JOINStoriesListenerDelegate {
   ...
}
import JOINStoriesSDK

struct YourView : View {
    
   @StateObject var viewModel = YourViewModel()
    
    var body: some View {
        Text("Hello, world!")
    }
}

class YourViewModel: ObservableObject {
    init() {
        JOINStoriesListener.setDelegate(delegate: self)
    }
}

extension YourViewModel: JOINStoriesListenerDelegate {
    ...
}

onTriggerFetchSuccess

This event tells you that the trigger has completed its network operations and that there are stories to display. Returns the number of items displayed.

func onTriggerFetchSuccess(itemCount: Int) {}

onTriggerFetchEmpty

This event tells you that the trigger has completed its network operations and that there are no stories to display. This can happen if the add alias has no stories configured or if there are no stories already stored locally in offline mode.

func onTriggerFetchEmpty() {}

onTriggerFetchError

This event tells you that the trigger has completed its network operations and had a problem while fetching your stories.

func onTriggerFetchError(errorMessage: String) {}

onPlayerFetchSuccess

This event tells you that the player has completed its operations (network or local) and that there are stories to display.

func onPlayerFetchSuccess() {}

onPlayerLoaded

This event tells you that the player is loaded and playing the stories

func onPlayerLoaded() {}

onPlayerFetchError

This event tells you that the trigger has completed its operations (network or local) and had a problem while fetching your stories.

func onPlayerFetchError(errorMessage: String) {}

onPlayerDismissed

This event tells you that the player has disappeared and how. It can be automatic when all the stories have finished being viewed without any user interaction. It can be manual when it's the user who makes the player disappear or via an event implemented in the application.

func onPlayerDismissed(type: OnDismiss) {
  switch type {
   case .auto : 
    //
   case .manual : 
    //
  }
}

onContentLinkClick

This event tells you that a user has clicked on a CTA in the player. It indicates the CTA link in parameters and you can customize the behaviour based on this link (deeplink, path, https, etc...).
The method should return true if the app manages the link click behaviour, and false if the app does not want to catch the link provided. If a false is returned, the SDK will try to open the link in the default browser of the device. By default, the method return false.

func onContentLinkClick(url: String) -> Bool {
  return false
}