Skip to content

Commit 5f0e4ed

Browse files
authored
Merge pull request #231 from YAPP-Github/feature/#230-meta-app-events-tracking
2 parents a5300e4 + 8e4ee0f commit 5f0e4ed

29 files changed

Lines changed: 348 additions & 34 deletions

File tree

‎.github/workflows/develop_branch.yml‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ jobs:
2424
RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }}
2525
RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
2626
RELEASE_STORE_PASSWORD: ${{ secrets.RELEASE_STORE_PASSWORD }}
27+
FACEBOOK_APP_ID: ${{ secrets.FACEBOOK_APP_ID }}
28+
FACEBOOK_CLIENT_TOKEN: ${{ secrets.FACEBOOK_CLIENT_TOKEN }}
29+
FACEBOOK_DEBUG_APP_ID: ${{ secrets.FACEBOOK_DEBUG_APP_ID }}
30+
FACEBOOK_DEBUG_CLIENT_TOKEN: ${{ secrets.FACEBOOK_DEBUG_CLIENT_TOKEN }}
2731
run: |
2832
# Keystore Decoding
2933
echo $RELEASE_STORE_BASE_64 > encoded_keystore.txt
@@ -38,6 +42,10 @@ jobs:
3842
echo "release.key.password=$RELEASE_KEY_PASSWORD" >> local.properties
3943
echo "release.keystore.password=$RELEASE_STORE_PASSWORD" >> local.properties
4044
echo "release.keystore.path=../release.jks" >> local.properties
45+
echo "facebook.app.id=$FACEBOOK_APP_ID" >> local.properties
46+
echo "facebook.client.token=$FACEBOOK_CLIENT_TOKEN" >> local.properties
47+
echo "facebook.debug.app.id=$FACEBOOK_DEBUG_APP_ID" >> local.properties
48+
echo "facebook.debug.client.token=$FACEBOOK_DEBUG_CLIENT_TOKEN" >> local.properties
4149
4250
- name: set up JDK 17
4351
uses: actions/setup-java@v4

‎app/build.gradle.kts‎

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import java.util.Properties
1+
import com.threegap.bitnagil.convention.extension.propertyOrNull
2+
import com.threegap.bitnagil.convention.extension.requireProperty
23

