-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feat] 6주차 과제 #10
base: develop
Are you sure you want to change the base?
[feat] 6주차 과제 #10
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,8 +5,9 @@ plugins { | |
alias(libs.plugins.kotlin.android) | ||
alias(libs.plugins.kotlin.compose) | ||
alias(libs.plugins.kotlin.serialization) | ||
alias(libs.plugins.dagger.hilt) | ||
id("org.jetbrains.kotlin.kapt") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 나도 kapt썻다가 ksp썻다가...ksp로 나중에 오류 잡아서 고쳐보자! |
||
} | ||
|
||
val properties = Properties().apply { | ||
load(project.rootProject.file("local.properties").inputStream()) | ||
} | ||
|
@@ -55,7 +56,6 @@ android { | |
|
||
|
||
dependencies { | ||
|
||
implementation(libs.androidx.core.ktx) | ||
implementation(libs.androidx.lifecycle.runtime.ktx) | ||
implementation(libs.androidx.activity.compose) | ||
|
@@ -90,4 +90,7 @@ dependencies { | |
implementation(libs.converter.gson) | ||
implementation(libs.coil.compose) | ||
|
||
// Hilt | ||
implementation(libs.bundles.hilt) | ||
kapt(libs.hilt.compiler) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package org.sopt.and | ||
|
||
import android.app.Application | ||
import dagger.hilt.android.HiltAndroidApp | ||
|
||
@HiltAndroidApp | ||
class WavveApp : Application() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hilt를 쓰니까 @HiltAndroidApp 어노테이션이 없으면 빌드 에러가 나더라구요...? 힐트를 써줄때면 이렇게 어플리케이션을 늘 하나 따로 만들어서 androidmanifest.xml 파일에도 등록해줘야 하는 건가요?! 뭔가 프로젝트 안에 동떨어진 WaveApp.kt 파일이 하나 생기는 게 조금 이질적으로 느껴져서 여쭤봅니다 ㅜㅜ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,16 @@ | ||
package org.sopt.and.data.datalocal.datasourceimpl | ||
|
||
|
||
Comment on lines
+2
to
+3
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2줄 ~ |
||
import android.content.Context | ||
import android.content.SharedPreferences | ||
import androidx.core.content.edit | ||
import org.sopt.and.data.datalocal.datasource.UserInfoLocalDataSource | ||
import dagger.hilt.android.qualifiers.ApplicationContext | ||
import org.sopt.and.data.datalocal.datasource.UserLocalDataSource | ||
import javax.inject.Inject | ||
|
||
class UserInfoLocalDataSourceImpl(context: Context) : UserInfoLocalDataSource { | ||
class UserLocalDataSourceImpl @Inject constructor( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LocalDataSource에 대해서 찾아봤는데 실제로 개발할 때 사용하기 엄청 유용할 것 같더라고요..! 길지 않은 시간 동안 무겁지 않은 정보를 저장하고 싶을 때 유용하게 쓸 것 같아요!! |
||
@ApplicationContext context: Context | ||
) : UserLocalDataSource { | ||
|
||
private val sharedPreferences: SharedPreferences = | ||
context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package org.sopt.and.data.dataremote.datasource | ||
|
||
import org.sopt.and.data.dataremote.model.request.RequestLoginDto | ||
import org.sopt.and.data.dataremote.model.request.RequestSignUpDto | ||
import org.sopt.and.data.dataremote.model.response.ResponseLoginDto | ||
import org.sopt.and.data.dataremote.model.response.ResponseMyHobbyDto | ||
import org.sopt.and.data.dataremote.model.response.ResponseSignUpDto | ||
import retrofit2.Response | ||
|
||
|
||
Comment on lines
+9
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 요기두 |
||
interface UserRemoteDataSource { | ||
suspend fun postSignup(requestSignUpDto: RequestSignUpDto): Response<ResponseSignUpDto> | ||
|
||
suspend fun postLogin(requestLoginDto: RequestLoginDto): Response<ResponseLoginDto> | ||
|
||
suspend fun getUserHobby(token: String): Response<ResponseMyHobbyDto> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package org.sopt.and.data.dataremote.datasourceimpl | ||
|
||
import org.sopt.and.data.dataremote.datasource.UserRemoteDataSource | ||
import org.sopt.and.data.dataremote.model.request.RequestLoginDto | ||
import org.sopt.and.data.dataremote.model.request.RequestSignUpDto | ||
import org.sopt.and.data.dataremote.model.response.ResponseLoginDto | ||
import org.sopt.and.data.dataremote.model.response.ResponseMyHobbyDto | ||
import org.sopt.and.data.dataremote.model.response.ResponseSignUpDto | ||
import org.sopt.and.data.dataremote.service.UserService | ||
import retrofit2.Response | ||
import javax.inject.Inject | ||
|
||
class UserRemoteDataSourceImpl @Inject constructor( | ||
private val service: UserService | ||
) : UserRemoteDataSource { | ||
override suspend fun postSignup(requestSignUpDto: RequestSignUpDto): Response<ResponseSignUpDto> = | ||
service.postSignup(requestSignUpDto) | ||
|
||
override suspend fun postLogin(requestLoginDto: RequestLoginDto): Response<ResponseLoginDto> = | ||
service.postLogin(requestLoginDto) | ||
|
||
override suspend fun getUserHobby(token: String): Response<ResponseMyHobbyDto> = | ||
service.getUserHobby(token) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package org.sopt.and.data.dataremote.service | ||
|
||
import org.sopt.and.data.dataremote.model.request.RequestLoginDto | ||
import org.sopt.and.data.dataremote.model.request.RequestSignUpDto | ||
import org.sopt.and.data.dataremote.model.response.ResponseLoginDto | ||
import org.sopt.and.data.dataremote.model.response.ResponseMyHobbyDto | ||
import org.sopt.and.data.dataremote.model.response.ResponseSignUpDto | ||
import retrofit2.Response | ||
import retrofit2.http.Body | ||
import retrofit2.http.GET | ||
import retrofit2.http.Header | ||
import retrofit2.http.POST | ||
|
||
|
||
interface UserService { | ||
@POST("/user") | ||
suspend fun postSignup(@Body requestSignUpDto: RequestSignUpDto): Response<ResponseSignUpDto> | ||
|
||
@POST("/login") | ||
suspend fun postLogin(@Body requestLoginDto: RequestLoginDto): Response<ResponseLoginDto> | ||
|
||
@GET("/user/my-hobby") | ||
suspend fun getUserHobby(@Header("token") token: String): Response<ResponseMyHobbyDto> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package org.sopt.and.data.repositoryimpl | ||
|
||
import jakarta.inject.Inject | ||
import org.sopt.and.data.datalocal.datasource.UserLocalDataSource | ||
import org.sopt.and.data.dataremote.datasource.UserRemoteDataSource | ||
import org.sopt.and.data.dataremote.model.request.RequestLoginDto | ||
import org.sopt.and.data.dataremote.model.request.RequestSignUpDto | ||
import org.sopt.and.data.dataremote.model.response.ResponseLoginDto | ||
import org.sopt.and.data.dataremote.model.response.ResponseMyHobbyDto | ||
import org.sopt.and.data.dataremote.model.response.ResponseSignUpDto | ||
import org.sopt.and.domain.repository.UserRepository | ||
import retrofit2.Response | ||
|
||
class UserRepositoryImpl @Inject constructor( | ||
private val userRemoteDataSource: UserRemoteDataSource, | ||
private val userLocalDataSource: UserLocalDataSource | ||
) : UserRepository { | ||
override suspend fun postSignup(requestSignUpDto: RequestSignUpDto): Response<ResponseSignUpDto> = | ||
userRemoteDataSource.postSignup(requestSignUpDto) | ||
|
||
override suspend fun postLogin(requestLoginDto: RequestLoginDto): Response<ResponseLoginDto> = | ||
userRemoteDataSource.postLogin(requestLoginDto) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Response 타입을 그대로 반환하는데, 도메인 레이어에서 더 사용하기 좋은 형태(Result나 sealed class)로 매핑하는게 더 좋다고 들었는데 어떤가요? |
||
|
||
override suspend fun getUserHobby(token: String): Response<ResponseMyHobbyDto> = | ||
userRemoteDataSource.getUserHobby(token) | ||
|
||
override fun saveAccessToken(token: String) { | ||
userLocalDataSource.accessToken = token | ||
} | ||
|
||
override fun getAccessToken(): String { | ||
return userLocalDataSource.accessToken | ||
} | ||
|
||
override fun saveNickname(nickname: String) { | ||
userLocalDataSource.nickname = nickname | ||
} | ||
|
||
override fun getNickname(): String { | ||
return userLocalDataSource.nickname | ||
} | ||
|
||
override fun clearUserData() { | ||
userLocalDataSource.clear() | ||
} | ||
} |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package org.sopt.and.di | ||
|
||
import dagger.Binds | ||
import dagger.Module | ||
import dagger.hilt.InstallIn | ||
import dagger.hilt.components.SingletonComponent | ||
import org.sopt.and.data.datalocal.datasource.UserLocalDataSource | ||
import org.sopt.and.data.datalocal.datasourceimpl.UserLocalDataSourceImpl | ||
import org.sopt.and.data.dataremote.datasource.UserRemoteDataSource | ||
import org.sopt.and.data.dataremote.datasourceimpl.UserRemoteDataSourceImpl | ||
import javax.inject.Singleton | ||
|
||
@Module | ||
@InstallIn(SingletonComponent::class) | ||
abstract class DataSourceModule { | ||
@Binds | ||
@Singleton | ||
abstract fun bindsUserRemoteDataSource(userRemoteDataSourceImpl: UserRemoteDataSourceImpl): UserRemoteDataSource | ||
|
||
@Binds | ||
@Singleton | ||
abstract fun bindsUserLocalDataSource(userLocalDataSourceImpl: UserLocalDataSourceImpl): UserLocalDataSource | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package org.sopt.and.di | ||
|
||
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory | ||
import dagger.Module | ||
import dagger.Provides | ||
import dagger.hilt.InstallIn | ||
import dagger.hilt.components.SingletonComponent | ||
import kotlinx.serialization.ExperimentalSerializationApi | ||
import kotlinx.serialization.json.Json | ||
import okhttp3.MediaType.Companion.toMediaTypeOrNull | ||
import okhttp3.OkHttpClient | ||
import okhttp3.logging.HttpLoggingInterceptor | ||
import org.sopt.and.BuildConfig | ||
import retrofit2.Retrofit | ||
import java.util.concurrent.TimeUnit | ||
import javax.inject.Singleton | ||
|
||
@Module | ||
@InstallIn(SingletonComponent::class) | ||
object NetworkModule { | ||
@OptIn(ExperimentalSerializationApi::class) | ||
@Provides | ||
@Singleton | ||
fun providesJson(): Json = | ||
Json { | ||
isLenient = true | ||
prettyPrint = true | ||
explicitNulls = false | ||
ignoreUnknownKeys = true | ||
} | ||
|
||
@Provides | ||
@Singleton | ||
fun providesOkHttpClient( | ||
loggingInterceptor: HttpLoggingInterceptor | ||
): OkHttpClient = | ||
OkHttpClient.Builder().apply { | ||
connectTimeout(10, TimeUnit.SECONDS) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 타임아웃 디테일👍 이부분도 나중에는 상수화 하는게 좋겠네요 |
||
writeTimeout(10, TimeUnit.SECONDS) | ||
readTimeout(10, TimeUnit.SECONDS) | ||
addInterceptor(loggingInterceptor) | ||
addInterceptor { chain -> | ||
val request = chain.request().newBuilder() | ||
.addHeader("Accept", "*/*") | ||
.build() | ||
chain.proceed(request) | ||
} | ||
Comment on lines
+42
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 친구 꼭 필요한가요? |
||
}.build() | ||
|
||
@Provides | ||
@Singleton | ||
fun providesLoggingInterceptor(): HttpLoggingInterceptor = | ||
HttpLoggingInterceptor().apply { | ||
level = HttpLoggingInterceptor.Level.BODY | ||
} | ||
|
||
@ExperimentalSerializationApi | ||
@Provides | ||
@Singleton | ||
fun providesRetrofit( | ||
okHttpClient: OkHttpClient, | ||
json: Json | ||
): Retrofit = | ||
Retrofit.Builder() | ||
.baseUrl(BuildConfig.BASE_URL) | ||
.client(okHttpClient) | ||
.addConverterFactory( | ||
json.asConverterFactory(requireNotNull("application/json".toMediaTypeOrNull())) | ||
) | ||
.build() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package org.sopt.and.di | ||
|
||
import dagger.Binds | ||
import dagger.Module | ||
import dagger.hilt.InstallIn | ||
import dagger.hilt.components.SingletonComponent | ||
import org.sopt.and.data.repositoryimpl.UserRepositoryImpl | ||
import org.sopt.and.domain.repository.UserRepository | ||
import javax.inject.Singleton | ||
|
||
@Module | ||
@InstallIn(SingletonComponent::class) | ||
abstract class RepositoryModule { | ||
@Binds | ||
@Singleton | ||
abstract fun bindUserRepository(userRepositoryImpl: UserRepositoryImpl): UserRepository | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ksp 써보쉴?
kapt와 ksp의 차이점, ksp의 장점은 아실테니 한번 해보시면 좋을거같아요~