GuidesAPI GuideChangelog
Log In
Guides

iOS 웹뷰 연동

고객사 iOS 애플리케이션의 네이티브 WKWebView를 활용하여 SauceClip 플레이어를 연동하는 방법을 안내합니다.

연동 방식은 서비스 환경에 따라 크게 세 가지로 나뉘며, 프로젝트에 적합한 방식을 선택하여 구현할 수 있습니다.


1. 연동 방식

연동 방식은 서비스 환경에 따라 SauceClip 도메인 URL 직접 연동(방식 A), 커스텀 도메인 연동(라이브러리 사용 - 방식 B / 라이브러리 미사용 - 방식 C) 세 가지로 구분되며, 프로젝트에 적합한 방식을 선택하여 구현할 수 있습니다.

방식 A. SauceClip 도메인 URL 직접 연동

SauceClip에서 제공하는 기본 클립 플레이어 URL을 WKWebView에 직접 로드합니다. 별도의 웹 개발 없이 가장 빠르고 간편하게 연동할 수 있습니다.

방식 B. 커스텀 도메인 연동 (라이브러리 사용)

고객사 도메인의 웹페이지에 SauceClip JS 라이브러리를 설치한 후, 해당 웹페이지를 WKWebView에서 로드합니다. 플레이어 레이아웃 제어 등 웹 환경 확장이 필요할 때 적합합니다.

👉 라이브러리 및 iframe 연동이 필요한 경우, 별도 라이브러리 가이드를 참고해 주세요. 🔗라이브러리 및 iframe 연동 가이드 문서

방식 C. 커스텀 도메인 연동 (라이브러리 미사용)

고객사가 자체 웹페이지에 라이브러리를 사용하지 않고 직접 플레이어를 임베드하여 구축한 후, 해당 페이지를 WKWebView에서 로드합니다.



2. 사전 준비 (Prerequisites) - 공통

원활한 숏폼 영상 재생을 위해 아래 사항을 확인합니다.

2.1 HTTPS 환경 사용 권장

WKWebView는 App Transport Security(ATS) 정책의 영향을 받으므로, SauceClip URL 또는 고객사 커스텀 웹페이지는 HTTPS 환경 사용을 권장합니다.


3. WebView 설정 (Settings) - 공통

숏폼 비디오 스트리밍과 브릿지가 정상적으로 동작하기 위해서는 아래의 필수 웹 설정이 선행되어야 합니다.

import UIKit
import WebKit

final class ClipWebViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {

    private lazy var webView: WKWebView = {
        let userContentController = WKUserContentController()
        let configuration = WKWebViewConfiguration()
        configuration.userContentController = userContentController
        configuration.allowsInlineMediaPlayback = true

        if #available(iOS 10.0, *) {
            configuration.mediaTypesRequiringUserActionForPlayback = []
        }

        let webView = WKWebView(frame: .zero, configuration: configuration)
        webView.navigationDelegate = self
        webView.uiDelegate = self
        webView.scrollView.contentInsetAdjustmentBehavior = .never
        return webView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(webView)
        webView.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            webView.topAnchor.constraint(equalTo: view.topAnchor),
            webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            webView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ])
    }
}

4. 로드 구현

선택한 방식에 맞게 URL을 로드합니다.

방식 A. SauceClip URL 직접 로드

let clipId = "YOUR_CLIP_ID"
let sauceClipUrl = URL(string: "https://player.sauceflex.com/clip/\(clipId)")!
webView.load(URLRequest(url: sauceClipUrl))

방식 B / C. 고객사 커스텀 웹페이지 로드

라이브러리 사용 여부(방식 B, C)와 관계없이, iOS 앱단에서는 동일하게 고객사 도메인으로 구축된 웹페이지 URL을 로드합니다.

let clientDomainUrl = URL(string: "https://www.your-domain.com/clip-player?clipId=YOUR_CLIP_ID")!
webView.load(URLRequest(url: clientDomainUrl))

5. JavaScript 브릿지 연동 (Bridge Integration)

플레이어 내부에서 발생하는 액션(상품 클릭, 공유하기 등)을 네이티브 앱에서 처리하려면WKScriptMessageHandler를 등록해야 합니다.

5.1 브릿지 객체 생성

import UIKit
import WebKit

final class SauceClipBridge: NSObject, WKScriptMessageHandler {
    weak var viewController: UIViewController?

    init(viewController: UIViewController) {
        self.viewController = viewController
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        switch message.name {
        case "sauceclipMoveProduct":
            if let payload = message.body as? String {
                // 전달받은 JSON(payload)을 파싱하여
                // 네이티브 상품 상세 화면으로 이동 처리
            }

        case "sauceclipOnShare":
            if let payload = message.body as? String {
                // 전달받은 JSON(payload)을 파싱하여
                // iOS 기본 공유 시트(UIActivityViewController) 실행
            }

        default:
            break
        }
    }
}

👉 전체 Payload 규격 및 메서드는 🔗 SauceClip Payload 스펙 가이드 문서 참고해 주세요.

5.2 WebView에 브릿지 연결

private var bridge: SauceClipBridge!

override func viewDidLoad() {
    super.viewDidLoad()

    bridge = SauceClipBridge(viewController: self)

    let controller = webView.configuration.userContentController
    controller.add(bridge, name: "sauceclipMoveProduct")
    controller.add(bridge, name: "sauceclipOnShare")
}

🏠 소스라이브 🎬 소스클립 🔗 소스링크 📢 소스애드
🧩 API 가이드
🆕 최근 업데이트
💬 도움이 더 필요하신가요?
메일로 문의 카카오톡 채널로 문의