-
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/#4] 4주차 필수과제 #9
base: develop
Are you sure you want to change the base?
Changes from all commits
ce4217f
1875f18
8075f87
265bb45
7d6c91f
a99668b
75e5dc5
376f458
135e9ff
d16061b
98f2445
e1323ca
e845e52
3ba2ba5
c08635f
bf155e7
7e6b0c6
c4f2044
35bed35
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 |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package org.sopt.and.data.local | ||
|
||
interface TokenLocalDataSource { | ||
var token: String | ||
fun clearInfo() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.sopt.and.data.local | ||
|
||
import android.content.SharedPreferences | ||
import javax.inject.Inject | ||
|
||
class TokenLocalDataSourceImpl @Inject constructor( | ||
private val sharedPreferences: SharedPreferences | ||
): TokenLocalDataSource { | ||
override var token: String | ||
get() = sharedPreferences.getString(TOKEN, "") ?: "" | ||
set(value) = sharedPreferences.edit().putString(TOKEN, value).apply() | ||
|
||
override fun clearInfo() { | ||
sharedPreferences.edit().clear().apply() | ||
} | ||
|
||
companion object { | ||
private const val TOKEN = "TOKEN" | ||
} | ||
} |
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. 사용하지 않는 친구인 것 같은데! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package org.sopt.and.data.remote | ||
|
||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class ApiResponse<T>( | ||
@SerialName("status") | ||
val status: Int, | ||
@SerialName("message") | ||
val message: String, | ||
@SerialName("result") | ||
val result: T | ||
) |
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. ApiResponse 는 @SerialName 과 변수 선언을 분리했는데 어떤 곳은 한줄로 어떤 곳은 여러 줄로 하신 이유가 궁금해요 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package org.sopt.and.data.remote.dto.request | ||
|
||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class RequestLoginDto( | ||
@SerialName("username") val username: String, | ||
@SerialName("password") val password: String, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package org.sopt.and.data.remote.dto.request | ||
|
||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class RequestUserRegistrationDto ( | ||
@SerialName("username") val username: String, | ||
@SerialName("password") val password: String, | ||
@SerialName("hobby") val hobby: String, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package org.sopt.and.data.remote.dto.response | ||
|
||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class ResponseGetMyHobbyDto( | ||
@SerialName("result") val result: GetMyHobbyResult | ||
) | ||
Comment on lines
+6
to
+9
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. 이렇게 공통되는 부분에 대한 BaseResponse를 만들어두셔도 좋습니다. (ApiResponse의 형태를 이렇게 바꾸면 될 것 같네요!) |
||
|
||
@Serializable | ||
data class GetMyHobbyResult( | ||
@SerialName("hobby") val hobby: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package org.sopt.and.data.remote.dto.response | ||
|
||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class ResponseLoginDto ( | ||
@SerialName("result") val result: LoginResult | ||
) | ||
|
||
@Serializable | ||
data class LoginResult( | ||
@SerialName("token") val token: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package org.sopt.and.data.remote.dto.response | ||
|
||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class ResponseUserRegistrationDto( | ||
@SerialName("result") val result: UserRegistrationResult | ||
) | ||
|
||
@Serializable | ||
data class UserRegistrationResult( | ||
@SerialName("no") val no: Int | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.sopt.and.data.remote.service | ||
|
||
import org.sopt.and.data.remote.dto.request.RequestLoginDto | ||
import org.sopt.and.data.remote.dto.request.RequestUserRegistrationDto | ||
import org.sopt.and.data.remote.dto.response.ResponseLoginDto | ||
import org.sopt.and.data.remote.dto.response.ResponseUserRegistrationDto | ||
import retrofit2.Call | ||
import retrofit2.http.Body | ||
import retrofit2.http.POST | ||
|
||
interface AuthService { | ||
@POST("user") | ||
fun registerUser( | ||
@Body requestUserRegistrationDto: RequestUserRegistrationDto | ||
): Call<ResponseUserRegistrationDto> | ||
|
||
@POST("login") | ||
fun login( | ||
@Body requestLoginDto: RequestLoginDto | ||
): Call<ResponseLoginDto> | ||
} | ||
Comment on lines
+11
to
+21
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. API 엔드포인트가 하드코딩되어 있는데 추후 변경 및 유지보수 할 때 BuildConfig를 활용하거나 별도로 상수화하면 편리하다고 합니다!! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.sopt.and.data.remote.service | ||
|
||
import org.sopt.and.data.remote.dto.response.ResponseGetMyHobbyDto | ||
import retrofit2.Call | ||
import retrofit2.http.GET | ||
import retrofit2.http.Header | ||
|
||
interface UserService { | ||
@GET("user/my-hobby") | ||
fun getMyHobby( | ||
@Header("token") token: String | ||
): Call<ResponseGetMyHobbyDto> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package org.sopt.and.data.repository | ||
|
||
interface TokenRepository { | ||
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. 이 Repository만 data에 위치시키신 이유가 뭔가요! 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. 아 지금 보니까 domain이 따로 없군요 ㅋㅋ |
||
fun getToken(): String | ||
fun setToken(token: String) | ||
fun clearInfo() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.sopt.and.data.repositoryimpl | ||
|
||
import android.util.Log | ||
import org.sopt.and.data.local.TokenLocalDataSource | ||
import org.sopt.and.data.repository.TokenRepository | ||
import javax.inject.Inject | ||
|
||
class TokenRepositoryImpl @Inject constructor( | ||
private val tokenLocalDataSource: TokenLocalDataSource | ||
) : TokenRepository { | ||
override fun getToken(): String = tokenLocalDataSource.token | ||
|
||
override fun setToken(token: String) { | ||
tokenLocalDataSource.token = token | ||
Log.d("TokenDataStore", "Token Saved: $token") | ||
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. 불필요한 로그는 지워줍시다 |
||
} | ||
|
||
override fun clearInfo() { | ||
tokenLocalDataSource.clearInfo() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package org.sopt.and.di | ||
|
||
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory | ||
import kotlinx.serialization.json.Json | ||
import okhttp3.MediaType.Companion.toMediaType | ||
import okhttp3.OkHttpClient | ||
import okhttp3.logging.HttpLoggingInterceptor | ||
import org.sopt.and.BuildConfig | ||
import org.sopt.and.data.remote.service.AuthService | ||
import org.sopt.and.data.remote.service.UserService | ||
import retrofit2.Retrofit | ||
|
||
object ApiFactory { | ||
private const val BASE_URL: String = BuildConfig.BASE_URL | ||
|
||
private val loggingInterceptor = HttpLoggingInterceptor().apply { | ||
level = HttpLoggingInterceptor.Level.BODY | ||
} | ||
|
||
private val client = OkHttpClient.Builder() | ||
.addInterceptor(loggingInterceptor) | ||
.build() | ||
|
||
val retrofit: Retrofit by lazy { | ||
Retrofit.Builder() | ||
.baseUrl(BASE_URL) | ||
.client(client) | ||
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType())) | ||
.build() | ||
} | ||
|
||
inline fun <reified T> create(): T = retrofit.create(T::class.java) | ||
} | ||
|
||
object ServicePool { | ||
val authService = ApiFactory.create<AuthService>() | ||
val userService = ApiFactory.create<UserService>() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
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.repository.TokenRepository | ||
import org.sopt.and.data.repositoryimpl.TokenRepositoryImpl | ||
import javax.inject.Singleton | ||
|
||
@Module | ||
@InstallIn(SingletonComponent::class) | ||
abstract class RepositoryModule { | ||
@Binds | ||
@Singleton | ||
abstract fun bindTokenRepository( | ||
tokenRepositoryImpl: TokenRepositoryImpl | ||
): TokenRepository | ||
} | ||
Comment on lines
+10
to
+19
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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.sopt.and.di | ||
|
||
import android.content.Context | ||
import android.content.SharedPreferences | ||
import dagger.Module | ||
import dagger.Provides | ||
import dagger.hilt.InstallIn | ||
import dagger.hilt.android.qualifiers.ApplicationContext | ||
import dagger.hilt.components.SingletonComponent | ||
import javax.inject.Singleton | ||
|
||
@Module | ||
@InstallIn(SingletonComponent::class) | ||
object SharedPreferencesModule { | ||
@Provides | ||
@Singleton | ||
fun provideSharedPreferences(@ApplicationContext context: Context): SharedPreferences { | ||
return context.getSharedPreferences("token_prefs", Context.MODE_PRIVATE) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.sopt.and.di | ||
|
||
import android.content.SharedPreferences | ||
import dagger.Module | ||
import dagger.Provides | ||
import dagger.hilt.InstallIn | ||
import dagger.hilt.components.SingletonComponent | ||
import org.sopt.and.data.local.TokenLocalDataSource | ||
import org.sopt.and.data.local.TokenLocalDataSourceImpl | ||
import javax.inject.Singleton | ||
|
||
@Module | ||
@InstallIn(SingletonComponent::class) | ||
object TokenLocalDataSourceModule { | ||
@Provides | ||
@Singleton | ||
fun provideTokenLocalDataSource(sharedPreferences: SharedPreferences): TokenLocalDataSource { | ||
return TokenLocalDataSourceImpl(sharedPreferences) | ||
} | ||
} |
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.
clear는 현재 모든 SharedPreferences 데이터를 지울 수 있으므로, 나중에 Token만 지우고 싶을 때는 clear() 대신 remove(Token)을 사용할 수 있다고 합니다!