Skip to content

Commit

Permalink
feat: 딥링크 && utm 추적 적용하기
Browse files Browse the repository at this point in the history
  • Loading branch information
raymondanythings committed Sep 9, 2024
1 parent 86b26a2 commit cfaa3e9
Show file tree
Hide file tree
Showing 23 changed files with 402 additions and 24 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,5 @@ dist
.svelte-kit

# End of https://www.toptal.com/developers/gitignore/api/node

*.xcconfig
3 changes: 3 additions & 0 deletions apps/branch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"deferInitForPluginRuntime": true
}
4 changes: 3 additions & 1 deletion apps/mobile/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ expo-env.d.ts

*.keystore

gradle.properties
gradle.properties

ios/Config.xcconfig
2 changes: 2 additions & 0 deletions apps/mobile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@ Join our community of developers creating universal apps.

- [Expo on GitHub](https://github.com/expo/expo): View our open source platform and contribute.
- [Discord community](https://chat.expo.dev): Chat with Expo users and ask questions.

npx uri-scheme open 'layer://?utm_source=google&utm_medium=cpc&utm_campaign=spring_sale' --ios
20 changes: 20 additions & 0 deletions apps/mobile/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { ConfigContext } from "expo/config";
import * as dotenv from "dotenv";

dotenv.config();

export default ({ config }: ConfigContext): ConfigContext["config"] => {
return {
Expand All @@ -8,11 +11,28 @@ export default ({ config }: ConfigContext): ConfigContext["config"] => {
config: {
...(config?.ios?.config ?? {}),
usesNonExemptEncryption: false,
branch: {
apiKey: "key_live_itjP2IzCCpusGpEaJZoejcicxrdQXPCx",
},
},
associatedDomains: [
"applinks:app.layerapp.io",
"applinks:layer-five.vercel.app",
"applinks:1xdd5-alternate.app.link",
],
},
android: {
config: {
branch: {
apiKey: "key_live_itjP2IzCCpusGpEaJZoejcicxrdQXPCx",
},
},
},
plugins: [
"expo-router",
"expo-asset",
["@config-plugins/react-native-branch"],

[
"expo-font",
{
Expand Down
1 change: 1 addition & 0 deletions apps/mobile/app/(tabs)/analysis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default function LoginPage() {
<WebViewLayout
pathname="/analysis"
style={{
backgroundColor: "#F2F4F8",
paddingTop: insets.top,
}}
/>
Expand Down
1 change: 1 addition & 0 deletions apps/mobile/app/(tabs)/goals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default function LoginPage() {
<WebViewLayout
pathname="/goals"
style={{
backgroundColor: "#F2F4F8",
paddingTop: insets.top,
}}
/>
Expand Down
1 change: 1 addition & 0 deletions apps/mobile/app/(tabs)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default function LoginPage() {
<WebViewLayout
pathname="/"
style={{
backgroundColor: "#F2F4F8",
paddingTop: insets.top,
}}
/>
Expand Down
17 changes: 17 additions & 0 deletions apps/mobile/app/+html.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { PropsWithChildren } from "react";

export default function Root({ children }: PropsWithChildren) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />

<meta name="apple-itunes-app" content="app-id={ITUNES_ID}" />

{/* Other head elements... */}
</head>
<body>{children}</body>
</html>
);
}
79 changes: 79 additions & 0 deletions apps/mobile/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,88 @@ import { GestureHandlerRootView } from "react-native-gesture-handler";
import { SuspenseProvider } from "@/provider/suspense-provider";
import { PermissionsAndroid, Platform } from "react-native";
import { PERMISSIONS } from "react-native-permissions";
import * as Linking from "expo-linking";
import branch from "react-native-branch";
import { Mixpanel } from "mixpanel-react-native";

const trackAutomaticEvents = false;
const useNative = false;
const mixpanel = new Mixpanel(
process.env.EXPO_PUBLIC_MIXPANEL_TOKEN,
trackAutomaticEvents,
useNative
);

mixpanel.init();

interface BranchEventParams {
$og_title: string;
"+referrer": string;
$marketing_title: string;
"+referring_browser": string;
"+is_first_session": boolean;
/**
* utm_source
*/
"~channel": string;
"~referring_link": string;
"+match_type": string;
"~id": string;
"+click_timestamp": number;
"+match_guaranteed": boolean;
"+clicked_branch_link": boolean;
/**
* utm_medium
*/
"~feature": "natural";
$deeplink_path: string;
"~marketing": true;
/**
* utm_campaign
*/
"~campaign": "none";
}

export default function App() {
const colorScheme = useColorScheme();

useEffect(() => {
async function checkInitialReferringParams() {
const [f, l] = await Promise.all([
branch.getFirstReferringParams(),
branch.getLatestReferringParams(),
]);
if (l) {
mixpanel.track("Last Branch Event ", l);
}
}
function subscribeBranch() {
const unsubscribe = branch.subscribe({
onOpenComplete(event) {
if (event.params) {
const params = event.params as unknown as BranchEventParams;
const args = {
utm_source: params["~channel"],
utm_medium: params["~feature"],
utm_campaign: params["~campaign"],
...params,
};
mixpanel.track("Referer Event ", args);
}
},
});

return unsubscribe;
}

checkInitialReferringParams();
const unsubscribe = subscribeBranch();
if (!!process.env.EXPO_PUBLIC_KAKAO_NATIVE_APP_KEY) {
initializeKakaoSDK(process.env.EXPO_PUBLIC_KAKAO_NATIVE_APP_KEY);
}
return () => {
unsubscribe();
};
}, []);

useEffect(() => {
Expand Down Expand Up @@ -51,6 +125,11 @@ export default function App() {
}
};

const url = Linking.useURL();
if (url) {
const { hostname, path, queryParams, scheme } = Linking.parse(url);
}

return (
<GestureHandlerRootView>
<ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
Expand Down
5 changes: 5 additions & 0 deletions apps/mobile/app/space/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Redirect } from "expo-router";

export default function Page() {
return <Redirect href="/login" />;
}
11 changes: 7 additions & 4 deletions apps/mobile/env.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
declare module "@env" {
export const EXPO_PUBLIC_KAKAO_NATIVE_APP_KEY: string;
export const EXPO_USE_METRO_WORKSPACE_ROOT: string;
export const EXPO_PUBLIC_WEBVIEW_URI: string;
declare namespace NodeJS {
interface ProcessEnv {
readonly EXPO_PUBLIC_KAKAO_NATIVE_APP_KEY: string;
readonly EXPO_USE_METRO_WORKSPACE_ROOT: string;
readonly EXPO_PUBLIC_WEBVIEW_URI: string;
readonly EXPO_PUBLIC_MIXPANEL_TOKEN: string;
}
}
2 changes: 2 additions & 0 deletions apps/mobile/ios/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ DerivedData
*.xcuserstate
project.xcworkspace
.xcode.env.local
Config.xcconfig

# Bundle artifacts
*.jsbundle

# CocoaPods
/Pods/

Loading

0 comments on commit cfaa3e9

Please sign in to comment.