{"_id":"@app-emotion/react-native-naver-login","name":"@app-emotion/react-native-naver-login","dist-tags":{"latest":"3.0.0-rc.2"},"versions":{"3.0.0-rc.2":{"name":"@app-emotion/react-native-naver-login","version":"3.0.0-rc.2","description":"React Native Module for Naver Login","main":"index.js","postinstall":"dooboolab-welcome postinstall","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"tsc && tsc -p ./plugin && flowgen index.d.ts -o index.js.flow","flow":"flow","lint":"eslint -c .eslintrc.js 'index.ts'","validate":"npm run lint && npm run test:typescript && npm run test:flow && npm run test"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/react-native-seoul/react-native-naver-login.git"},"keywords":["react-native","naver","네아로","네이버","react-native-seoul","dooboolab","naver-login"],"author":{"name":"dooboolab, Jongwoo Moon"},"license":"MIT","peerDependencies":{"react":"*","react-native":"*"},"dependencies":{"dooboolab-welcome":"^1.3.2"},"devDependencies":{"@dooboo/eslint-config-react-native":"^1.0.3","@types/react":"^17.0.0","@types/react-native":"^0.67.3","eslint":"^8.25.0","flow-bin":"^0.190.0","flowgen":"^1.20.1","typescript":"^4.8.4","prettier":"^2.7.1","@babel/plugin-syntax-flow":"^7.18.6","@babel/plugin-transform-react-jsx":"^7.19.0","@babel/core":"^7.19.3","eslint-plugin-jest":"^27.1.3","jest":"^29.2.1","expo-module-scripts":"^3.0.7"},"types":"./index.d.ts","gitHead":"c7b767fc82b99cdd8b5bfbede4ae35e0e1fb75de","bugs":{"url":"https://github.com/react-native-seoul/react-native-naver-login/issues"},"homepage":"https://github.com/react-native-seoul/react-native-naver-login#readme","_id":"@app-emotion/react-native-naver-login@3.0.0-rc.2","_nodeVersion":"19.8.1","_npmVersion":"9.5.1","dist":{"integrity":"sha512-v4SZRxyvHaghASqfXzMLTfdJXnDZ+s52iHQ1VQYZhkUTFi8iKZJuTz4iFR25tlxIlA7sxbqIS4ZZRM/G47uhWQ==","shasum":"3f059997ad0f804d11a95a1aa22646ef9727bbdb","tarball":"https://registry.npmjs.org/@app-emotion/react-native-naver-login/-/react-native-naver-login-3.0.0-rc.2.tgz","fileCount":25,"unpackedSize":113367,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGUCHl9lqJ9Fm0Ls020g3aX0QHfCLQ1hp6NZ5aXd/GnDAiAB61wbpO/26hcln2g10eTdVx+yflPVSEnovnGRG/126Q=="}]},"_npmUser":{"name":"jeongshin","email":"sjeong1127@gmail.com"},"directories":{},"maintainers":[{"name":"jeongshin","email":"sjeong1127@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-native-naver-login_3.0.0-rc.2_1685778987308_0.2774663112663607"},"_hasShrinkwrap":false}},"time":{"created":"2023-06-03T07:56:27.222Z","3.0.0-rc.2":"2023-06-03T07:56:27.505Z","modified":"2023-06-03T07:56:27.743Z"},"maintainers":[{"name":"jeongshin","email":"sjeong1127@gmail.com"}],"description":"React Native Module for Naver Login","homepage":"https://github.com/react-native-seoul/react-native-naver-login#readme","keywords":["react-native","naver","네아로","네이버","react-native-seoul","dooboolab","naver-login"],"repository":{"type":"git","url":"git+https://github.com/react-native-seoul/react-native-naver-login.git"},"author":{"name":"dooboolab, Jongwoo Moon"},"bugs":{"url":"https://github.com/react-native-seoul/react-native-naver-login/issues"},"license":"MIT","readme":"# @react-native-seoul/naver-login\n\n[![npm version](http://img.shields.io/npm/v/@react-native-seoul/naver-login.svg?style=flat-square)](https://npmjs.org/package/@react-native-seoul/naver-login)\n[![downloads](http://img.shields.io/npm/dm/@react-native-seoul/naver-login.svg?style=flat-square)](https://npmjs.org/package/@react-native-seoul/naver-login)\n[![license](http://img.shields.io/npm/l/@react-native-seoul/naver-login.svg?style=flat-square)](https://npmjs.org/package/@react-native-seoul/naver-login)\n\nReact Native 네이버 로그인 라이브러리 입니다.\n\n### Supported platforms\n\n![Android](https://img.shields.io/badge/Android-3DDC84?style=for-the-badge&logo=android&logoColor=white)\n![iOS](https://img.shields.io/badge/iOS-000000?style=for-the-badge&logo=ios&logoColor=white)\n\n### Supported typing\n\n- TypeScript\n- Flow\n\n<img src=\"https://user-images.githubusercontent.com/33388801/196834333-69841305-ebd2-4b59-b02b-b079aafd7523.gif\" width=400 />\n\n## Installation\n\n❗️ `2.x` 버전은 [2.x branch](https://github.com/react-native-seoul/react-native-naver-login/tree/2.x) 의 설치 가이드와 사용법을 따라주세요.\n\n\n```shell\n# npm\nnpm install @react-native-seoul/naver-login --save\n\n# yarn\nyarn add @react-native-seoul/naver-login\n```\n\n### RN version >= `0.60` \n\n- Auto Linking 이 적용됩니다.\n- iOS의 경우 추가적으로 Cocoapods 설치가 필요합니다.\n\n```shell\ncd ios && pod install\n```\n\n### RN version < `0.60`\n\n- `0.60` 미만의 React Native를 사용중이시라면 [Manual Linking Guide](./README-manual-linking.md)를 참고해주세요.\n\n\n### 추가 작업 - iOS ❗️Important\n\n#### 1. Launch Service Queries Schemes 추가\n\n로그인 시에 네이버 앱을 실행시키기 위해 [Launch Services Queries Schemes](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html) 를 등록해주어야 합니다.\n\n`Info.plist` 파일안에 다음과 같은 항목을 추가합니다. \n\n- `naversearchapp`\n- `naversearchthirdlogin`\n\n이미 `LSApplicationQueriesSchemes` 가 항목으로 추가되어 있다면, `<array>` 안에 두 가지만 더 추가해주세요.\n\n```\n<key>LSApplicationQueriesSchemes</key>\n<array>\n  <string>naversearchapp</string>\n  <string>naversearchthirdlogin</string>\n</array>\n```\n\n![image](https://user-images.githubusercontent.com/33388801/196834997-40ca2368-50e6-45cb-9b68-2cf5307fd792.png)\n\n#### 2. custom URL scheme 추가\n\n네이버 로그인이 완료된 뒤 다시 우리의 앱으로 돌아오기 위해 `URL Scheme`를 `Info.plist` 에 정의해주어야 합니다.\n\n아래 코드들에서 `{{ CUSTOM URL SCHEME }}`는 커스텀하게 정의할 우리 앱에 사용될 URL scheme라고 생각하시면 됩니다.\n\n주의할 점은 다음과 같습니다.\n\n- 네이버 개발자 콘솔에 기입한 `URL Scheme`와 동일해야 합니다.\n- `login` 함수 호출시에 `serviceUrlScheme` 로 동일하게 전달해주어야 합니다.\n- TODO 설명 및 이미지 추가\n\n대략 다음과 같이 `Info.plist`에 입력되게 됩니다.\n```\n<key>CFBundleURLTypes</key>\n<array>\n\t<dict>\n\t\t<key>CFBundleTypeRole</key>\n\t\t<string>Editor</string>\n\t\t<key>CFBundleURLName</key>\n\t\t<string>naver</string>\n\t\t<key>CFBundleURLSchemes</key>\n\t\t<array>\n\t\t\t<string>{{ CUSTOM URL SCHEME }}</string>\n\t\t</array>\n\t</dict>\n\t...\n</array>\n```\n\n![image](https://user-images.githubusercontent.com/33388801/196835050-3d887f3c-1d07-4be3-a2cf-27ed18a48691.png)\n\n#### 3. `AppDelegate`의 `application:openURL:options` 에서 URL 핸들링 로직 추가\n\n네이버 로그인이 성공한 후 우리앱으로 다시 돌아와 URL을 처리하기 위해 필요한 과정입니다.\n\n```objc\n#import <NaverThirdPartyLogin/NaverThirdPartyLoginConnection.h>\n...\n\n// 다른 URL 핸들링 로직이 없는경우\n- (BOOL)application:(UIApplication *)application\n            openURL:(NSURL *)url\n            options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {\n   return [[NaverThirdPartyLoginConnection getSharedInstance] application:app openURL:url options:options];\n}\n\n// 다른 URL 핸들링 로직이 같이 있는 경우\n- (BOOL)application:(UIApplication *)application\n            openURL:(NSURL *)url\n            options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {\n  // naver\n  if ([url.scheme isEqualToString:@\"{{ CUSTOM URL SCHEME }}\"]) {\n    return [[NaverThirdPartyLoginConnection getSharedInstance] application:application openURL:url options:options];\n  }\n  \n  // kakao\n  if([RNKakaoLogins isKakaoTalkLoginUrl:url]) {\n    return [RNKakaoLogins handleOpenUrl: url];\n  }\n  \n  ...\n}\n```\n\n\n### 추가 작업 - Android ❗️Important\n\n#### 1. Proguard\n\n만약 Release build에서 R8 컴파일러를 이용해 code obfuscating을 하신다면, app/build.gradle 설정에 `minifyEnabled`이 `true`로 설정이 되어있을 것입니다.\n\n그 경우 다음과 같은 Proguard 규칙이 필요합니다.\n\n만약 그렇지 않다면 별도의 설정이 필요하지 않습니다.\n\n```text\n-keep public class com.nhn.android.naverlogin.** {\n       public protected *;\n}\n```\n\n### EXPO\n\n1. app.json 파일을 아래와 같이 수정합니다.\n\n```text\n{\n  \"expo\": {\n    ...\n    \"plugins\": [\n      ...,\n      [\n        \"@react-native-seoul/naver-login\",\n        {\n          \"urlScheme\": \"CUSTOM URL SCHEME\" // 네이버 url scheme를 적어주세요.\n        }\n      ]\n    ],\n    ...\n  }\n}\n```\n\n2.\n\n- Bare workflow의 경우에는 expo prebuild를 이용합니다.\n- Managed Workflow의 경우에는 EAS Build 이후 expo start --dev-client를 이용합니다.\n\n3. (Optional) Android에서 proguard rules 등을 적용하실 경우, [Expo BuildProperties](https://docs.expo.dev/versions/latest/sdk/build-properties/) 를 참고하세요.\n\n## API\n\n| Func        |        Param        |            Return             | Description                        |\n|:------------|:-------------------:|:-----------------------------:|:-----------------------------------|\n| login       | `NaverLoginRequest` | `Promise<NaverLoginResponse>` | 로그인, 반환되는 `Promise`는 항상 resolve된다. |\n| getProfile  |      `String`       | `Promise<GetProfileResponse>` | 프로필 불러오기                           |\n| logout      |                     |        `Promise<void>`        | 로그아웃                               |\n| deleteToken |                     |        `Promise<void>`        | 네이버 앱 연동 삭제                        |\n\n### Type\n\n**NaverLoginRequest**\n```typescript\nexport interface NaverLoginRequest {\n  consumerKey: string;\n  consumerSecret: string;\n  appName: string;\n  disableNaverAppAuth?: boolean;\n  /** Only for iOS */\n  serviceUrlScheme?: string;\n}\n```\n\n**NaverLoginResponse**\n```typescript\nexport interface NaverLoginResponse {\n  isSuccess: boolean;\n  /** isSuccess가 true일 때 존재합니다. */\n  successResponse?: {\n    accessToken: string;\n    refreshToken: string;\n    expiresAtUnixSecondString: string;\n    tokenType: string;\n  };\n  /** isSuccess가 false일 때 존재합니다. */\n  failureResponse?: {\n    message: string;\n    isCancel: boolean;\n\n    /** Android Only */\n    lastErrorCodeFromNaverSDK?: string;\n    /** Android Only */\n    lastErrorDescriptionFromNaverSDK?: string;\n  };\n}\n```\n\n**GetProfileResponse**\n```typescript\nexport interface GetProfileResponse {\n  resultcode: string;\n  message: string;\n  response: {\n    id: string;\n    profile_image: string | null;\n    email: string;\n    name: string;\n    birthday: string | null;\n    age: string | null;\n    birthyear: number | null;\n    gender: string | null;\n    mobile: string | null;\n    mobile_e164: string | null;\n    nickname: string | null;\n  };\n}\n```\n\n\n## Usage\n\n- 자세한 예제는 [예제 프로젝트](./NaverLoginExample)를 참고해주세요\n\n```typescript jsx\nimport React, {useState} from 'react';\nimport {SafeAreaView, Button, View, Text, ScrollView} from 'react-native';\nimport NaverLogin, {\n  NaverLoginResponse,\n  GetProfileResponse,\n} from '@react-native-seoul/naver-login';\n\nconst consumerKey = '';\nconst consumerSecret = '';\nconst appName = 'Hello';\nconst serviceUrlScheme = 'navertest';\n\nconst App = () => {\n  const [success, setSuccessResponse] =\n    useState<NaverLoginResponse['successResponse']>();\n  const [failure, setFailureResponse] =\n    useState<NaverLoginResponse['failureResponse']>();\n  const [getProfileRes, setGetProfileRes] = useState<GetProfileResponse>();\n\n  const login = async () => {\n    const {failureResponse, successResponse} = await NaverLogin.login({\n      appName,\n      consumerKey,\n      consumerSecret,\n      serviceUrlScheme,\n    });\n    setSuccessResponse(successResponse);\n    setFailureResponse(failureResponse);\n  };\n\n  const logout = async () => {\n    try {\n      await NaverLogin.logout();\n      setSuccessResponse(undefined);\n      setFailureResponse(undefined);\n      setGetProfileRes(undefined);\n    } catch (e) {\n      console.error(e);\n    }\n  };\n\n  const getProfile = async () => {\n    try {\n      const profileResult = await NaverLogin.getProfile(success!.accessToken);\n      setGetProfileRes(profileResult);\n    } catch (e) {\n      setGetProfileRes(undefined);\n    }\n  };\n\n  const deleteToken = async () => {\n    try {\n      await NaverLogin.deleteToken();\n      setSuccessResponse(undefined);\n      setFailureResponse(undefined);\n      setGetProfileRes(undefined);\n    } catch (e) {\n      console.error(e);\n    }\n  };\n\n  return (\n    <SafeAreaView\n      style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>\n      <ScrollView\n        style={{flex: 1}}\n        contentContainerStyle={{flexGrow: 1, padding: 24}}>\n        <Button title={'Login'} onPress={login} />\n        <Gap />\n        <Button title={'Logout'} onPress={logout} />\n        <Gap />\n        {success ? (\n          <>\n            <Button title=\"Get Profile\" onPress={getProfile} />\n            <Gap />\n          </>\n        ) : null}\n        {success ? (\n          <View>\n            <Button title=\"Delete Token\" onPress={deleteToken} />\n            <Gap />\n            <ResponseJsonText name={'Success'} json={success} />\n          </View>\n        ) : null}\n        <Gap />\n        {failure ? <ResponseJsonText name={'Failure'} json={failure} /> : null}\n        <Gap />\n        {getProfileRes ? (\n          <ResponseJsonText name={'GetProfile'} json={getProfileRes} />\n        ) : null}\n      </ScrollView>\n    </SafeAreaView>\n  );\n};\nconst Gap = () => <View style={{marginTop: 24}} />;\nconst ResponseJsonText = ({json = {}, name}: {json?: object; name: string}) => (\n  <View\n    style={{\n      padding: 12,\n      borderRadius: 16,\n      borderWidth: 1,\n      backgroundColor: '#242c3d',\n    }}>\n    <Text style={{fontSize: 20, fontWeight: 'bold', color: 'white'}}>\n      {name}\n    </Text>\n    <Text style={{color: 'white', fontSize: 13, lineHeight: 20}}>\n      {JSON.stringify(json, null, 4)}\n    </Text>\n  </View>\n);\n\nexport default App;\n```\n","readmeFilename":"README.md"}