아마 이것때문에 삽질을 엄청 많이들 하셨을거에요.
저의 경우는 nice기술담당자에게 이메일도 보내봤는데요.
돌아오는 답변은 form 데이터 parameter 들을 올바르게 전송했냐는 너무나 형식적인 답변들을 들었는데요.
디깅을 했을때, ios의 보안정책때문에 팝업이 안열린다는 얘기도 있었지만, 그것도 정답은 아니었어요.
보통 예제코드#1 처럼 진행을 하게될시에 ios에서 흰화면이 노출되게 됩니다.
그렇지만, 예제코드#2 하시게 된다면 nice본인인증 팝업화면이 정상적으로 동작할것입니다.
안되는 이유를 뇌피셜로 추측해보자면, RN 웹뷰화면에서 window.open을 실행하고 form에 데이터할당해주고, submit을 하는데요.
nice의 action url에 submit이 끝나고 target 팝업을 찾아서 nice본인인증 화면이 들어가야하는데,
저부분에서 코드라인이 순차적으로 바로 실행되는게 워낙빠르게 동작이되다보니 0점몇초 라도 제대로 싱크가 맞지않아서 그렇지 않을까 추측해보아요.
그리하여, if 조건절이 처리되기 전에 먼저 팝업을 띄워놓고 하니 정상적으로 nice 팝업이 동작합니다.
// 예제코드#1
const nice본인인증 = async () => {
const res = await fetch();
if (form && res.data) {
const { enc_data, integrity_value, token_version_id } = res.data;
window.open('업체페이지', 'nicePopup', 팝업옵션);
form.target = 'nicePopup';
form.enc_data.value = enc_data;
form.token_version_id.value = token_version_id;
form.integrity_value.value = integrity_value;
form.submit();
}
};
// 예제코드 #2
const nice본인인증 = async () => {
const res = await fetch();
window.open('', 'nicePopup', 팝업옵션);
if (form && res.data) {
const { enc_data, integrity_value, token_version_id } = res.data;
form.target = 'nicePopup';
form.enc_data.value = enc_data;
form.token_version_id.value = token_version_id;
form.integrity_value.value = integrity_value;
form.submit();
}
};
뭔가 논리적이고 정확하게 떨어지는 해답은 아니다보니, 좀 그렇긴하지만
앱 공통가이드에서도 팝업이 흰화면으로 뜨는경우, window.open을 실행하는 코드와 submit을 하는 코드의 함수를 각각 작성하여
호출을 하라고 되어있기도 합니다..!
변경전
function fnPopup(){
window.open('', 'popup',"'팝업설정정보'");
document.form.target = "popup";
document.form.action = "nice url";
document.form.submit();
}
변경 후
function fnPopup(){
window.open('업체페이지', 'popup.',"'팝업설정정보'");
}
팝업으로 호출 된 업체 페이지
function goNice(){
document.form.action = "nice url";
document.form.submit();
}
추가내용
// RN 웹뷰코드
const onShouldStartLoadWithRequest = (event: ShouldStartLoadRequest) => {
console.log('event url', event.url);
if (
event.url.startsWith('http://') ||
event.url.startsWith('https://') ||
event.url.startsWith('about:blank')
) {
return true;
}
...
// 나머지 코드
return false;
};
<WebView
...
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
/>
if (wrappedFormRef.current !== null) {
const form = wrappedFormRef.current.querySelector('form');
const left = screen.width / 2 - 500 / 2;
const top = screen.height / 2 - 800 / 2;
const option = `status=no, menubar=no, toolbar=no, resizable=no, width=500, height=600, left=${left}, top=${top}`;
if (form && res) {
const { enc_data, integrity_value, token_version_id } =
res?.value || {};
window.open('', '/nicePopup', option);
form.target = '/nicePopup'; target의 기본값은 _blank
form.enc_data.value = enc_data;
form.token_version_id.value = token_version_id;
form.integrity_value.value = integrity_value;
form.action = OUTER_LINKS.NICE_ENCRYPT.MAIN;
form.submit();
}
window.open코드 선언 위치와 상관없다.
빈URL을 줘도 상관없다.
form.target을 window.open시의 name과 맞춰준다.
window.open의 두번째 매개변수는 팝업의 name을 의미한다.
내가 아는 target은 _blank, _parent, _self ... 만 알고있었는데, 따로 저렇게 커스텀 타겟을 줄수있는건가 싶다.
참고로 target명 앞에 슬래시("/")를 안붙이면 동작이 안된다.
대신 RN코드에서 onShoudStartLoadWithRequest property가 꼭 정의되어 있어야한다.
이렇게 열리게된 ios에서의 본인인증 nice팝업은 사실 부모팝업이 아니라, 현재 나의 페이지 그자체이다.
그렇기에 웹코드에서 window.opner등의 부모팝업을 핸들링하는 코드는 동작하지 않게 된다.

'JavaScript > React-Native' 카테고리의 다른 글
| 디바이스 정보를 가져오는 Native Module 만들어보기 (0) | 2023.04.28 |
|---|---|
| React-Native NativeModules 네이티브 모듈 만들기 (0) | 2023.04.26 |
| [React-Native] 안드로이드 시뮬레이터에서 localhost 동작하기 / 안드로이드 adb reverse 명령 사용하기 (0) | 2023.03.27 |