Skip to content

Latest commit

ย 

History

History
419 lines (348 loc) ยท 11.9 KB

README.md

File metadata and controls

419 lines (348 loc) ยท 11.9 KB

react-native-kakao-links

React-Native Kakao Link Module

ํ•„๋…!

/android ํŒจํ‚ค์ง€ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

com.reactlibrary => co.jootopia.kakao.link

react-native-kakao-plus-friend ์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜์‹œ๋Š”๊ฒฝ์šฐ ํŒจํ‚ค์ง€๋ช… ์ค‘๋ณต์œผ๋กœ ๋นŒ๋“œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ์ด๋Ÿฐ ๊ฒฝ์šฐ ์ˆ˜๋™์œผ๋กœ ํŒจํ‚ค์ง€๋ช…์„ ๋ฐ”๊ฟ”์ฃผ์…”์•ผํ•ฉ๋‹ˆ๋‹ค..!

Note

์•ˆ๋…•ํ•˜์„ธ์š”. ์ˆ  1๋ณ‘์œผ๋กœ ๋ชจ๋‘๊ฐ€ ์–ด๊นจ์ถค์„ ์ถ”๊ฒŒํ•˜๋Š” '๊ฝ์•Œ' ์„œ๋น„์Šค๋ฅผ ์ค€๋น„์ค‘์ธ JOOTOPIA์ž…๋‹ˆ๋‹ค. RN์œผ๋กœ ์„œ๋น„์Šค๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ์ค‘ ์นด์นด์˜ค๋งํฌ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•˜์—ฌ ๋ณธ ๋ชจ๋“ˆ์„ ์ œ์ž‘ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ธฐ๋Šฅ ๋ฐ ์˜ค๋ฅ˜๊ฐ€ ์žˆ์œผ์‹œ๋ฉด ์ด์Šˆ๋ž€์— ๋‚จ๊ฒจ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์ฐธ๊ณ ํ•˜์‹ค ์‚ฌํ•ญ์œผ๋กœ๋Š” ๋ณธ๋ž˜ ํŒจํ‚ค์ง€ ์ด๋ฆ„์„ react-native-kakao-link ํŒจํ‚ค์ง€๋กœ ํ•˜๊ณ ์‹ถ์—ˆ์œผ๋‚˜ npm์— ๋“ฑ๋ก์ด ๋ถˆ๊ฐ€ํ•˜์—ฌ ํŒจํ‚ค์ง€๋ช…์„ react-native-kakao-links๋กœ ์ง€์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌํ•œ ํ”์ (?)์œผ๋กœ Android ํŒจํ‚ค์ง€ ๋ฐ IOS ํŒจํ‚ค์ง€ ๋ช…์€ RNKakaoLinks ๊ฐ€ ์•„๋‹Œ RNKakaoLink ์ž…๋‹ˆ๋‹ค. Manual installation ๋ฐ ์‚ฌ์šฉ์‹œ ์œ ์˜ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

Getting started

$ npm install react-native-kakao-links --save

๋น ๋ฅธ ์„ค์น˜

react-native link ๋ฅผ ์ด์šฉํ•˜์‹œ๋ฉด ๋น ๋ฅธ ์„ค์น˜๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

$ react-native link react-native-kakao-links

์ˆ˜๋™ ์„ค์น˜

์œ„ react-native link ๋ฅผ ์‚ฌ์šฉํ•˜์‹œ์ง€ ์•Š๋Š” ๋ถ„๋“ค์€ ๋ณธ ๋ชจ๋“ˆ์„ IOS, Android์— ์‚ฌ์šฉํ•˜๊ธฐ์œ„ํ•ด ์•„๋ž˜์™€ ๊ฐ™์€ ๋งํฌ ์ ˆ์ฐจ๋ฅผ ๊ฑฐ์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

