Handler

    Handler


    Article summary

    In Shoplive Player, notifications such as user UI events or state changes are conveyed to the client through handler (delegate) functions, and the necessary processing is performed.


    delegate

    Declare a function to receive handler events of the Shoplive iOS SDK, and it is a property that connects events with the Shoplive iOS SDK.

    @objc var delegate: ShopLiveSDKDelegate? { get set }
    @objc public protocol ShopLiveSDKDelegate: AnyObject {
        @objc func handleNavigation(with url: URL)
        @objc func handleChangeCampaignStatus(status: String)
        @objc optional func handleChangedPlayerStatus(status: String)
        @objc func handleCampaignInfo(campaignInfo: [String : Any])
    
        @objc func onSetUserName(_ payload: [String : Any])
    
        @objc func handleCommand(_ command: String, with payload: Any?)
        @objc func handleReceivedCommand(_ command: String, with payload: Any?)
    
        @objc func handleError(code: String, message: String)
    
        @objc optional func handleDownloadCoupon(with couponId: String, result: @escaping (ShopLiveCouponResult) -> Void)
        @objc optional func handleCustomAction(with id: String, type: String, payload: Any?, result: @escaping (ShopLiveCustomActionResult) -> Void)
        @objc optional func playerPanGesture(state: UIGestureRecognizer.State, position: CGPoint)
        @objc optional func log(name: String, feature: ShopLiveLog.Feature, campaign: String, payload: [String: Any])
    
    }

    Sample code

    class MainViewController: UIViewController {
        ...
        override func viewDidLoad() {
            super.viewDidLoad()
    
            ShopLive.delegate = self
    
        }
        ...
    }
    
    
    extension MainViewController: ShopLiveSDKDelegate {
        func handleNavigation(with url: URL) {
            print("handleNavigation \(url)")
        }
        ...
    }


    handleNavigation

    When a product, banner, etc., is selected (tapped) in Shoplive, it conveys the information of the selected product or banner.

    handleNavigation(with url: URL)

    Parameter name

    Type

    Description

    url

    URL

    URL to go to when selecting a product or banner

    Sample code

    extension MainViewController: ShopLiveSDKDelegate {
        func handleNavigation(with url: URL) {
            print("handleNavigation \(url)")
    
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        }
        ...
    }


    handleChangeCampaignStatus

    When the broadcast status changes, it conveys the updated broadcast status.

    @objc func handleChangeCampaignStatus(status: String)

    Parameter name

    Type

    Description

    status

    String

    Broadcast status: READY, ONAIR, CLOSED

    Sample code

    extension MainViewController: ShopLiveSDKDelegate {
        func handleChangeCampaignStatus(status: String) {
            print("handleChangeCampaignStatus \(status)")
    
            switch status {
                case "READY", "ONAIR":
                    break
                case "CLOSED":
                    print("ended campaign")
                    break
            }
        }
        ...
    }


    handleChangedPlayerStatus

    Receives the change of Shoplive Player status.

    handleChangedPlayerStatus(status: String)

    Parameter name

    Type

    Description

    status

    String

    Status of Shoplive Player:

    • CREATED: The player created

    • DESTROYED: The player terminated

    Sample code

    extension MainViewController: ShopLiveSDKDelegate {
        func handleChangedPlayerStatus(status: String) {
            print("handleChangedPlayerStatus \(status)")
    
            switch status {
                case "CREATED":
                    break
                case "DESTROYED":
                    break
            }
        }
        ...
    }


    handleCampaignInfo

    Provides information about the current broadcast.

    handleCampaignInfo(campaignInfo: [String : Any])

    Parameter name

    Type

    Description

    campaignInfo

    [String: Any]

    The information of a current campaign. For example, {title: “BROADCAST_TITLE”}

    Sample code

    extension MainViewController: ShopLiveSDKDelegate {
        func handleCampaignInfo(campaignInfo: [String : Any]) {
    
            campaignInfo.forEach { (key, value) in
                print("campaignInfo key: \(key)  value: \(value)")
            }
    
        }
        ...
    }


    onSetUserName

    Called when the username has changed.

    onSetUserName(_ payload: [String : Any])

    Parameter name

    Type

    Description

    payload

    [String: Any]

    The information of a user. For example, {user: “USER_ID”}

    Sample code

    extension MainViewController: ShopLiveSDKDelegate {
        func onSetUserName(_ payload: [String : Any]) {
            payload.forEach { (key, value) in
                print("onSetUserName key: \(key) value: \(value)")
            }
        }
        ...
    }

    Change the status of the Shoplive Player

    When the Shoplive Player status changes, a ShopLiveViewTrackEvent is passed through as a command.

    ShopLiveViewTrackEvent

    @objc public enum ShopLiveViewTrackEvent : Int, CaseIterable {
        case viewWillDisAppear
        case viewDidDisAppear
        case pipWillAppear
        case pipDidAppear
        case fullScreenWillAppear
        case fullScreenDidAppear
        
        public var name : String {
            switch self {
            case .viewWillDisAppear:
                return "viewWillDisAppear"
            case .viewDidDisAppear:
                return "viewDidDisAppear"
            case .pipWillAppear:
                return "pipWillAppear"
            case .pipDidAppear:
                return "pipDidAppear"
            case .fullScreenWillAppear:
                return "fullScreenWillAppear"
            case .fullScreenDidAppear:
                return "fullScreenDidAppear"
            }
        }
    }

    Parameter name

    Type

    Description

    viewWillDisAppear

    CaseIterable

    Shoplive Player starts changing to closed state

    viewDidDisAppear

    CaseIterable

    Shoplive Player has changed to closed status.

    pipWillAppear

    CaseIterable

    Shoplive Player starts changing to PIP mode state

    pipDidAppear

    CaseIterable

    Shoplive Player has changed to PIP mode status.

    fullScreenWillAppear

    CaseIterable

    Shoplive Player starts changing to full screen mode

    fullScreenDidAppear

    CaseIterable

    Shoplive Player has changed to full screen mode.

    payload

    Delivers the status of the previous Shoplive Player as a payload.

    Parameter name

    Type

    Description

    currentStyle

    Any?

    The name (String) of the current PresentationStyle

    lastStyle

    Any?

    The name (String) of the previous PresentationStyle

    isPreview

    Any?

    The value is true if window style is Preview, false if window style is InAppPip

    viewHiddenActionType

    Any?

    ShopLiveViewHiddenActionType (Optional String)

    ShopLiveViewHiddenActionType

    Case

    Description

    onSwipeOut

    on swipe out

    onBtnTapped

    on back button click

    onClose

    on calling close() function

    onError

    on exiting due to error

    onRestoringPip

    on exited when restoring from OSPIP by error

    onNavigationHandleClose

    when the user defined nextActionTypeOnHandleNavigation as .CLOSE

    Deprecated

    Parameter name

    Type

    Description

    willShopLiveOn

    CaseIterable

    Shoplive Player starts changing to full screen

    didShopLiveOn

    CaseIterable

    Shoplive Player has changed to full screen

    willShopLiveOff

    CaseIterable

    Shoplive Player starts changing to PIP mode or shutdown state

    didShopLiveOff

    CaseIterable

    Shoplive Player changes to PIP mode or exit status complete

    payload

    Convey the previous Shoplive Player status as a payload.

    Parameter name

    Type

    Description

    style

    Any?

    rawValue(Int) in PresentationStyle

    Sample code

    extension MainViewController: ShopLiveSDKDelegate {
        func handleCommand(_ command: String, with payload: Any?) {
            print("handleCommand: \(command)  payload: \(payload)") 
        }
        ...
    }


    handleReceivedCommand

    Convey the command information received from the WEB of the Shoplive iOS SDK.

    handleReceivedCommand(_ command: String, with payload: Any?)

    Parameter name

    Type

    Description

    command

    String

    The name of a command

    payload

    Any?

    Data passed along with the command

    Sample code

    extension MainViewController: ShopLiveSDKDelegate {
        func handleReceivedCommand(_ command: String, with payload: Any?) {
            switch command {
            case "LOGIN_REQUIRED":
                let alert = UIAlertController(title: command, message: "alert.login.required.description".localized(), preferredStyle: .alert)
                alert.addAction(.init(title: "alert.msg.ok".localized(), style: .default, handler: { _ in
                    
                    ShopLive.startPictureInPicture()
                    let login = LoginViewController()
                    login.delegate = self
                    self.navigationController?.pushViewController(login, animated: true)
                }))
                alert.addAction(.init(title: "alert.msg.no".localized(), style: .default, handler: { _ in
                    alert.dismiss(animated: true)
                }))
                ShopLive.viewController?.present(alert, animated: true, completion: nil)
                break
            case "CLICK_PRODUCT_CART":
              break
            default:
                break
            }
          
        }
        ...
    }


    Coupon

    This status is for setting whether or not the coupon to be visible when coupon processing is completed.

    @objc public enum ShopLiveResultStatus: Int, CaseIterable {
        case SHOW // SHOW coupon
        case HIDE // HIDE coupon
        case KEEP // KEEP the status of coupon visibility
    
        public var name: String {
            switch self {
            case .SHOW:
                return "SHOW"
            case .HIDE:
                return "HIDE"
            case .KEEP:
                return "KEEP"
            }
        }
    }

    Set the type of notification message that appears when coupon processing is completed.

    @objc public enum ShopLiveResultAlertType: Int, CaseIterable {
        case ALERT // Alert
        case TOAST // Toast
    
        public var name: String {
            switch self {
            case .ALERT:
                return "ALERT"
            case .TOAST:
                return "TOAST"
            }
        }
    }
    @objc public class ShopLiveCouponResult: NSObject {
        var success: Bool         
        var coupon: String = ""   
        var message: String?      
        var couponStatus: ShopLiveResultStatus
        var alertType: ShopLiveResultAlertType 
    
        public init(couponId: String, success: Bool, message: String?, status: ShopLiveResultStatus, alertType: ShopLiveResultAlertType) {
            self.coupon = couponId
            self.success = success
            self.message = message
            self.couponStatus = status
            self.alertType = alertType
        }
    }
    @objc public class ShopLiveCustomActionResult: NSObject {
        var success: Bool             
        var id: String = ""           
        var message: String?          
        var couponStatus: ShopLiveResultStatus           
        var alertType: ShopLiveResultAlertType           
    
        public init(id: String, success: Bool, message: String?, status: ShopLiveResultStatus, alertType: ShopLiveResultAlertType) {
            self.id = id
            self.success = success
            self.message = message
            self.couponStatus = status
            self.alertType = alertType
        }
    }


    handleDownloadCoupon

    When a coupon is selected (tapped) on Shoplive, the coupon information is transmitted to the client. The coupon status in the Shoplive Player is set through the result callback, which sends back the client's coupon processing result to the Shoplive iOS SDK.

    handleDownloadCoupon(with couponId: String, result: @escaping (ShopLiveCouponResult) -> Void)

    Parameter name

    Type

    Description

    couponId

    String

    Coupon ID

    result

    ShopLiveCouponResult

    Result callback that transmits the result value to Shoplive iOS SDK

    Sample code

    extension MainViewController: ShopLiveSDKDelegate {
        func handleDownloadCoupon(with couponId: String, result: @escaping (ShopLiveCouponResult) -> Void) {
            print("handleDownloadCoupon: \(couponId)")
    
            
            let couponResult = ShopLiveCouponResult(couponId: couponId, success: true, message: "쿠폰 다운로드가 성공하였습니다.", status: .SHOW, alertType: .ALERT)
            // 실패
            let couponResult = ShopLiveCouponResult(couponId: couponId, success: false, message: "쿠폰 다운로드가 실패하였습니다.", status: .HIDE, alertType: .TOAST)
            result(couponResult)
        }
        ...
    }


    handleCustomAction

    In the popup, the click event is set to custom, and when the popup is selected (tapped), the popup information is transmitted. The popup's id, type (COUPON, BANNER, NOTICE), and payload are transmitted.

    handleCustomAction(with id: String, type: String, payload: Any?, result: @escaping (ShopLiveCustomActionResult) -> Void)

    Parameter name

    Type

    Description

    id

    String

    Popup ID

    type

    String

    Popup type: COUPON, BANNER, NOTICE

    payload

    Any?

    Custom data

    result

    ShopLiveCustomActionResult

    The callback to pass the result toShoplive iOS SDK

    Sample code

    extension MainViewController: ShopLiveSDKDelegate {
        func handleCustomAction(with id: String, type: String, payload: Any?, result: @escaping (ShopLiveCustomActionResult) -> Void) {
            print("handleCustomAction \(id) \(type) \(payload.debugDescription)")
    
            // 팝업 처리가 완료되면 호출됨(처리 결과)
            // 성공
            let customActionResult = ShopLiveCustomActionResult(id: id, success: true, message: "Coupon download was successful.", status: .SHOW, alertType: .ALERT)
    
            // 실패
            let customActionResult = ShopLiveCustomActionResult(id: id, success: false, message: "Coupon download was failed.", status: .HIDE, alertType: .TOAST)
    
            result(customActionResult)
        }
        ...
    }


    handleError

    Delivers messages regarding error situations that occur before or during broadcasting.

    handleError(code: String, message: String)

    Parameter name

    Type

    Description

    code

    String

    An error code

    message

    String

    An error message

    Sample code

    extension MainViewController: ShopLiveSDKDelegate {
        func handleError(code: String, message: String) {
            print("handleError \(code) \(message)")
        }
        ...
    }


    playerPanGesture

    When user moves the window position in PIP mode, the window's coordinates and gesture event status are transmitted.

    playerPanGesture(state: UIGestureRecognizer.State, position: CGPoint)

    Sample code

    extension MainViewController: ShopLiveSDKDelegate {
    	func playerPanGesture(state: UIGestureRecognizer.State, position: CGPoint) {
        	print("gesture state \(state) position \(position)")
    	}
      ...
    }


    log

    The event log of the Shoplive Player is transmitted. This information can be used in analytical tools such as Google Analytics.

    log(name: String, feature: ShopLiveLog.Feature, campaign: String, payload: [String: Any])

    ShopLiveLog

    The event log of the Shoplive Player is transmitted. This information can be used in analytical tools such as Google Analytics.

    @objc public class ShopLiveLog: NSObject {
        @objc public enum Feature: Int, CaseIterable {
            case CLICK, SHOW, ACTION
            
            public var name: String {
                switch self {
                case .CLICK:
                    return "click"
                case .ACTION:
                    return "action"
                case .SHOW:
                    return "show"
                }
            }
            
            static func featureFrom(type: String) -> Feature? {
                return Feature.allCases.filter({$0.name == type}).first
            }
        }
        
        public var name: String
        public var campaign: String
        public var feature: Feature
        public var payload: [String: Any] = [:]
        
        public init(name: String, feature: Feature, campaign: String, payload: [String : Any]) {
            self.name = name
            self.feature = feature
            self.campaign = campaign
            self.payload = payload
        }
    }

    Sample code

    extension MainViewController: ShopLiveSDKDelegate {
        func log(name: String, feature: ShopLiveLog.Feature, campaign: String, payload: [String : Any]) {
            let eventLog = ShopLiveLog(name: name, feature: feature, campaign: campaign, payload: payload)
            print("eventLog \(eventLog.name)")
        }
    }


    What's Next