[RN] ๐Ÿช…Deep Link ๊ณต์œ ํ•˜๊ธฐ

TATAยท2024๋…„ 9์›” 14์ผ
0

React-Native

๋ชฉ๋ก ๋ณด๊ธฐ
10/10

Deep Link ๊ณต์‹๋ฌธ์„œ

๊ณต์‹๋ฌธ์„œ ๋ณด๊ณ  ๊ธฐ๋ณธ์ ์ธ ์„ค์ • ํ•ด์ฃผ๊ธฐ

๐Ÿช… IOS

# ์ƒ์„ฑ
npx uri-scheme add fromnow --ios

๐Ÿช… Android

# ์ƒ์„ฑ
npx uri-scheme add fromnow --android

# ๊ธฐ๋ณธ ๊ฒฝ๋กœ
fromnow://

# npx uri-scheme open [your deep link] --[ios|android]
npx uri-scheme open "fromnow://profile" --ios

npx uri-scheme open "fromnow://team-setting/8" --android

npx uri-scheme open "fromnow://team-detail/8/123" --android

๐Ÿช… deeplinkConfig.ts

/* deeplinkConfig.ts */
import { Linking } from 'react-native';
import { LinkingOptions } from '@react-navigation/native';

export const linking: LinkingOptions<RootStackParamList> = {
  prefixes: ['fromnow://'],
  config: {
    screens: {
      Home: 'home',
      Profile: 'profile',
      Team: 'team/:id',
      TeamCalendar: 'team-calendar/:id',
      TeamSetting: 'team-setting/:id',
      TeamEdit: 'team-edit/:id',
      TeamDetail: 'team-detail/:teamId/:date',
    },
  },
  async getInitialURL() {
    const url = await Linking.getInitialURL();
    if (url != null) return url;
  },
};

type RootStackParamList = {
  Home: string;
  Profile: string;
  Team: { id: string };
  TeamCalendar: { id: string };
  TeamSetting: { id: string };
  TeamEdit: { id: string };
  TeamFriendAdd: { id: string };
  TeamDetail: { teamId: string; date: string };
};
/* App.tsx */
import { linking } from './deeplinkConfig';

<NavigationContainer linking={linking}>
  ...
</NavigationContainer>

Linking.openURL

Linking.openURL("fromnow://profile");

์•ฑ ์„ค์ • ์—ด๊ธฐ

Linking.openSettings();

๐Ÿ—‘๏ธ deeplinkConfig ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ณ  ๋งŒ๋“ค์—ˆ๋˜ ์ฝ”๋“œ(๋ฒ„๋ฆผ..)

# ํ”„๋กœํ•„ ๊ฒฝ๋กœ
fromnow://Profile
# ํŒ€์„ธํŒ… ๊ฒฝ๋กœ
fromnow://TeamSetting?id=3256
npx uri-scheme open "fromnow://TeamSetting?id=8" --android

npx uri-scheme open "fromnow://TeamDetail?postId=8&teamId=123" --android
import { Linking } from 'react-native';
import useNavi from '@hooks/useNavi';

...
const { navigation } = useNavi();

const parseQueryParams = (query: string) => {
  const paramsObj = {};
  const paramsArray = query.split('&');
  paramsArray.forEach(param => {
    const [key, value] = param.split('=');
    if (key && value) {
      paramsObj[key] = decodeURIComponent(value);
    }
  });
  return paramsObj;
};

const navigateByDeepLink = (e: { url: string }) => {
  let { url } = e;
  if (!url) return;
  const [path, query] = url.replace(/.*?:\/\//g, '').split('?');
  let paramsObj = {};
  if (query) {
    paramsObj = parseQueryParams(query);
  }
  navigation.navigate(path, paramsObj);
};

useEffect(() => {
  // ์•ฑ์ด ์ฒ˜์Œ ์‹œ์ž‘๋์„ ๋•Œ
  Linking.getInitialURL().then(url => {
    navigateByDeepLink({ url });
  });
  // ์ด๋ฏธ ์•ฑ์ด ์‹คํ–‰์ค‘์ผ ๋•Œ
  const linking = Linking.addEventListener('url', navigateByDeepLink);

  return () => {
    linking.remove();
  };
}, []);
...
profile
๐ŸŒฟ https://www.tatahyeonv.com

0๊ฐœ์˜ ๋Œ“๊ธ€