shpongle2634 / react-native-kakao-links

React-Native Kakao Link Module
MIT License
28 stars 21 forks source link

안녕하세요. 질문글 하나 올립니다. #3

Closed HoYeongSong closed 5 years ago

HoYeongSong commented 5 years ago

안녕하세요. 올려주신 모듈 잘 사용하고 있습니다. 현재 기능은 다 잘 작동을 하는데 특정 글에서 공유하기 버튼을 눌러 카카오톡으로 카카오링크를 보낸 후에 '앱으로보기' 버튼을 누르면 특정 글로 다시 들어가는 것이 아니라 어플 메인화면이 뜨는데요. 이 부분을 혹시 어떤식으로 구현해야하는 지 알려주실 수 있나요?

type LinkObject={ webURL? :string, //optional mobileWebURL? :string, //optional androidExecutionParams?:string, //optional For Linking URL iosExecutionParams? :string, //optional For Linking URL };

이 부분에서 androidExecutionParams 값을 찾고 있는데 계속 막혀서 여기까지 글을 올리게 됐습니다.

답변 기다리고 있겠습니다..감사합니다.

shpongle2634 commented 5 years ago

안녕하세요. 질문주셔서 감사합니다. 질문 내용은 링크를 통해 보낸 글을, '앱에서 보기' 와 같은 버튼을 눌러 '상세페이지' 로 navigate 하는 것으로 볼 수 있습니다.

먼저 예시로, 1.exampleapp이라는 스키마를 가진 앱에서, 2.리스트에서 id 값이 3인 게시물을 카카오링크하고 3.카카오 링크를 받은 사용자는 링크를 눌러서 id가 3 게시물을 본다고 가정하겠습니다.

여기서 필요한것은 카카오 링크를 생성할때 androidExecutionParams, iosExecutionParams에 id=3 이라는 쿼리 스트링형태의 값을 넣으셔야 합니다. 예시는 아래와 같습니다.

const link ={
      androidExecutionParams : 'id=3',
      iosExecutionParams : 'id=3',
  };

이렇게 생성된 카카오 링크는 exampleapp://somepath?id=3 과 같은 url을 가지고 앱 메인화면을 로드하게 됩니다. 따라서 메인 컴포넌트는 url값을 보고, id=3 과 같은 param이 있는지 체크하고, 있다면 상세페이지로 route 해야합니다.

구현은 ios와 android 플랫폼 사이에 약간의 차이가 있습니다.

componentDidMount(){
    if (Platform.OS === 'android') { //안드로이드는 아래와 같이 initialURL을 확인하고 navigate 합니다.
      Linking.getInitialURL().then(url => {
        if(url) this.navigate(url); //
      });
    }else{ //ios는 이벤트리스너를 mount/unmount 하여 url을 navigate 합니다.
      Linking.addEventListener('url', this.handleOpenURL);
    }
  }
  componentWillUnmount() { 
    Linking.removeEventListener('url', this.handleOpenURL);
  }
 handleOpenURL = (event) => { //이벤트 리스너.
    this.navigate(event.url);
 }

navigate는 url을 파싱하고 route하는 메소드로 이루어집니다.

navigate = (url) =>{
    console.log(url); // exampleapp://somepath?id=3
    const paths = url.split('?'); // 쿼리스트링 관련한 패키지들을 활용하면 유용합니다.
    if(paths.length>1){ //파라미터가 있다
      const params= paths[1].split('&');
      let id;
      for(let i=0; i<params.length; i++){
        let param = params[i].split('=');// [0]: key, [1]:value
        if(param[0] ==='id'){
          id=Number(param[1]);//id=3
        }
      }
    //id 체크 후 상세페이지로 navigate 합니다.
    }
  }

제생각에는 이 코드는 최상위 레벨의 컴포넌트에 넣는것이 가장 좋을 것 같네요.. 헤더나, 탭바 같은..? 예를들어 앱이 새로 실행되는것이 아니라 다른 페이지를 보고있다가 앱 링크를 누른경우, 로딩화면과 같은 컴포넌트의 위 코드가 실행될 일이 없기 때문입니다.

HoYeongSong commented 5 years ago

안녕하세요. 질문주셔서 감사합니다. 질문 내용은 링크를 통해 보낸 글을, '앱에서 보기' 와 같은 버튼을 눌러 '상세페이지' 로 navigate 하는 것으로 볼 수 있습니다.

먼저 예시로, 1.exampleapp이라는 스키마를 가진 앱에서, 2.리스트에서 id 값이 3인 게시물을 카카오링크하고 3.카카오 링크를 받은 사용자는 링크를 눌러서 id가 3 게시물을 본다고 가정하겠습니다.

여기서 필요한것은 카카오 링크를 생성할때 androidExecutionParams, iosExecutionParams에 id=3 이라는 쿼리 스트링형태의 값을 넣으셔야 합니다. 예시는 아래와 같습니다.

const link ={
      androidExecutionParams : 'id=3',
      iosExecutionParams : 'id=3',
  };

이렇게 생성된 카카오 링크는 exampleapp://somepath?id=3 과 같은 url을 가지고 앱 메인화면을 로드하게 됩니다. 따라서 메인 컴포넌트는 url값을 보고, id=3 과 같은 param이 있는지 체크하고, 있다면 상세페이지로 route 해야합니다.

구현은 ios와 android 플랫폼 사이에 약간의 차이가 있습니다.

componentDidMount(){
    if (Platform.OS === 'android') { //안드로이드는 아래와 같이 initialURL을 확인하고 navigate 합니다.
      Linking.getInitialURL().then(url => {
        if(url) this.navigate(url); //
      });
    }else{ //ios는 이벤트리스너를 mount/unmount 하여 url을 navigate 합니다.
      Linking.addEventListener('url', this.handleOpenURL);
    }
  }
  componentWillUnmount() { 
    Linking.removeEventListener('url', this.handleOpenURL);
  }
 handleOpenURL = (event) => { //이벤트 리스너.
    this.navigate(event.url);
 }

navigate는 url을 파싱하고 route하는 메소드로 이루어집니다.

navigate = (url) =>{
    console.log(url); // exampleapp://somepath?id=3
    const paths = url.split('?'); // 쿼리스트링 관련한 패키지들을 활용하면 유용합니다.
    if(paths.length>1){ //파라미터가 있다
      const params= paths[1].split('&');
      let id;
      for(let i=0; i<params.length; i++){
        let param = params[i].split('=');// [0]: key, [1]:value
        if(param[0] ==='id'){
          id=Number(param[1]);//id=3
        }
      }
    //id 체크 후 상세페이지로 navigate 합니다.
    }
  }

제생각에는 이 코드는 최상위 레벨의 컴포넌트에 넣는것이 가장 좋을 것 같네요.. 헤더나, 탭바 같은..? 예를들어 앱이 새로 실행되는것이 아니라 다른 페이지를 보고있다가 앱 링크를 누른경우, 로딩화면과 같은 컴포넌트의 위 코드가 실행될 일이 없기 때문입니다.

몇일째 해답을 찾지 못했었는데 진심으로 감사드립니다..!! 정말 감사합니다!

HoYeongSong commented 5 years ago

말씀하신대로 해봤는데 여전히 해결을 못하고 있습니다..ㅠㅠ 제가 혹시 실수한 부분이 있을까요?

일단 어플이 처음 실행되는 index.js 부분에

componentDidMount() { if (Platform.OS === "android") { //안드로이드는 아래와 같이 initialURL을 확인하고 navigate 합니다. Linking.getInitialURL().then(url => { if (url) this.navigate(url); // }); } else { //ios는 이벤트리스너를 mount/unmount 하여 url을 navigate 합니다. Linking.addEventListener("url", this.handleOpenURL); } } componentWillUnmount() { Linking.removeEventListener("url", this.handleOpenURL); } handleOpenURL = event => { //이벤트 리스너. this.navigate(event.url); };

navigate = url => { console.log(url); // exampleapp://somepath?id=3 const paths = url.split("?"); // 쿼리스트링 관련한 패키지들을 활용하면 유용합니다. if (paths.length > 1) { //파라미터가 있다 const params = paths[1].split("&"); let id; for (let i = 0; i < params.length; i++) { let param = params[i].split("="); // [0]: key, [1]:value if (param[0] === "id") { id = Number(param[1]); //id=3 } } //id 체크 후 상세페이지로 navigate 합니다. } };

이렇게 넣었구요!

카카오링크 모듈을 조금 수정해서

const linkObject = { webURL: "https://developers.kakao.com/docs/android/kakaotalk-link", //optional mobileWebURL: "https://developers.kakao.com/docs/android/kakaotalk-link", //optional androidExecutionParams: "id=3", //optional For Linking URL iosExecutionParams: "shopId=1&itemId=24" //optional For Linking URL };

이런식으로 해놨는데 카카오링크를 누르면 어플 메인화면까지만 가고 그 뒤로는 잘 안되네요..ㅠ 혹시 제가 잘못 이해한 부분이 있을까요?

shpongle2634 commented 5 years ago
navigate = (url) =>{
    console.log(url); // exampleapp://somepath?id=3
    const paths = url.split('?'); // 쿼리스트링 관련한 패키지들을 활용하면 유용합니다.
    if(paths.length>1){ //파라미터가 있다
      const params= paths[1].split('&');
      let id;
      for(let i=0; i<params.length; i++){
        let param = params[i].split('=');// [0]: key, [1]:value
        if(param[0] ==='id'){
          id=Number(param[1]);//id=3
        }
      }
 //id 체크 후 상세페이지로 navigate 합니다. <- 이 부분 구현을 깜빡하신것 같습니다!
if(id&& id>-1){
   this.props.navigation.push("DetailPage" , { item_id : id });
}
// 위와 같이 부분에 상세페이지로 렌더링하는 함수를 직접 구현하셔야 합니다 :D
// 이 코드는 react-navigation 을 사용할 경우 예시 코드입니다. 
// id 값이 있는지 확인하고 원하는 페이지로 route 혹은 rendering 하시면 됩니다.
    }
  }
HoYeongSong commented 5 years ago

아..그렇군요! 제가 잘 몰라서 질문이 너무 많았네요.. 진심으로 감사드립니다! :)