34
plugins {
45
alias(libs.plugins.bitnagil.android.application)
@@ -7,34 +8,17 @@ plugins {
78
}
89

910
android {
10-
val properties =
11-
Properties().apply {
12-
val propFile = rootProject.file("local.properties")
13-
if (propFile.exists()) {
14-
load(propFile.inputStream())
15-
}
16-
}
17-
1811
signingConfigs {
1912
create("release") {
20-
keyAlias = properties["release.key.alias"] as? String
21-
?: System.getenv("RELEASE_KEY_ALIAS")
22-
?: throw GradleException("RELEASE_KEY_ALIAS 값이 없습니다.")
23-
keyPassword = properties["release.key.password"] as? String
24-
?: System.getenv("RELEASE_KEY_PASSWORD")
25-
?: throw GradleException("RELEASE_KEY_PASSWORD 값이 없습니다.")
26-
storePassword = properties["release.keystore.password"] as? String
27-
?: System.getenv("RELEASE_KEYSTORE_PASSWORD")
28-
?: throw GradleException("RELEASE_KEYSTORE_PASSWORD 값이 없습니다.")
29-
storeFile = File("${properties["release.keystore.path"]}")
13+
keyAlias = requireProperty("release.key.alias", "RELEASE_KEY_ALIAS")
14+
keyPassword = requireProperty("release.key.password", "RELEASE_KEY_PASSWORD")
15+
storePassword = requireProperty("release.keystore.password", "RELEASE_KEYSTORE_PASSWORD")
16+
storeFile = File("${propertyOrNull("release.keystore.path", "RELEASE_KEYSTORE_PATH")}")
3017
}
3118
}
3219

3320
defaultConfig {
34-
val kakaoNativeAppKey =
35-
(properties["kakao.native.app.key"] as? String)
36-
?: System.getenv("KAKAO_NATIVE_APP_KEY")
37-
?: throw GradleException("KAKAO_NATIVE_APP_KEY 값이 없습니다.")
21+
val kakaoNativeAppKey = requireProperty("kakao.native.app.key", "KAKAO_NATIVE_APP_KEY")
3822

3923
manifestPlaceholders["KAKAO_NATIVE_APP_KEY"] = kakaoNativeAppKey
4024
buildConfigField(
@@ -43,10 +27,7 @@ android {
4327
value = "\"$kakaoNativeAppKey\"",
4428
)
4529

46-
val kakaoRestApiKey =
47-
(properties["kakao.rest.api.key"] as? String)
48-
?: System.getenv("KAKAO_REST_API_KEY")
49-
?: throw GradleException("KAKAO_REST_API_KEY 값이 없습니다.")
30+
val kakaoRestApiKey = requireProperty("kakao.rest.api.key", "KAKAO_REST_API_KEY")
5031

5132
buildConfigField(
5233
type = "String",
@@ -61,17 +42,14 @@ android {
6142
versionNameSuffix = "-DEBUG"
6243
isDebuggable = true
6344

64-
val devUrl = properties["bitnagil.dev.url"] as? String
65-
?: System.getenv("BITNAGIL_DEV_URL")
66-
?: throw GradleException("bitnagil.dev.url 값이 없습니다.")
45+
val devUrl = requireProperty("bitnagil.dev.url", "BITNAGIL_DEV_URL")
6746
buildConfigField("String", "BASE_URL", "\"$devUrl\"")
6847
}
6948

7049
release {
71-
val prodUrl = properties["bitnagil.prod.url"] as? String
72-
?: System.getenv("BITNAGIL_PROD_URL")
73-
?: throw GradleException("bitnagil.prod.url 값이 없습니다.")
50+
val prodUrl = requireProperty("bitnagil.prod.url", "BITNAGIL_PROD_URL")
7451
buildConfigField("String", "BASE_URL", "\"$prodUrl\"")
52+
7553
isMinifyEnabled = true
7654
isShrinkResources = true
7755
proguardFiles(
@@ -88,6 +66,7 @@ android {
8866
}
8967

9068
dependencies {
69+
implementation(projects.core.analytics)
9170
implementation(projects.core.datastore)
9271
implementation(projects.core.designsystem)
9372
implementation(projects.core.network)

‎app/src/main/AndroidManifest.xml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,9 @@
5757
android:name="android.support.FILE_PROVIDER_PATHS"
5858
android:resource="@xml/file_paths" />
5959
</provider>
60+
61+
<meta-data android:name="com.facebook.sdk.AutoInitEnabled" android:value="true" />
62+
<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="true" />
63+
<meta-data android:name="com.facebook.sdk.AdvertiserIDCollectionEnabled" android:value="true" />
6064
</application>
6165
</manifest>

‎app/src/main/java/com/threegap/bitnagil/BitnagilApplication.kt‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import coil3.network.okhttp.OkHttpNetworkFetcherFactory
1010
import coil3.request.crossfade
1111
import coil3.util.DebugLogger
1212
import com.kakao.sdk.common.KakaoSdk
13+
import com.threegap.bitnagil.analytics.meta.MetaAnalyticsInitializer
1314
import com.threegap.bitnagil.di.core.CoilEntryPoint
1415
import dagger.hilt.EntryPoints
1516
import dagger.hilt.android.HiltAndroidApp
@@ -21,6 +22,7 @@ class BitnagilApplication : Application(), SingletonImageLoader.Factory {
2122
override fun onCreate() {
2223
super.onCreate()
2324
initKakaoSdk()
25+
configureMetaAppEvents()
2426
}
2527

2628
override fun newImageLoader(context: PlatformContext): ImageLoader {
@@ -49,4 +51,8 @@ class BitnagilApplication : Application(), SingletonImageLoader.Factory {
4951
private fun initKakaoSdk() {
5052
KakaoSdk.init(this, BuildConfig.KAKAO_NATIVE_APP_KEY)
5153
}
54+
55+
private fun configureMetaAppEvents() {
56+
MetaAnalyticsInitializer.initialize(isDebugBuild = BuildConfig.DEBUG)
57+
}
5258
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.threegap.bitnagil.di.core
2+
3+
import android.content.Context
4+
import com.threegap.bitnagil.analytics.AnalyticsLogger
5+
import com.threegap.bitnagil.analytics.meta.MetaAnalyticsLogger
6+
import dagger.Module
7+
import dagger.Provides
8+
import dagger.hilt.InstallIn
9+
import dagger.hilt.android.qualifiers.ApplicationContext
10+
import dagger.hilt.components.SingletonComponent
11+
import javax.inject.Singleton
12+
13+
@Module
14+
@InstallIn(SingletonComponent::class)
15+
object AnalyticsModule {
16+
17+
@Provides
18+
@Singleton
19+
fun provideAnalyticsLogger(@ApplicationContext context: Context): AnalyticsLogger =
20+
MetaAnalyticsLogger(context)
21+
}

‎app/src/main/java/com/threegap/bitnagil/di/core/DataStoreModule.kt‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import com.threegap.bitnagil.datastore.auth.serializer.AuthTokenSerializer
66
import com.threegap.bitnagil.datastore.auth.serializer.AuthTokenSerializerImpl
77
import com.threegap.bitnagil.datastore.auth.storage.AuthTokenDataStore
88
import com.threegap.bitnagil.datastore.auth.storage.AuthTokenStorageFactory
9+
import com.threegap.bitnagil.datastore.routine.storage.RoutineAchievementDataStore
10+
import com.threegap.bitnagil.datastore.routine.storage.RoutineAchievementStorageFactory
911
import com.threegap.bitnagil.security.crypto.Crypto
1012
import dagger.Module
1113
import dagger.Provides
@@ -38,4 +40,10 @@ object DataStoreModule {
3840
@ApplicationContext context: Context,
3941
serializer: AuthTokenSerializer,
4042
): AuthTokenDataStore = AuthTokenStorageFactory.create(context, serializer)
43+
44+
@Provides
45+
@Singleton
46+
fun provideRoutineAchievementDataStore(
47+
@ApplicationContext context: Context,
48+
): RoutineAchievementDataStore = RoutineAchievementStorageFactory.create(context)
4149
}

‎app/src/main/java/com/threegap/bitnagil/di/data/DataSourceModule.kt‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ import com.threegap.bitnagil.data.recommendroutine.datasource.RecommendRoutineDa
2424
import com.threegap.bitnagil.data.recommendroutine.datasourceImpl.RecommendRoutineDataSourceImpl
2525
import com.threegap.bitnagil.data.report.datasource.ReportDataSource
2626
import com.threegap.bitnagil.data.report.datasourceImpl.ReportDataSourceImpl
27+
import com.threegap.bitnagil.data.routine.datasource.RoutineLocalDataSource
2728
import com.threegap.bitnagil.data.routine.datasource.RoutineRemoteDataSource
29+
import com.threegap.bitnagil.data.routine.datasourceImpl.RoutineLocalDataSourceImpl
2830
import com.threegap.bitnagil.data.routine.datasourceImpl.RoutineRemoteDataSourceImpl
2931
import com.threegap.bitnagil.data.user.datasource.UserLocalDataSource
3032
import com.threegap.bitnagil.data.user.datasource.UserRemoteDataSource
@@ -58,6 +60,10 @@ abstract class DataSourceModule {
5860
@Singleton
5961
abstract fun bindRoutineDataSource(routineDataSourceImpl: RoutineRemoteDataSourceImpl): RoutineRemoteDataSource
6062

63+
@Binds
64+
@Singleton
65+
abstract fun bindRoutineLocalDataSource(routineLocalDataSourceImpl: RoutineLocalDataSourceImpl): RoutineLocalDataSource
66+
6167
@Binds
6268
@Singleton
6369
abstract fun bindEmotionLocalDataSource(emotionLocalDataSourceImpl: EmotionLocalDataSourceImpl): EmotionLocalDataSource
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.threegap.bitnagil.convention.extension
2+
3+
import java.util.Properties
4+
import org.gradle.api.GradleException
5+
import org.gradle.api.Project
6+
7+
private const val LOCAL_PROPERTIES_FILE_NAME = "local.properties"
8+
private const val LOCAL_PROPERTIES_EXTRA_KEY = "bitnagilLocalProperties"
9+
10+
private fun Project.loadLocalProperties(): Properties =
11+
Properties().apply {
12+
val localPropertiesFile = rootProject.file(LOCAL_PROPERTIES_FILE_NAME)
13+
if (localPropertiesFile.exists()) {
14+
localPropertiesFile.inputStream().use(::load)
15+
}
16+
}
17+
18+
/**
19+
* 모듈마다 한 번만 읽고 해당 프로젝트의 extra 에 담아둔다.
20+
* 데몬이 아니라 빌드마다 새로 만들어지는 저장소이므로 local.properties 를 수정하면 다음 빌드에 반영된다.
21+
*/
22+
private val Project.localProperties: Properties
23+
get() {
24+
val extra = extensions.extraProperties
25+
if (!extra.has(LOCAL_PROPERTIES_EXTRA_KEY)) {
26+
extra.set(LOCAL_PROPERTIES_EXTRA_KEY, loadLocalProperties())
27+
}
28+
return extra.get(LOCAL_PROPERTIES_EXTRA_KEY) as Properties
29+
}
30+
31+
/**
32+
* local.properties 값을 읽고, 없으면 환경 변수를 사용한다. 둘 다 없으면 null 을 반환한다.
33+
*/
34+
fun Project.propertyOrNull(propertyKey: String, environmentKey: String): String? =
35+
localProperties.getProperty(propertyKey) ?: System.getenv(environmentKey)
36+
37+
/**
38+
* [propertyOrNull] 과 동일하되, 값이 없거나 비어 있으면 설정 단계에서 실패한다.
39+
*/
40+
fun Project.requireProperty(propertyKey: String, environmentKey: String): String =
41+
propertyOrNull(propertyKey, environmentKey)?.takeIf(String::isNotBlank)
42+
?: throw GradleException("$propertyKey 값이 없습니다.")

‎core/analytics/build.gradle.kts‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import com.threegap.bitnagil.convention.extension.requireProperty
2+
3+
plugins {
4+
alias(libs.plugins.bitnagil.android.library)
5+
}
6+
7+
android {
8+
buildTypes {
9+
debug {
10+
resValue(
11+
type = "string",
12+
name = "facebook_app_id",
13+
value = requireProperty("facebook.debug.app.id", "FACEBOOK_DEBUG_APP_ID"),
14+
)
15+
resValue(
16+
type = "string",
17+
name = "facebook_client_token",
18+
value = requireProperty("facebook.debug.client.token", "FACEBOOK_DEBUG_CLIENT_TOKEN"),
19+
)
20+
}
21+
22+
release {
23+
resValue(
24+
type = "string",
25+
name = "facebook_app_id",
26+
value = requireProperty("facebook.app.id", "FACEBOOK_APP_ID"),
27+
)
28+
resValue(
29+
type = "string",
30+
name = "facebook_client_token",
31+
value = requireProperty("facebook.client.token", "FACEBOOK_CLIENT_TOKEN"),
32+
)
33+
}
34+
}
35+
36+
buildFeatures {
37+
resValues = true
38+
}
39+
}
40+
41+
dependencies {
42+
implementation(libs.facebook.core)
43+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<application>
5+
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id" />
6+
<meta-data android:name="com.facebook.sdk.ClientToken" android:value="@string/facebook_client_token" />
7+
</application>
8+
</manifest>

0 commit comments

Comments
 (0)