디파이너리(애드브릭스) 연동하기 - 하이브리드 앱
팔로우시작하기
이 아티클에서는 하이브리드 앱에서 디파이너리(애드브릭스) SDK를 사용하기 위한 Javascript Interface 를 만드는 방법을 안내합니다.
[[인용:위험:작게]] 주의 : SDK 설치 및 초기화와 같은 기본 안내는 [연동하기 > SDKs] 의 문서들을 참고해주세요.
하이브리드 앱을 연동하는데 필요한 2개의 영역인 웹과 네이티브로 구분하여 안내를 합니다.
- WEB PAGE
- NATIVE
- ANDROID : JAVA
- ANDROID : KOTLIN
- iOS : SWIFT
WEB PAGE
웹에서 발생한 이벤트 정보를 NATIVE 로 전달하기 위해 스크립트 작업이 필요합니다.
For Android
웹에서 발생한 이벤트 정보를 Android Native 로 전달해야 합니다.
window.[interface_name].[method_name](var event_data);
위와 같은 형태로 호출하며, 예제에서는 다음과 같이 AdBrixRm의 주요 커머스 이벤트를 호출하였습니다.
window.adbrix.purchase(orderId, productId, productName, unitPrice, quantity, currencyCode, category);
* 전달되는 모든 정보는 url encoding 처리를 해야 합니다.
* [interface_name].[method_name] 과 같이 호출하여도 동작합니다.
For iOS
웹에서 발생한 이벤트 정보를 iOS Native로 전달해야 합니다.
window.location("[interface_name]://[method_name]?key=value");
위와 같은 방식으로 호출하며, 예제에서는 다음과 같이 AdBrixRm의 주요 커머스 이벤트를 호출하였습니다.
adbrix://purchase?orderId=orderid&productId=productid&productName=productname&unitPrice=price&quantity=quantity¤cyCode=currencycode&category=category
* 전달되는 모든 정보는 url encoding 처리를 해야 합니다.
Android Native : Java
웹에서 전달한 이벤트 정보를 수신하여 적절한 디파이너리(애드브릭스) api를 호출합니다.
인터페이스 등록
안드로이드 webview에 javascript interface handler 를 추가하여 웹에서 호출하는 자바스크립트 이벤트를 캐치하도록 구성합니다.
webView.addJavascriptInterface(new AdbrixRmHybridInterface(WebViewActivity.this), "adbrix");
* 위 예시의 "adbrix" 는 웹에서 호출되는 자바스크립트의 window.[interface_name].[method_name] 의 [interface_name] 과 반드시 동일해야 합니다.
인터페이스 구현
웹에서 발생한 구매 이벤트 정보가 전달된 것을 처리하는 인터페이스 구현 예시입니다.
public class AdbrixRmHybridInterface { public AdbrixRmHybridInterface(){ } @JavascriptInterface public void purchase(String orderId, String productId, String productName, double price, int quantity, String currencyCode, String category){ try { Log.d(LOG_TAG, "GET PURCHASE EVENT DATA FROM WEB WITH BELOW DATAS ::: " + " \n orderId :: " + orderId + "\n productId :: " + productId + "\n productName :: " + productName + "\n price :: " + price + "\n quantity :: " + quantity + "\n discount :: n/a" + "\n currencyCode :: " + currencyCode + "\n category :: " + category); /** * Create Product Model List For Purchased Products Details * */ ArrayList productModelArrayList = new ArrayList<>(); /** * Create Product Model With Product Details * */ AdBrixRm.CommerceProductModel productModel = new AdBrixRm.CommerceProductModel().setProductID(productId) .setProductName(productName) .setCategory(new AdBrixRm.CommerceCategoriesModel().setCategory(category)) .setPrice(price) .setQuantity(quantity) .setCurrency(AdBrixRm.Currency.getCurrencyByCurrencyCode(currencyCode)); /** * Put The Purchased Product Details Into Product Model List * */ productModelArrayList.add(productModel); /** * Store Purchase Event Details For Passing Data To Adbrix Remaster Back-end. * */ AdBrixRm.Common.purchase(orderId, productModelArrayList, 0.00, 0.00, AdBrixRm.CommercePaymentMethod.CreditCard); }catch (Exception e){ Log.e(LOG_TAG, "parameter error w/ " + e.getMessage()); } } }
Android Native : Kotlin
웹에서 전달한 이벤트 정보를 수신하여 적절한 디파이너리(애드브릭스) api를 호출합니다.
인터페이스 등록
안드로이드 webview에 javascript interface handler 를 추가하여 웹에서 호출하는 자바스크립트 이벤트를 캐치하도록 구성합니다.
webView.addJavascriptInterface(AbxJavascriptInterfaceBridge(this), "adbrixrm")
* 위 예시의 "adbrixrm" 는 웹에서 호출되는 자바스크립트의 [interface_name].[method_name] 의 [interface_name] 과 반드시 동일해야 합니다.
* 위 예시의 AbxJavascriptInterfaceBridge의 생성자는 예제 프로젝트의 구성을 위해서 activity context를 전달받도록 작성되었습니다.
인터페이스 구현
웹에서 발생한 구매 이벤트 정보가 전달된 것을 처리하는 인터페이스 구현 예시입니다.
class AbxJavascriptInterfaceBridge(private var mContext:Context) { @JavascriptInterface fun purchase(order_id:String, product_id : String, product_name:String, price:Double, quantity:Int, category:String, currency: String, discount:Double, deliveryCharge:Double, paymentMethod: Int ){ Toast.makeText(mContext, "Sample Purchase Called From Webview", Toast.LENGTH_SHORT).show() var sampleCategoryModel = AdBrixRm.CommerceCategoriesModel() // 예제에서는 웹에서 전달하는 카테고리 정보에 대해서 / 를 구분자로 하는 계층구조를 가진다. // 전달 받은 카테고리 문자열을 구분자를 이용하여 분리하고 AdBrixRm.CommerceCategoriesModel 에 담는다. var categoryArr = category.split("/") for (item in categoryArr) { sampleCategoryModel.setCategory(item) } // 웹에서 전달 받은 상품 상세 정보를 이용하여 AdBrixRm.CommerceProductModel 에 담는다. var sampleProductModel = AdBrixRm.CommerceProductModel() sampleProductModel.setProductID(product_id) .setProductName(product_name) .setPrice(price) .setQuantity(quantity) .setCategory(sampleCategoryModel) // 여러 개의 상품을 한번에 담는 경우를 지원하기 위해서 ArrayList 를 이용하여야 한다. var productArrayList = ArrayList() // 완성된 ProductModel을 ArrayList에 담는다. productArrayList.add(sampleProductModel) // 완성된 productArrayList와 나머지 정보를 이용하여 AbxCommerce.purcahse api를 호출한다. AbxCommon.purchase(order_id, productArrayList, discount ,deliveryCharge, AdBrixRm.CommercePaymentMethod.getMethodByMethodCode(paymentMethod)) Log.d("ABXRM_KOTILN_HYBRID", "ABXRM PURCHASE EVENT :: "+ "\n- sample_order_id : " + order_id + "\n- sample_product_id : " + product_id + "\n- sample_product_name : " + product_name + "\n- sample_price : " + price + "\n- sample_qauntity : " + quantity + "\n- sample_category : " + category + "\n- sample_discount : " + discount + "\n- sample_deliverty_charget : " + deliveryCharge + "\n- sample_payment_method : " + AdBrixRm.CommercePaymentMethod.getMethodByMethodCode(paymentMethod) ) } @JavascriptInterface fun product_view(product_id : String, product_name:String, price:Double, quantity:Int, category:String) { Toast.makeText(mContext, "Sample ProductView Called From Webview", Toast.LENGTH_SHORT).show() var sampleCategoryModel = AdBrixRm.CommerceCategoriesModel() // 예제에서는 웹에서 전달하는 카테고리 정보에 대해서 / 를 구분자로 하는 계층구조를 가진다. // 전달 받은 카테고리 문자열을 구분자를 이용하여 분리하고 AdBrixRm.CommerceCategoriesModel 에 담는다. var categoryArr = category.split("/") for (item in categoryArr) { sampleCategoryModel.setCategory(item) } // 웹에서 전달 받은 상품 상세 정보를 이용하여 AdBrixRm.CommerceProductModel 에 담는다. var sampleProductModel = AdBrixRm.CommerceProductModel() sampleProductModel.setProductID(product_id) .setProductName(product_name) .setPrice(price) .setQuantity(quantity) .setCategory(sampleCategoryModel) // 완성된 ProductModel을 이용하여 AbxCommerce.productView api 를 호출한다. AbxCommerce.productView(sampleProductModel) Log.d("ABXRM_KOTILN_HYBRID", "ABXRM PRODUCT_VIEW EVENT :: "+ "\n- sample_product_id : " + product_id + "\n- sample_product_name : " + product_name + "\n- sample_price : " + price + "\n- sample_qauntity : " + quantity + "\n- sample_category : " + category ) } @JavascriptInterface fun add_to_cart(product_id : String, product_name:String, price:Double, quantity:Int, category:String) { Toast.makeText(mContext, "Sample AddToCart Called From Webview", Toast.LENGTH_SHORT).show() var sampleCategoryModel = AdBrixRm.CommerceCategoriesModel() // 예제에서는 웹에서 전달하는 카테고리 정보에 대해서 / 를 구분자로 하는 계층구조를 가진다. // 전달 받은 카테고리 문자열을 구분자를 이용하여 분리하고 AdBrixRm.CommerceCategoriesModel 에 담는다. var categoryArr = category.split("/") for (item in categoryArr) { sampleCategoryModel.setCategory(item) } // 웹에서 전달 받은 상품 상세 정보를 이용하여 AdBrixRm.CommerceProductModel 에 담는다. var sampleProductModel = AdBrixRm.CommerceProductModel() sampleProductModel.setProductID(product_id) .setProductName(product_name) .setPrice(price) .setQuantity(quantity) .setCategory(sampleCategoryModel) // 여러 개의 상품을 한번에 담는 경우를 지원하기 위해서 ArrayList 를 이용하여야 한다. var productArrayList = ArrayList() // 완성된 ProductModel을 ArrayList에 담는다. productArrayList.add(sampleProductModel) // 완성된 ArrayList를 이용하여 AbxCommerce.addToCart api를 호출한다. AbxCommerce.addToCart(productArrayList) Log.d("ABXRM_KOTILN_HYBRID", "ABXRM ADD_TO_CART EVENT :: "+ "\n- sample_product_id : " + product_id + "\n- sample_product_name : " + product_name + "\n- sample_price : " + price + "\n- sample_quantity : " + quantity + "\n- sample_category : " + category ) } }
iOS Native
웹에서 전달한 이벤트 정보를 수신하여 적절한 디파이너리(애드브릭스) api를 호출합니다.
인터페이스 등록 및 구현(Swift)
webView delegate 로 전달되는 webView 이벤트 중에서 사전에 정의된 interface_name과 method_name으로 자바스크립트 인터페이스 호출 이벤트를 식별하도록 구현합니다.
아래는 웹에서 발생한 구매 이벤트 정보가 전달된 것을 처리하는 인터페이스 구현 예시입니다.
@available(iOS 8.0, *) func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { if let url = navigationAction.request.url, let schm = url.scheme, let funcName = url.host { if let dic = Utils.getURLParmaters(url) { if ("adbrix" == schm) { if (funcName.contains(Constants.FUNC_purchase) || funcName.contains(Constants.FUNC_viewList) || funcName.contains(Constants.FUNC_addToWishList) || funcName.contains(Constants.FUNC_share) || funcName.contains(Constants.FUNC_search) || funcName.contains(Constants.FUNC_productView) || funcName.contains(Constants.FUNC_addToCart) ) { var cateArr :Array = Array() if let cate = (dic[Constants.DIC_category] as? String) { let categories = cate.components(separatedBy: ".") for str in categories { if cateArr.count >= 5 { break } cateArr.append(str) } } else { if cateArr.count < 5 { cateArr.append("") } } if let productId = dic[Constants.DIC_productId], let productName = dic[Constants.DIC_productName], let price = dic[Constants.DIC_unitPrice], let quantity = dic[Constants.DIC_quantity], let currencyString = dic[Constants.DIC_currencyCode] { var arr : Array = Array() if let priceNum = (price as? NSString), let quantityNum = (quantity as? NSString) { let productModel = AdBrixRM.getInstance.createCommerceProductData( productId: productId as! String ,productName: productName as! String ,price: Double(priceNum.integerValue) ,quantity: quantityNum.integerValue ,discount: 0.00 ,currencyString: self.validCurreny(currencyString as! String) ,category: AdBrixRM.getInstance.createCommerceProductCategoryDataByArray(categoryArray: cateArr) ,productAttrsMap: nil ) arr.append(productModel) if funcName.contains(Constants.FUNC_purchase) { if let orderId = dic[Constants.DIC_orderId] { AdBrixRM.getInstance.commonPurchase( orderId: orderId as! String, productInfo: arr, discount: 0.00, deliveryCharge: 0.00, paymentMethod: AdBrixRM.getInstance.convertPayment(self.validPayment(Constants.ABXRM_PAYMENT[1] ?? "CreditCard")) ) } } } } } }