iOS

  1. In XCode, in the project navigator, right click Libraries โžœ Add Files to [your project's name]
  2. Go to node_modules โžœ react-native-kakao-links and add RNKakaoLink.xcodeproj
  3. In XCode, in the project navigator, select your project. Add libRNKakaoLink.a to your project's Build Phases โžœ Link Binary With Libraries
  4. Run your project (Cmd+R)<

Android

  1. Open up android/app/src/main/java/[...]/MainActivity.java
  • Add import com.reactlibrary.RNKakaoLinkPackage; to the imports at the top of the file
  • Add new RNKakaoLinkPackage() to the list returned by the getPackages() method
  1. Append the following lines to android/settings.gradle:
    include ':react-native-kakao-links'
    project(':react-native-kakao-links').projectDir = new File(rootProject.projectDir, 	'../node_modules/react-native-kakao-links/android')
    
  2. Insert the following lines inside the dependencies block in android/app/build.gradle:
      compile project(':react-native-kakao-links')
    

Install KakaoSDK

IOS

์นด์นด์˜ค๋งํฌ ๊ณต์‹๊ฐ€์ด๋“œ https://developers.kakao.com/docs/ios/kakaotalk-link ๋ฅผ ์ฐธ๊ณ ํ•˜์…”์„œ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๊ธฐ์œ„ํ•œ KakaoSDK๋ฅผ ์„ค์น˜ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

Note: CocoaPod ์‚ฌ์šฉ์ค‘์ธ ๊ฒฝ์šฐ /ios/Podfile ์— pod 'KakaoOpenSDK'๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  pod install๋กœ Kakao SDK๋ฅผ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Android

์นด์นด์˜ค๋งํฌ ๊ณต์‹๊ฐ€์ด๋“œ https://developers.kakao.com/docs/android/kakaotalk-link ๋ฅผ ์ฐธ๊ณ ํ•˜์…”์„œ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๊ธฐ์œ„ํ•œ Kakao SDK๋ฅผ ์„ค์น˜ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

Usage

Object Type ์†Œ๊ฐœ

์นด์นด์˜ค๋งํฌ ๊ณต์‹ ๊ฐ€์ด๋“œ์— ์˜ํ•˜๋ฉด ์นด์นด์˜ค๋งํฌ๋Š” ๋ช‡๊ฐ€์ง€ ์ง€์ •๋œ ํ…œํ”Œ๋ฆฟ์„ ์ด์šฉํ•˜์—ฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ ๋ฉ”์‹œ์ง€๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜ Object Type์„ ์ด์šฉํ•˜์—ฌ ํ…œํ”Œ๋ฆฟ์„ ์†์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ Object Type์„ ๊ฐ€์ง€๊ณ  ๋ฉ”์‹œ์ง€ ํ…œํ”Œ๋ฆฟ์ด ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑ๋˜๋Š”์ง€๋Š” ๋‹ค์Œ ์„น์…˜์„ ์ฐธ์กฐํ•ด์ฃผ์„ธ์š”.

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


type ContentObject = {
  title     : string,     //required
  link      : LinkObject, //required
  imageURL  : string,     //required

  desc?       : string,   //optional
  imageWidth? : number,   //optional
  imageHeight?:number     //optional
}

type SocialObject ={
  likeCount?        :number,//optional
  commentCount?     :number,//optional
  sharedCount?      :number,//optional
  viewCount?        :number,//optional
  subscriberCount?  :number//optional
}

type ButtonObject = {
  title : string,//required
  link  : LinkObject,//required
}

type CommerceDetailObject ={
  regularPrice?       :number,  //required,
  discountPrice?      :number,  //optional
  discountRate?       :number,  //optional
  fixedDiscountPrice? :number   //optional
};

์นด์นด์˜ค๋งํฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†ก์€ ํ…œํ”Œ๋ฆฟ ์ข…๋ฅ˜์™€ ์ƒ๊ด€์—†์ด RNKakaoLink.link( options ); ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ options๋Š” ์•„๋ž˜ 1~7 ์˜ Template Type์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์ „์ฒด ์ƒ˜ํ”Œ์ฝ”๋“œ๋Š” /examples/TemplateExamples.js ๋ฅผ ์ฐธ์กฐํ•ด์ฃผ์„ธ์š”.

Note : ๊ณต์‹ ๋ฌธ์„œ์—๋Š” ๋ฒ„ํŠผ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋Š” buttonTitle ์˜ต์…˜์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋‚˜์™€์žˆ์œผ๋‚˜ sdk ์—์„œ ์ด๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” API๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์•„ ๋ช…์‹œํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. buttons ๋ฅผ ์ด์šฉํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

1. FeedTemplate

type FeedTemplate = {
        objectType    : 'feed',             //required
        content       : ContentObject,      //required
        social?       : SocialObject,       //optional
        buttons?      : Array<ButtonObject> //optional
 };
export default class TemplateExample extends Component {

  linkFeed = async () => {
    try{
      const options = {
        objectType:'feed',//required
        content:contentObject,//required
        social:socialObject,//optional
        buttons:[buttonObject]//optional
      };
      const response = await RNKakaoLink.link(options);
      console.log(response);

    }catch(e){
      console.warn(e);
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={this.linkFeed} style={styles.button}>
          <Text style={styles.buttonText}>Feed</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

2. ListTemplate

type ListTemplate = {
        objectType    :'list',                //required
        headerTitle   : string,               //required
        headerLink    : LinkObject,           //required
        contents      : Array<ContentObject>, //required
        buttons?      : Array<ButtonObject>   //optional
 };
export default class TemplateExample extends Component {

  linkList = async () => {
    try{
      const options = {
        objectType:'list',//required
        headerTitle:'๋ฆฌ์ŠคํŠธ ์ œ๋ชฉ',//required
        headerLink:linkObject,//required
        contents:[contentObject,contentObject],//required
        buttons:[buttonObject]//optional
      };
      const response = await RNKakaoLink.link(options);
      console.log(response);
    }catch(e){
      console.warn(e);
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={this.linkList} style={styles.button}>
          <Text style={styles.buttonText}>List</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

3. LocationTemplate

type LocationTemplate = {
        objectType    :'location',          //required
        content       : ContentObject,      //required
        address       : string,             //required
        addressTitle? : string,             //optional
        buttons?      : Array<ButtonObject> //optional
 };
export default class TemplateExample extends Component {

  linkLocation = async () => {
    try{
      const options = {
        objectType:'location',//required
        content:contentObject,//required
        address:'์‹ค์ œ ์ฃผ์†Œ',//required
        addressTitle:'์šฐ๋ฆฌ ์ง‘',//optional
        buttons:[buttonObject]//optional
      };
      const response = await RNKakaoLink.link(options);
      console.log(response);
    }catch(e){
      console.warn(e);
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={this.linkLocation} style={styles.button}>
          <Text style={styles.buttonText}>Location</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

4. CommerceTemplate

type FeedTemplate = {
        objectType    : 'feed',             //required
        content       : ContentObject,      //required
        commerce      : CommerceObject,     //required
        buttons?      : Array<ButtonObject> //optional
 };
export default class TemplateExample extends Component {

  linkCommerce = async () => {
    try{
      const options = {
        objectType:'commerce',//required
        content:contentObject,//required
        commerce:commerceDetailObject,//required
        // buttonTitle:'',//optional buttons๋ž‘ ์‚ฌ์šฉ ๋ถˆ๊ฐ€.
        buttons:[buttonObject]//optional
      };
      const response = await RNKakaoLink.link(options);
      console.log(response);
    }catch(e){
      console.warn(e);
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={this.linkCommerce} style={styles.button}>
          <Text style={styles.buttonText}>Commerce</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

5. TextTemplate

type TextTemplate = {
        objectType  : string,  //required
        text        : string,  //required
        link        : LinkObject,//required
        buttons?    : Array<ButtonObject>//optional
};
export default class TemplateExample extends Component {

  linkText = async () => {
    try{
      const options = {
        objectType:'text',//required
        text:'ํ…์ŠคํŠธ ์ž…๋ ฅ',//required
        link:linkObject,//required
        // buttonTitle:'',//optional buttons๋ž‘ ์‚ฌ์šฉ ๋ถˆ๊ฐ€.
        buttons:[buttonObject]//optional
      };
      const response = await RNKakaoLink.link(options);
      console.log(response);
    }catch(e){
      console.warn(e);
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={this.linkText} style={styles.button}>
          <Text style={styles.buttonText}>Text</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

6. Scrap

type Scrap = {
        objectType  : string,  //required
        url         : string,  //required
};
export default class TemplateExample extends Component {

  linkScrap = async () => {
    try{
      const options = {
        objectType:'scrap',//required
        url:'https://developers.kakao.com',//required
      };
      const response = await RNKakaoLink.link(options);
      console.log(response);
    }catch(e){
      console.warn(e);
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={this.linkScrap} style={styles.button}>
          <Text style={styles.buttonText}>Scrap</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

7. Custom

type CustomTemplate = {
        objectType    : 'feed',             //required
        templateId    : string,             //required
        templateArgs  : any,                //required
        buttons?      : Array<ButtonObject> //optional
 };
export default class TemplateExample extends Component {

  linkCustom = async () => {
    try{
      const options = {
        objectType:'custom',//required
        templateId:'13671',//required
        templateArgs:{
          title:'์ปค์Šคํ…€ ์ œ๋ชฉ',//Your Param
          desc:'์ปค์Šคํ…€ ์„ค๋ช…',//Your Param
        }
      };
      const response = await RNKakaoLink.link(options);
      console.log(response);
    }catch(e){
      console.warn(e);
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={this.linkCustom} style={styles.button}>
          <Text style={styles.buttonText}>Custom</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

TODO

Callback

์นด์นด์˜ค์Šคํ† ๋ฆฌ ๋งํฌ