네이티브 연동

    네이티브 연동


    기사 요약

    라이브러리 추가

    build.gradle에 아래 코드를 추가하세요. app/build.gradle에 통합된 라이브러리나 분할된 라이브러리를 추가하세요.

    통합된 라이브러리

    dependencies {
        def shoplive_sdk_version = "1.6.0.1"
        
        // Shoplive combined packaging
        implementation "cloud.shoplive:shoplive-sdk-all:$shoplive_sdk_version" // live + short-form + editor
    }

    분할된 라이브러리

    dependencies {
        def shoplive_sdk_version = "1.6.0.1"
        def your_exoplayer_version = "2.19.1"
        def your_media3_version = "1.4.1"
        def shoplive_exoplayer_version = your_exoplayer_version + "." + "8"
        def shoplive_media3_version = your_media3_version + "." + "8"
        
        // Shoplive split packaging
        implementation "cloud.shoplive:shoplive-common:$shoplive_sdk_version" // must required
        implementation "cloud.shoplive:shoplive-exoplayer:$shoplive_exoplayer_version" // must required
        // When using media3. Exoplayer will be deprecated soon.
        // https://developer.android.com/guide/topics/media/media3/getting-started/migration-guide
        // implementation "cloud.shoplive:shoplive-media3:$shoplive_media3_version" 
        implementation "cloud.shoplive:shoplive-network:$shoplive_sdk_version" // must required
      
        implementation "cloud.shoplive:shoplive-short-form:$shoplive_sdk_version" // for short-form player
      
        implementation "cloud.shoplive:shoplive-sdk-core:$shoplive_sdk_version" // for live player
    
        implementation "cloud.shoplive:shoplive-filter:$shoplive_sdk_version" // for short-form editor
        implementation "cloud.shoplive:shoplive-video-editor:$shoplive_sdk_version" // for short-form editor
    }

    Proguard Rule 추가

    R8 Build를 하면 난독화 문제가 발생할 수 있습니다. 아래의 내용을 추가해주세요.

    -keep public class cloud.shoplive.** { *; }
    -dontwarn cloud.shoplive.**
    -keep class org.json.** { *; }
    -keep class com.google.gson.** { *; }


    AccessKey 적용

    ShopLiveCommon.setAccessKey("your accessKey")

    Access Key

    Access key 와 secret key는 샵라이브 담당자로부터 제공받을 수 있습니다.


    네이티브 컬렉션 적용

    원하는 형태의 숏폼 컬렉션을 적용합니다.

    • 영상의 기본 비율은 9:16입니다. 고객사가 원하는 너비, 높이를 유연하게 적용할 수 있어 고객사가 원하는 대로 Customizing 가능합니다.

    ShopLiveShortformCardTypeView

    세로 스크롤 레이아웃(격자형 목록 Large) 컬렉션을 노출할 화면에 다음과 같이 구성합니다. 고객사 xml에 ShopLiveShortformCardTypeView 를 추가하세요.

    <cloud.shoplive.sdk.shorts.ShopLiveShortformCardTypeView
        android:id="@+id/shopLiveShortformCardTypeView"
        android:layout_width="match_parent"
        android:layout_height="custom height" />

    ShopLiveShortformVerticalTypeView

    세로 스크롤 레이아웃(격자형 목록 Large) 컬렉션을 노출할 화면에 다음과 같이 구성합니다. 고객사 xml에 ShopLiveShortformVerticalTypeView 를 추가하세요.

    <cloud.shoplive.sdk.shorts.ShopLiveShortformVerticalTypeView
        android:id="@+id/shopLiveShortformVerticalTypeView"
        android:layout_width="match_parent"
        android:layout_height="custom height" />

    ShopLiveShortformHorizontalTypeView

    가로 스크롤 레이아웃 컬렉션을 노출할 화면에 다음과 같이 구성합니다. 고객사 xml에 ShopLiveShortformHorizontalTypeView 를 추가하세요.

    <cloud.shoplive.sdk.shorts.ShopLiveShortformHorizontalTypeView
        android:id="@+id/shortsHorizontalType1View"
        android:layout_width="match_parent"
        android:layout_height="custom height" />

    ShopLiveShortformDetailTypeView

    상세화면 컬렉션을 노출할 화면에 다음과 같이 구성합니다. 고객사 xml에 ShopLiveShortformDetailTypeView 를 추가하세요.

    <cloud.shoplive.sdk.shorts.ShopLiveShortformDetailTypeView
        android:id="@+id/shortsDetailTypeView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


    View 속성 설정

    목록 view를 구성하고 view의 public function으로 속성을 설정할 수 있습니다.

    View 활성화

    view의 속성을 구성하고 submit() 함수를 호출하여 데이터를 로드합니다.

    submit() 함수를 호출하세요

    submit() 함수를 호출하지 않으면 데이터가 로드되지 않아 화면에 목록 view가 구성되지 않습니다.

    yourView.submit()

    컬렉션 내 상품 카드 레이아웃 설정

    카드 레이아웃을 설정합니다. (기본값: CARD_TYPE1)

    • CARD_TYPE0 : 컬렉션에 상품 카드 미노출

    • CARD_TYPE1 : 컬렉션에 카드형 상품 카드 노출

    • CARD_TYPE2 : 컬렉션에 원형 상품 카드 노출

    // CARD_TYPE0, CARD_TYPE1, CARD_TYPE2
    yourView.setViewType(type: ShopLiveShortform.CardViewType)

    자세한 예시는 아래 내용을 참고해주세요.

    • TYPE0

    • TYPE1

    • TYPE2

    태그 기반 컬렉션

    HashTag 단위로 검색을 할 수 있습니다. 

    • ShopLiveShortformTagSearchOperator.OR: HashTag 통합검색(기본값)

    • ShopLiveShortformTagSearchOperator.AND: HashTag 교차검색

    yourView.setHashTags(hashTags: List<String>?, tagSearchOperator: ShopLiveShortformTagSearchOperator)

    브랜드 기반 컬렉션

    브랜드 단위로 검색을 할 수 있습니다. (제목, 식별자 둘 다 검색)

    yourView.setBrands(brands: List<String>?)

    그룹 기반 컬렉션

    그룹 단위로 검색을 할 수 있습니다.

    yourView.setShortsCollectionId(shortsCollectionId: String?)

    무작위로 컬렉션 데이터 구성

    무작위 혹은 최신순으로 숏폼들을 보이게 설정합니다.

    • enableShuffle() : 숏폼을 무작위로 보여줍니다.

    • disableShuffle(): 숏폼을 최신 시간순으로 보여줍니다.

    yourView.enableShuffle() 
    yourView.disableShuffle()

    스냅 효과 설정

    스냅 효과를 사용하여 개별 콘텐츠 강조 여부를 설정합니다.

    • enableSnap(): 스냅 효과 설정

    • disableSnap(): 스냅 효과 해제 (기본값)

    yourView.enableSnap() 
    yourView.disableSnap()

    영상 재생 범위(가로 스크롤 전용)

    가로 스크롤에서 어떠한 view를 재생할 건지 선택할 수 있습니다.

    • PlayableType.First: 가시 영역의 가장 왼쪽 view만 재생 (기본값)

    • PlayableType.Center: 가시 영역의 중앙 view만 재생

    • PlayableType.All: 가시 영역에 보이는 모든 view들을 재생

    yourView.setPlayableType(type: ShopLiveShortform.PlayableType)

    영상 자동 재생 효과 설정

    view의 영상을 자동을 재생할지 설정합니다.

    • enablePlayVideos(): 영상을 재생한다. (기본값)

    • disablePlayVideos(): 영상 재생을 해제한다.

    yourView.enablePlayVideos()
    yourView.disablePlayVideos()

    응용하기

    Pager 구조에서 탭 간 이동 시, 현재 재생 중인 뷰에서 disablePlayVideos()를 호출하여 메모리를 해제하고, 되돌아갈 때 해당 뷰에 enablePlayVideos()를 다시 호출하면 클라이언트 앱의 효과적인 메모리 관리가 가능합니다.

    최상단으로 스크롤 하기

    최상단으로 스크롤 합니다.

    yourView.scrollToTop()

    와이파이 환경에서만 영상 재생되도록 설정

    와이파이 환경에서만 재생이 가능하게 할지 설정합니다.

    • true: wifi에서만 재생

    • false: 모든 네트워크에서 재생 (기본값)

    yourView.setPlayOnlyWifi(isEnabled : Boolean)

    아이템 간격 설정

    ViewHolder 들의 간격을 custom 설정합니다. 기본 간격은 default 설정되어 있습니다.

    • ShopLiveShortformCardTypeView

      • top: 32dp, bottom: 32dp, left: 32dp, right: 32dp

    • ShopLiveShortformVerticalTypeView

      • top: 16dp, bottom: 16dp, left: 16dp, right: 16dp

      • ViewHolder 사이 간격 8dp

    • ShopLiveShortformHorizontalTypeView

      • top: 16dp, bottom: 16dp, left: 16dp, right: 16dp

      • ViewHolder 사이 간격 8dp

    yourView.addItemDecoration(object : ItemDecoration() {
    	override fun getItemOffsets(
    		outRect: Rect,
    		view: View,
    		parent: RecyclerView,
    		state: RecyclerView.State
    	) {
        super.getItemOffsets(outRect, view, parent, state)
        parent.getChildAdapterPosition(view)
        val itemCount = parent.adapter?.itemCount ?: 0
        if (parent.getChildAdapterPosition(view) == 0) {
            outRect.top = 16.toDp(view.context).toInt()
            outRect.bottom = 16.toDp(view.context).toInt()
            outRect.left = 16.toDp(view.context).toInt()
            outRect.right = 4.toDp(view.context).toInt()
        } else if (parent.getChildAdapterPosition(view) == itemCount - 1) {
            outRect.top = 16.toDp(view.context).toInt()
            outRect.bottom = 16.toDp(view.context).toInt()
            outRect.left = 4.toDp(view.context).toInt()
            outRect.right = 16.toDp(view.context).toInt()
        } else {
            outRect.top = 16.toDp(view.context).toInt()
            outRect.bottom = 16.toDp(view.context).toInt()
            outRect.left = 4.toDp(view.context).toInt()
            outRect.right = 4.toDp(view.context).toInt()
        }
    	}
    })
    
    fun Int.toDp(context: Context): Float = TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        this.toFloat(),
        context.resources.displayMetrics
    )

    조회수 숨김 처리

    상단에 있는 영상을 본 횟수를 나타내는 view를 보여주게 할지 설정합니다. (기본값: visible)

    yourView.setVisibleViewCount(isVisible : Boolean)

    상품 개수 숨김 처리

    상품의 개수를 나타내는 view를 보여주게 할지 설정합니다. (기본값: visible)

    yourView.setVisibleProductCount(isVisible : Boolean)

    브랜드 숨김 처리

    브랜드를 보여주게 할지 설정합니다. (기본값: visible)

    yourView.setVisibleBrand(isVisible : Boolean)

    제목 숨김 처리

    제목을 보여주게 할지 설정합니다. (기본값: visible)

    yourView.setVisibleTitle(isVisible : Boolean)

    설명 숨김 처리

    내용을 보여주게 할지 설정합니다. (기본값:visible)

    yourView.setVisibleDescription(isVisible : Boolean)

    영상 radius 값 설정

    영상의 Radius 값을 설정합니다.

    • ShopLiveShortformCardTypeView: 16dp

    • ShopLiveShortformVerticalTypeView: 12dp

    • ShopLiveShortformHorizontalTypeView: 12dp

    yourView.setRadius(radius : Float)

    Placeholder 색상 설정

    Placeholder 값을 설정합니다. (기본값:CBCBCB)

    yourView.setCardBackgroundColor(@ColorInt colorInt: Int)

    진입경로 통계 추가

    진입 경로 통계를 측정할 수 있는 파라미터를 추가합니다.

    yourView.setReferrer(referrer : String?)

    핸들러 설정

    view에서 발생한 알림을 클라이언트에서 Handler 함수를 통해 전달받고 필요한 처리를 합니다.

    yourView.handler = object : ShopLiveShortformHandler() {
    	override fun onError(context: Context, error: ShopLiveCommonError) {
    		// Do something
    	}
    }


    DetailView 속성 설정

    특정 Shortform ID로 숏폼 상세 목록 구성

    Coroutine 사용

    detailView.setShortformIdsData(shortformIdsData: ShopLiveShortformIdsData, moreSuspendListener: ShopLiveShortformMoreSuspendListener)을 통해 숏폼 API로 받아온 shortformId를 이용해 playlist를 구성하고 순서대로 재생합니다.

    ShopLiveShortformIdsData

    Property name

    Type

    Description

    ids

    List<ShopLiveShortformIdData>?

    숏폼 ID를 통한 목록 구성 요소 (최대 30개)

    currentId

    String?

    목록중 현재 Focus 할 수 있는 목록

    referrer

    String?

    경로를 추적할 수 있는 값

    handler

    ShopLiveShortformHandler?

    Event handler

    ShopLiveShortformIdData

    Property name

    Type

    Description

    shortsId

    String

    숏폼 ID

    payload

    Map<String, Any?>?

    Custom payload

    ShopLiveShortformMoreSuspendListener

    Property name

    Type

    Description

    onMore

    ShopLiveShortformIdsMoreData?

    Coroutine을 활용하여 Pagination 목록 구성할 수 있는 function

    ShopLiveShortformIdsMoreData

    Property name

    Type

    Description

    ids

    List<ShopLiveShortformIdData>?

    숏폼 ID를 통한 목록 구성 요소 (최대 30개)

    hasMore

    Boolean?

    Pagination 가능 여부

    detailView.setShortformIdsData(ShopLiveShortformIdsData().apply {
        ids = listOf(ShopLiveShortformIdData("{YOUR_IDS}"))
        currentId = "{YOUR_CURRENT_ID}"
    }, ShopLiveShortformMoreSuspendListener {
        val moreResponse =
            kotlin.runCatching {
                "{YOUR_MORE_API_RESPONSE}"
            }.getOrNull() ?: return@ShopLiveShortformMoreSuspendListener null
        val ids = moreResponse.shortsList?.mapNotNull { it.shortsId }?.map { ShopLiveShortformIdData(it) } ?: emptyList()
        val hasMore = moreResponse.hasMore
        return@ShopLiveShortformMoreSuspendListener ShopLiveShortformIdsMoreData().apply {
            this.ids = ids
            this.hasMore = hasMore
        }
    })
    detailView.submit()

    Future 사용

    detailView.setShortformIdsData(shortformIdsData: ShopLiveShortformIdsData, moreFutureListener: ShopLiveShortformMoreFutureListener)을 통해 숏폼 API로 받아온 shortformId를 이용해 playlist를 구성하고 순서대로 재생합니다.

    ShopLiveShortformIdsData

    Property name

    Type

    Description

    ids

    List<ShopLiveShortformIdData>?

    숏폼 ID를 통한 목록 구성 요소 (최대 30개)

    currentId

    String?

    목록중 현재 Focus 할 수 있는 목록

    referrer

    String?

    경로를 추적할 수 있는 값

    handler

    ShopLiveShortformHandler?

    Event handler

    ShopLiveShortformIdData

    Property name

    Type

    Description

    shortsId

    String

    숏폼 ID

    payload

    Map<String, Any?>?

    Custom payload

    ShopLiveShortformMoreFutureListener

    Property name

    Type

    Description

    onMore

    Future<ShopLiveShortformIdsMoreData?>

    Future를 활용하여 Pagination 목록 구성할 수 있는 function

    ShopLiveShortformIdsMoreData

    Property name

    Type

    Description

    ids

    List<ShopLiveShortformIdData>?

    숏폼 ID를 통한 목록 구성 요소 (최대 30개)

    hasMore

    Boolean?

    Pagination 가능 여부

    detailView.setShortformIdsData(ShopLiveShortformIdsData().apply {
        ids = listOf(ShopLiveShortformIdData("{YOUR_IDS}"))
        currentId = "{YOUR_CURRENT_ID}"
    }, ShopLiveShortformMoreFutureListener {
        val task: Future<ShopLiveShortformIdsMoreData?> =
            Executors.newCachedThreadPool().submit {
                "{YOUR_MORE_API_RESPONSE}"
                ShopLiveShortformIdsMoreData().apply {
                    this.ids = listOf(ShopLiveShortformIdData("{YOUR_MORE_IDS}"))
                    this.hasMore = hasMore
                }
            }
        return@ShopLiveShortformMoreFutureListener task
    })
    detailView.submit()

    핸들러 설정

    detailView에서 발생한 알림을 클라이언트에서 Handler 함수를 통해 전달받고 필요한 처리를 합니다.

    ShopLiveShortform.setHandler(object : ShopLiveShortformHandler() {
    	override fun getOnClickProductListener(): ShopLiveShortformProductListener {
    	    return ShopLiveShortformProductListener { context, data, product ->
    	        // Something landing customer
        	}
    	}
    
    	override fun getOnClickBannerListener(): ShopLiveShortformUrlListener {
        	return ShopLiveShortformUrlListener { context, data, url ->
            	// Something landing customer
    	    }
    	}
    
    	override fun onEvent(context: Context, webView: ShopLiveShortformWebView?, command: String, payload: String?) {
    		// Do something
    	}
    
    	override fun onError(context: Context, error: ShopLiveCommonError) {
    		// Do something
    	}
    
    	override fun onShare(context: Context, data: ShopLiveShortformShareData) {
    		// Do something
    	}
    
    	override fun onCreate() {
    		// Do something
    	}
    
    	override fun onDestroy() {
    		// Do something
    	}
    
        open fun onShortsAttached(data: ShopLiveShortformData) {
            // Do nothing
        }
    
        open fun onShortsDetached(data: ShopLiveShortformData) {
            // Do nothing
        }
    })