메인 메뉴로 바로가기
본문으로 바로가기
헥토데이터 개발자센터
연동 가이드
본문영역
연동 가이드
시작하기
FinpongPlusLibrary
Flow Chart
Android
iOS
Flutter
React Native
Error Code List
Library 다운로드
FinpongPlusLibrary
연동 가이드
Flow Chart
Android
iOS
Flutter
React Native
※ FinpongPlusLib를 적용 하시려면 먼저
ClientId와 Secure Code를 발급
받으셔야 합니다. --- # 1. 사전준비 ## 1.1 다운로드 및 프로젝트에 추가 다운로드한 압축파일을 해제하면 FinpongPlusLib.xcframework 폴더가 존재합니다. 해당 xcframework를 프로젝트에 추가하고 FinpongPlusLib를 사용할 타겟을 설정합니다. ## 1.2 프로젝트 설정 * 타켓을 선택 한 후, General => Frameworks, Libraries, and Embed Content 에 **FinpongPlusLib.xcframework** 를 추가 합니다. > ![img_ios-finpongplus-third-sdk-guide.png](./static/img/guide/1.2image.Framework.png) * min target 11.0 이상으로 설정 합니다. * Deployment Info > ![img_ios-webkit2-mintarget.png](./static/img/guide/1.2image.mintarget.png) ## 1.3 간편인증 설정 * info.plist 파일에 앱 스킴을 등록합니다. 이동할 앱 스킴 리스트를 확인하고 추가해주세요. 앱 스킴을 추가하는 방법은 이미지를 참고하세요 * 아래의 이미지를 참고하여 URL Schemes 에는 **해당 어플의 앱 스킴**(예:certfinpongapp)을 설정해 주세요.(간편인증에서 핀퐁플러스로 복귀를 위함) | 간편인증 기관 | 앱 스킴(App Scheme) | |---|:---:| | `네이버` | naversearchthirdlogin | | `핀퐁` | finpongapp | | `토스` | supertoss | | `PASS(SKT)` | tauthlink | | `PASS(KT)` | ktauthexternalcall | | `PASS(LG)` | upluscorporation | | `카카오` | kakaotalk | > ![img_ios-webkit2-schemes.png](./static/img/guide/1.3image.schemes_1.png) --- # 2. FinpongPlusLib 사용하기 ## 2.1 Library import 및 Delegate 채택 * Swift : 클래스 상단에 설정 ```swift import FinpongPlusLib class ViewController: UIViewController, FinpongPlusDelegate { ... } ``` * Objective-C : 헤더파일 상단에 설정 ```objective-c #import
@interface ViewController : UIViewController
{ ... } ``` (!)
**FinpongPlusLib**를 import
합니다. (!)
**FinpongPlusDelegate**를 채택
합니다. (!)
**Objective-C** 프로젝트인
경우 추가 **Build Settings - Packaging - Defines Module**을 **Yes**로 설정 ## 2.2 FinpongPlusScreen 정보 설정 및 실행 * Swift ```swift // 버튼 이벤트 시 FinpongPlusScreen 실행 @IBAction func actionFinPongPlusStart(_ sender: Any) { finpongPlus = FinpongPlusScreen() // initialize finpongPlus.finpongPlusDelegate = self // FinpongPlus 델리게이트 설정 finpongPlus.modalPresentationStyle = .fullScreen // 전체 화면으로 설정 /* * Codef에서 발급받은 토큰을 입력해 주세요. */ finpongPlus.codefToken = "codef에서 발급받은 토큰을 입력해 주세요." finpongPlus.mode = Mode.STAGING // 모드설정 finpongPlus.entry = "0" // 엔트리설정(0: 기본, 1,2,3..: 설정) finpongPlus.log = false // 로그출력설정 print("FinpongPlus Version :: \(finpongPlus.version)") // FinpongPlus 버전정보 // 아래 예시를 참고하여 finpongplus 화면을 띄우고 싶은 방식에 맞게 실행합니다. // navigationController?.pushViewController(finpongPlus, animated: true) present(finpongPlus, animated: true, completion: nil) // FinPongPlus 뷰 컨트롤러를 실행합니다. } ``` * Objective-C ```objective-c // 버튼 이벤트 시 FinpongPlusScreen 실행 - (IBAction)actionFinPongPlusStart:(id)sender { _finpongPlusScreen = [[FinpongPlusScreen alloc] init]; // initialize _finpongPlusScreen.finpongPlusDelegate = self; // FinPongPlus 델리게이트 설정 _finpongPlusScreen.modalPresentationStyle = UIModalPresentationFullScreen; // 전체 화면으로 설정 /* * Codef에서 발급받은 토큰을 입력해 주세요. */ _finpongPlusScreen.codefToken = @"Codef에서 발급받은 토큰을 입력해 주세요."; _finpongPlusScreen.mode = ModeSTAGING; // 모드설정 _finpongPlusScreen.entry = @"0"; // 엔트리설정(0: 기본, 1,2,3..: 설정) _finpongPlusScreen.log = false; // 로그출력설정 NSLog(@"FinpongPlus Version >>> %@", _finpongPlus.version); // FinpongPlus 버전정보 [self presentViewController:_finpongPlusScreen animated:YES completion:nil]; // FinpongPlusScreen 뷰컨트롤러를 실행합니다. } ``` (!) **mode**: SAMPLE, STAGING, RELEASE 3가지 모드를 설정 가능합니다.. (!) **codefToken**: Backend에서 받은 Token를 설정합니다. (!) **entry**: 핀퐁플러스 시작 페이지를 설정합니다. (0: 기본, 1,2,3..: 설정) (!) **log**: 핀퐁플러스 로그 출력 여부를 설정합니다. (!) **version**: 핀퐁플러스 버전 정보. | entry | 진입 페이지 | 예시 | |---|:---:|---| | `"0"` | 기본(default) 페이지 | 업권 메인페이지 (마이보험, 마이투자) | | `"1"` | 설정된 커스텀 페이지 | 마이데이터 연동관리 페이지 | ## 2.3 mode 설명 | mode | 내 용 | |---|:---:| | `SAMPLE` | Sample Page (샘플 화면) | | `STAGING` | Staging Page (개발 진행 시) | | `RELEASE` | Product Page (운영 시) | --- # 3. FinpongPlusDelegate 구현 ## 3.1 FinpongPlusScreen 종료 * Swift ```swift func onCloseScreen(finpongPlusScreen: FinpongPlusScreen) { // 아래 예시를 참고하여 FinpongPlusScreen 를 띄운 방식에 맞게 종료합니다. finpongPlusScreen.dismiss(animated: true, completion: nil) } ``` * Objective-C ```objective-c - (void)onCloseScreenWithFinpongPlusScreen:(FinpongPlusScreen * _Nonnull)finpongPlusScreen { // FinpongPlusScreen 뷰컨트롤러를 종료합니다. [finpongPlusScreen dismissViewControllerAnimated:YES completion:nil]; } ``` ## 3.2 사설인증서 호출 앱이 미설치된 경우의 예외 처리를 구현해야 합니다. | 간편인증 기관 | type(String) | appId | |---|:---:|---| | `네이버` | `1` | `393499958` | | `토스` | `3` | `839333328` | | `핀퐁` | `4` | `1611667407` | | `PASS(SKT)` | `5` | `1141258007` | | `PASS(KT)` | `6` | `1134371550` | | `PASS(LG)` | `7` | `1147394645` | | `카카오` | `9` | `362057947` | * Swift ```swift func onOpenURIScheme(finpongPlusScreen: FinpongPlusScreen, type: String, appScheme: String) { // 요청한 간편인증 앱 스킴을 통해 디바이스 내에 설치되어 있는 간편인증 기관 앱을 실행시켜 간편인증 진행을 시작합니다. // TODO: 아래 예시 구현부를 참고하여 앱연동을 진행하세요. guard let schemeURL = URL(string: "\(appScheme)") else { return } if UIApplication.shared.canOpenURL(schemeURL){ print(" onOpenURIScheme schemeURL(\(schemeURL))") UIApplication.shared.open(schemeURL, options: [:], completionHandler: { (bool) -> Void in guard bool else { self.showMessage("앱을 실행하는데 실패 하였습니다.") return } }) } else { // MARK: 미설치된 앱이거나, Scheme을 못 찾는 경우에 실행됩니다. /* * info.plist - LSApplicationQueriesSchemes 옵션에 해당 스킴값이 등록되어있지 않은 경우에도 실행됩니다. * ex) appScheme에서 '://' 이전 값이 등륵되어 있어야 합니다. 네이버의 경우 naversearchthirlogin 값이 추가되어야 합니다. */ // TODO: 미설치된 앱인경우 appstore 연결하셔야 합니다. ( 예시 ) // type (1: 네이버, 3: 토스, 4: 핀퐁, ... ) let store = "itms-apps://itunes.apple.com/app/id" var appID = "" switch type { case "1": appID = "393499958" // 네이버 case "3": appID = "839333328" // 토스 case "4": appID = "1611667407" // 핀퐁 default: appID = "" } guard let storeUrl = URL(string: "\(store)\(appID)") else { return } if UIApplication.shared.canOpenURL(storeUrl) { UIApplication.shared.open(storeUrl, options: [:], completionHandler: nil) } } } ``` * Objective-C ```objective-c - (void)onOpenURISchemeWithFinpongPlusScreen:(FinpongPlusScreen * _Nonnull)finpongPlusScreen type:(NSString * _Nonnull)type appScheme:(NSString * _Nonnull)appScheme { // 요청한 간편인증 앱 스킴을 통해 디바이스 내에 설치되어 있는 간편인증 기관 앱을 실행시켜 간편인증 진행을 시작합니다. // TODO: 아래 예시 구현부를 참고하여 앱연동을 진행하세요. NSURL *schemeURL = [NSURL URLWithString:appScheme]; if ([[UIApplication sharedApplication] canOpenURL:schemeURL]) { NSLog(@"Scheme : %@", schemeURL); [[UIApplication sharedApplication] openURL:schemeURL options:@{} completionHandler:^(BOOL success) { NSLog(@"Open %@: %d",schemeURL,success); }]; } else { // MARK: 미설치된 앱이거나, Scheme을 못 찾는 경우에 실행됩니다. // TODO: 미설치된 앱인경우 appstore 연결하셔야 합니다. ( 예시 ) // type (1: 네이버, 3: 토스, 4: 핀퐁, ... ) /* * info.plist - LSApplicationQueriesSchemes 옵션에 해당 스킴값이 등록되어있지 않은 경우에도 실행됩니다. * ex) appScheme에서 :// 이전 값이 등륵되어 있어야 합니다. 네이버의 경우 naversearchthirlogin 값이 추가되어야 합니다. */ NSLog(@"앱을 실행할 수 없습니다."); } } ``` ## 3.3 FinpongPlus Custom Action 호출 codef(FinpongPlus)와 사용하기로 협의 후 정의된 Action 호출 | pageId | param | 설명 | |---|:---:|---| | `FD-001` | `다운로드url` | `파일 다운로드 Action` | | `PA-001` | `SHOW or HIDE` | `고객사에서 제작한 업로드 팝업 호출 Action` | | `IV-001` | `SHOW or HIDE` | `라이브러리 호출후 최초 화면 로딩 전까지 표시될 안내용 View` | | `VV-001` | `SHOW or HIDE` | `Custom View Visibility` | * Swift ```swift func onCustomAction(finpongPlusScreen: FinpongPlusScreen, pageId: String, param: String) { print(" pageId : \(pageId) param : \(param)") if pageId == "IV-001" { // param SHOW or HIDE initView.isHidden = (param == "HIDE") } else if pageId == "VV-001" { // param SHOW or HIDE customView.isHidden = (param == "HIDE") } else if pageId == "FD-001" { let downloadUrl = param // TODO: 파일 다운로드 구현 var testData: [String: Any] = ["": ""] /* var testData: [String: Any] = [ "isUpload" : false, // 업로드 여부 N "uploadRes" : "", "uploadMsg" : "", "isAgree" : "Y" // 동의 여부 Y ] var testData: [String: Any] = [ "isUpload" : true, // 업로드 여부 Y "uploadRes" : "success", // 업로드 성공 여부 코드 : 성공(success) /실패(fail) "uploadMsg" : "업로드 성공하였습니다.", // 업로드 결과 메세지 (성공, 실패 메세지) "isAgree" : "Y" ] */ var jsonString = "[testData] ->jsonString으로 변환" finpongPlusScreen.runJavaScript(scriptName: "scriptName", param: jsonString) } else if (pageId == "PA-001") { // TODO: 업로드 팝업 노출 여부를 설정한다. ( param SHOW or HIDE ) if param == "SHOW" { // 업로드 팝업 호출 } else if param == "HIDE" { // 업로드 팝업 닫기 } } else if pageId == "ACT1000" { // FinpongPlus ACT1000 } ``` * Objective-C ```objective-c - (void)onCustomActionWithFinpongPlusScreen:(FinpongPlusScreen *)finpongPlusScreen pageId:(NSString *)pageId param:(NSString *)param { NSLog(@"onCustomAction Call"); if ([pageId isEqual: @"IV-001"]) { // TODO: init View 의 hidden 여부를 설정한다. ( param SHOW or HIDE ) } else if ([pageId isEqual: @"VV-001"]) { // TODO: Custom View 의 hidden 여부를 설정한다. ( param SHOW or HIDE ) } else if ([pageId isEqual: @"FD-001"]) { // TODO: 파일 다운로드 구현 NSMutableDictionary *testData = [[NSMutableDictionary alloc] init]; [testData setObject:@"false" forKey:@"isUpload"]; [testData setObject:@"" forKey:@"uploadRes"]; [testData setObject:@"" forKey:@"uploadMsg"]; [testData setObject:@"Y" forKey:@"isAgree"]; NSString *jsonString = @"testData > jsonString으로 변환"; [_finpongPlus runJavaScriptWithScriptName:@"" param:@""]; } else if ([pageId isEqual: @"PA-001"]) { // TODO: 업로드 팝업 노출 여부를 설정한다. ( param SHOW or HIDE ) } else if ([pageId isEqual: @"ACT1000"]) { } } ``` (!) **ACT1000**: FinpongPlus 와 pageId 를 ACT1000 으로 정의 한 경우. ( 예시 ) --- # 4. Custom View 설정하기 FinpongPlus 가 present 되면 Custom View 추가해준다. 아래 예시를 참고하여 Custom View 를 설정한다. 모든 화면에서 보여지는 것이 아니라면 Custom View 의 **isHidden** 값을 **true** 로 설정한다. CustomView 의 isHidden 변경은 **3.3 FinpongPlus Custom Action 호출** 부분을 참고하세요. * Swift ```swift // 핀퐁플러스 호출이 완료되면 커스텀뷰를 만드는 함수를 실행한다. present(finpongPlus, animated: true) { self.makeInitView() self.initCustomView() } // TODO: Custom View 및 UITapGestureRecognizer 설정 (예시) /** ex) 라이브러리호출후 최초 화면 로딩 전까지 표시될 안내용 View */ let initView: UIView = UIView() private func makeInitView() { if finpongPlus.view.subviews.contains(initView) { return } finpongPlus.view.addSubview(initView) initView.isHidden = false initView.backgroundColor = UIColor.blue initView.translatesAutoresizingMaskIntoConstraints = false initView.widthAnchor.constraint(equalToConstant: 200).isActive = true initView.heightAnchor.constraint(equalToConstant: 200).isActive = true initView.centerXAnchor.constraint(equalTo: finpongPlus.view.centerXAnchor).isActive = true initView.centerYAnchor.constraint(equalTo: finpongPlus.view.centerYAnchor).isActive = true } // CustomView let customView: UIView = UIView() private func initCustomView() { if finpongPlus.view.subviews.contains(customView) { return } finpongPlus.view.addSubview(customView) customView.isHidden = true customView.backgroundColor = UIColor.black customView.translatesAutoresizingMaskIntoConstraints = false customView.heightAnchor.constraint(equalToConstant: 60).isActive = true customView.leadingAnchor.constraint(equalTo: finpongPlus.view.leadingAnchor, constant: 30).isActive = true customView.bottomAnchor.constraint(equalTo: finpongPlus.view.bottomAnchor, constant: -50).isActive = true customView.trailingAnchor.constraint(equalTo: finpongPlus.view.trailingAnchor, constant: -30).isActive = true customView.isUserInteractionEnabled = true let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:))) customView.addGestureRecognizer(tapGesture) } @objc func handleTap(sender: UITapGestureRecognizer) { print("tap") } ``` * Objective-C ```objective-c // 핀퐁플러스 호출이 완료되면 커스텀뷰를 만드는 함수를 실행한다. [self presentViewController:_finpongPlus animated:YES completion:^{ [self makeInitView]; [self makeCustomView]; }]; UIView *initView; - (void) makeInitView { initView = [[UIView alloc] init]; initView.backgroundColor = [UIColor blueColor]; [initView setTranslatesAutoresizingMaskIntoConstraints:NO]; [_finpongPlus.view addSubview:initView]; NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:initView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:200]; NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:initView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:200]; NSLayoutConstraint *centerX = [NSLayoutConstraint constraintWithItem:initView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_finpongPlus.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]; NSLayoutConstraint *centerY = [NSLayoutConstraint constraintWithItem:initView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:_finpongPlus.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]; [_finpongPlus.view addConstraints:@[centerX, centerY]]; [initView addConstraints:@[height, width]]; } UIView *customView; - (void) makeCustomView { customView = [[UIView alloc] init]; customView.backgroundColor = [UIColor brownColor]; [customView setHidden:YES]; [customView setTranslatesAutoresizingMaskIntoConstraints:NO]; [_finpongPlus.view addSubview:customView]; NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:customView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:300]; NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:customView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:50]; NSLayoutConstraint *centerX = [NSLayoutConstraint constraintWithItem:customView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_finpongPlus.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]; NSLayoutConstraint *bottom = [NSLayoutConstraint constraintWithItem:customView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:_finpongPlus.view attribute:NSLayoutAttributeBottom multiplier:1 constant:0]; [_finpongPlus.view addConstraints:@[centerX, bottom]]; [customView addConstraints:@[height, width]]; } ``` --- # 5. FinpongPlus Script 호출 기존에 생성된 FinpongPlusScreen 인스턴스에서 필요시 runJavaScript를 실행 ``` var testData: [String : Any] = ["data1": 1, "data2": true] var jsonString = /*jsonString으로 변환*/ finpongPlusScreen.runJavaScript(scriptName: "scriptName", param: jsonString) ``` --- # 6. 파일 다운로드 / 업로드 # * 파일다운로드 & 업로드 가이드 - 사전 작업 : 업로드 팝업(업로드 동의/비동의 선택 팝업)을 고객사에서 제작합니다. * 웹뷰 내에서 파일데이터를 다운받고, 업로드 처리 후 업로드 결과값을 핀퐁플러스로 전달합니다. ## 1. onCustomAction pageId값이 PA-001로 들어왔을때 고객사 업로드 팝업을 호출합니다. ## 2. 고객사 업로드 팝업에서 동의 선택시 동의여부값을 전달합니다. finpongPlus의 fileDataConnect 함수 호출 * 다운로드 한 데이터가 전달됩니다. (pageId : FD-001) ``` var testData: [String: Any] = [ "isUpload" : false, // 업로드 여부 N "uploadRes" : "", "uploadMsg" : "", "isAgree" : "Y" // 동의 여부 Y ] var jsonString = /*jsonString으로 변환*/ finpongPlusScreen.runJavaScript(scriptName: "scriptName", param: jsonString) ``` ## 3. 다운로드 데이터를 받아 고객사에서 업로드 처리 후 업로드 결과값을 전달합니다. finpongPlus의 fileDataConnect 함수 호출 ``` var testData: [String: Any] = [ "isUpload" : true, // 업로드 여부 Y "uploadRes" : "success", // 업로드 성공 여부 코드 : 성공(success) /실패(fail) "uploadMsg" : "업로드 성공하였습니다.", // 업로드 결과 메세지 (성공, 실패 메세지) "isAgree" : "Y" ] var jsonString = /*jsonString으로 변환*/ finpongPlusScreen.runJavaScript(scriptName: "scriptName", param: jsonString) ```
맨위로 이동