Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions WSSiOS/WSSiOS/Network/Auth/AuthService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import Foundation
import RxSwift

protocol AuthService {
func loginWithApple(authorizationCode: String,
idToken: String) -> Single<LoginResponse>
func loginWithApple(appleLoginData: AppleLoginRequest) -> Single<LoginResponse>
func loginWithKakao(_ kakaoAccessToken: String) -> Single<LoginResponse>
func reissueToken() -> Single<ReissueResponse>
func postWithdrawId(withdrawData: WithdrawRequest) -> Single<Void>
Expand All @@ -21,8 +20,8 @@ protocol AuthService {


final class DefaultAuthService: NSObject, Networking, AuthService {
func loginWithApple(authorizationCode: String, idToken: String) -> RxSwift.Single<LoginResponse> {
guard let appleLoginBody = try? JSONEncoder().encode(AppleLoginBody(authorizationCode: authorizationCode, idToken: idToken)) else {
func loginWithApple(appleLoginData: AppleLoginRequest) -> RxSwift.Single<LoginResponse> {
guard let appleLoginBody = try? JSONEncoder().encode(appleLoginData) else {
return Single.error(NetworkServiceError.invalidRequestError)
}

Expand Down
6 changes: 3 additions & 3 deletions WSSiOS/WSSiOS/Network/Keyword/KeywordService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import Foundation
import RxSwift

protocol KeywordService {
func searchKeyword(query: String?) -> Single<SearchKeywordResult>
func searchKeyword(query: String?) -> Single<SearchKeywordResponse>
}

final class DefaultKeywordService: NSObject, Networking, KeywordService {
func searchKeyword(query: String? = nil) -> RxSwift.Single<SearchKeywordResult> {
func searchKeyword(query: String? = nil) -> RxSwift.Single<SearchKeywordResponse> {
var searchKeywordQueryItems: [URLQueryItem] = []

if let query {
Expand All @@ -32,7 +32,7 @@ final class DefaultKeywordService: NSObject, Networking, KeywordService {

return tokenCheckURLSession.rx.data(request: request)
.map { try self.decode(data: $0,
to: SearchKeywordResult.self) }
to: SearchKeywordResponse.self) }
.asSingle()

} catch {
Expand Down
42 changes: 9 additions & 33 deletions WSSiOS/WSSiOS/Network/NovelReview/NovelReviewService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,14 @@ import Foundation
import RxSwift

protocol NovelReviewService {
func postNovelReview(novelId: Int,
userNovelRating: Float,
status: String,
startDate: String?,
endDate: String?,
attractivePoints: [String],
keywordIds: [Int]) -> Single<Void>
func putNovelReview(novelId: Int,
userNovelRating: Float,
status: String,
startDate: String?,
endDate: String?,
attractivePoints: [String],
keywordIds: [Int]) -> Single<Void>
func getNovelReview(novelId: Int) -> Single<NovelReviewResult>
func postNovelReview(novelReviewData: PostNovelReviewRequest) -> Single<Void>
func putNovelReview(novelId: Int, novelReviewData: PutNovelReviewRequest) -> Single<Void>
func getNovelReview(novelId: Int) -> Single<NovelReviewResponse>
}

final class DefaultNovelReviewService: NSObject, Networking, NovelReviewService {
func postNovelReview(novelId: Int,
userNovelRating: Float,
status: String,
startDate: String?,
endDate: String?,
attractivePoints: [String],
keywordIds: [Int]) -> Single<Void> {
guard let novelReviewContentData = try? JSONEncoder().encode(PostNovelReviewContent(novelId: novelId, userNovelRating: userNovelRating, status: status, startDate: startDate, endDate: endDate, attractivePoints: attractivePoints, keywordIds: keywordIds)) else {
func postNovelReview(novelReviewData: PostNovelReviewRequest) -> Single<Void> {
guard let novelReviewContentData = try? JSONEncoder().encode(novelReviewData) else {
return Single.error(NetworkServiceError.invalidRequestError)
}

Expand All @@ -55,14 +37,8 @@ final class DefaultNovelReviewService: NSObject, Networking, NovelReviewService
}
}

func putNovelReview(novelId: Int,
userNovelRating: Float,
status: String,
startDate: String?,
endDate: String?,
attractivePoints: [String],
keywordIds: [Int]) -> Single<Void> {
guard let novelReviewContentData = try? JSONEncoder().encode(PutNovelReviewContent(userNovelRating: userNovelRating, status: status, startDate: startDate, endDate: endDate, attractivePoints: attractivePoints, keywordIds: keywordIds)) else {
func putNovelReview(novelId: Int, novelReviewData: PutNovelReviewRequest) -> Single<Void> {
guard let novelReviewContentData = try? JSONEncoder().encode(novelReviewData) else {
return Single.error(NetworkServiceError.invalidRequestError)
}

Expand All @@ -82,7 +58,7 @@ final class DefaultNovelReviewService: NSObject, Networking, NovelReviewService
}
}

func getNovelReview(novelId: Int) -> Single<NovelReviewResult> {
func getNovelReview(novelId: Int) -> Single<NovelReviewResponse> {
do {
let request = try makeHTTPRequest(method: .get,
path: URLs.NovelReview.getNovelReview(novelId: novelId),
Expand All @@ -93,7 +69,7 @@ final class DefaultNovelReviewService: NSObject, Networking, NovelReviewService

return tokenCheckURLSession.rx.data(request: request)
.map { try self.decode(data: $0,
to: NovelReviewResult.self) }
to: NovelReviewResponse.self) }
.asSingle()

} catch {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//
// AuthResult.swift
// Auth.swift
// WSSiOS
//
// Created by Hyowon Jeon on 11/2/24.
//

import Foundation

struct AppleLoginBody: Codable {
struct AppleLoginRequest: Encodable {
let authorizationCode: String
let idToken: String
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

struct NovelReviewResult: Codable {
struct NovelReviewResponse: Decodable {
let novelTitle: String
let status: String?
let startDate: String?
Expand All @@ -17,7 +17,7 @@ struct NovelReviewResult: Codable {
let keywords: [KeywordData]
}

struct PostNovelReviewContent: Codable {
struct PostNovelReviewRequest: Encodable {
let novelId: Int
let userNovelRating: Float
let status: String
Expand All @@ -27,7 +27,7 @@ struct PostNovelReviewContent: Codable {
let keywordIds: [Int]
}

struct PutNovelReviewContent: Codable {
struct PutNovelReviewRequest: Encodable {
let userNovelRating: Float
let status: String
let startDate: String?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//
// SearchKeywordResult.swift
// SearchKeywordResponse.swift
// WSSiOS
//
// Created by Hyowon Jeon on 9/27/24.
//

import Foundation

struct SearchKeywordResult: Codable {
struct SearchKeywordResponse: Decodable {
let categories: [KeywordCategory]
}

Expand Down
36 changes: 36 additions & 0 deletions WSSiOS/WSSiOS/Source/Data/Entity/AuthEntity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// AuthEntity.swift
// WSSiOS
//
// Created by Hyowon Jeon on 3/23/25.
//

import Foundation

struct AppleLoginEntity {
let authorizationCode: Data
let idToken: Data
}

extension AppleLoginEntity {
func toDTO() -> AppleLoginRequest {
let authorizationCode = String(data: authorizationCode, encoding: String.Encoding.utf8)!
let idToken = String(data: idToken, encoding: String.Encoding.utf8)!
return AppleLoginRequest(authorizationCode: authorizationCode,
idToken: idToken)
}
}

struct LoginEntity {
let Authorization: String
let refreshToken: String
let isRegister: Bool
}

extension LoginResponse {
func toEntity() -> LoginEntity {
return LoginEntity(Authorization: self.Authorization,
refreshToken: self.refreshToken,
isRegister: self.isRegister)
}
}
86 changes: 86 additions & 0 deletions WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//
// NovelReviewEntity.swift
// WSSiOS
//
// Created by Hyowon Jeon on 3/23/25.
//

import Foundation

struct NovelReviewEntity {
let novelTitle: String
let status: ReadStatus?
let startDate: Date?
let endDate: Date?
let userNovelRating: Float
let attractivePoints: [AttractivePoint?]
let keywords: [KeywordData]
}

extension NovelReviewResponse {
func toEntity() -> NovelReviewEntity {
let dateFormatter = DateFormatter().then {
$0.dateFormat = "yyyy-MM-dd"
$0.timeZone = TimeZone(identifier: "ko_KR")
}
Comment on lines +22 to +25
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 변수를 DateFormatter 익스텐션으로 빼서 static 변수로 만드는 게 기능상 좋아보입니다!

DateFormatter는 내부적인 계산이 많이 들어가는 값이기 떄문에 static 변수로 빼서 한번만 생성되고 앱 내에서 재사용 되는 방법이 어떨까요?

extension DateFormatter {
    static let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        formatter.timeZone = TimeZone(identifier: "ko_KR")
        return formatter
    }()
}
func toEntity() -> NovelReviewEntity {
    let formatter = DateFormatter.dateFormatter
    
    let startDate = self.startDate.flatMap { formatter.date(from: $0) }
    let endDate = self.endDate.flatMap { formatter.date(from: $0) }
}


let startDate = self.startDate.flatMap { dateFormatter.date(from: $0) }
let endDate = self.endDate.flatMap { dateFormatter.date(from: $0) }
let readStatus = self.status.flatMap { ReadStatus(rawValue: $0) }
let attractivePoints = self.attractivePoints.map { AttractivePoint(rawValue: $0) }

return NovelReviewEntity(novelTitle: self.novelTitle,
status: readStatus,
startDate: startDate,
endDate: endDate,
userNovelRating: self.userNovelRating,
attractivePoints: attractivePoints,
keywords: self.keywords)
}
}

struct PostNovelReviewEntity {
let novelId: Int
let userNovelRating: Float
let status: ReadStatus
let startDate: String?
let endDate: String?
let attractivePoints: [AttractivePoint?]
let keywordIds: [Int]
}

extension PostNovelReviewEntity {
func toDTO() -> PostNovelReviewRequest {
let statusString = self.status.rawValue
let attractivePoints = self.attractivePoints.compactMap { $0?.rawValue }
return PostNovelReviewRequest(novelId: self.novelId,
userNovelRating: self.userNovelRating,
status: statusString,
startDate: self.startDate,
endDate: self.endDate,
attractivePoints: attractivePoints,
keywordIds: self.keywordIds)
}
}

struct PutNovelReviewEntity {
let userNovelRating: Float
let status: ReadStatus
let startDate: String?
let endDate: String?
let attractivePoints: [AttractivePoint?]
let keywordIds: [Int]
}

extension PutNovelReviewEntity {
func toDTO() -> PutNovelReviewRequest {
let statusString = self.status.rawValue
let attractivePoints = self.attractivePoints.compactMap { $0?.rawValue }
return PutNovelReviewRequest(userNovelRating: self.userNovelRating,
status: statusString,
startDate: self.startDate,
endDate: self.endDate,
attractivePoints: attractivePoints,
keywordIds: self.keywordIds)
}
}
18 changes: 18 additions & 0 deletions WSSiOS/WSSiOS/Source/Data/Entity/SearchKeywordEntity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// SearchKeywordEntity.swift
// WSSiOS
//
// Created by Hyowon Jeon on 3/23/25.
//

import Foundation

struct SearchKeywordEntity {
let categories: [KeywordCategory]
}

extension SearchKeywordResponse {
func toEntity() -> SearchKeywordEntity {
return SearchKeywordEntity(categories: self.categories)
}
}
13 changes: 8 additions & 5 deletions WSSiOS/WSSiOS/Source/Data/Repository/AuthRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import RxKakaoSDKAuth
import RxSwift

protocol AuthRepository {
func loginWithApple(authorizationCode: String, idToken: String) -> Observable<LoginResponse>
func loginWithKakao(_ kakaoAccessToken: OAuthToken) -> Single<LoginResponse>
func loginWithApple(appleLoginData: AppleLoginEntity) -> Observable<LoginEntity>
func loginWithKakao(_ kakaoAccessToken: OAuthToken) -> Single<LoginEntity>
func postWithdrawId(withdrawData: WithdrawRequest) -> Observable<Void>
func postLogout(refreshToken: String, deviceIdentifier: String) -> Observable<Void>
}
Expand All @@ -26,13 +26,16 @@ struct DefaultAuthRepository: AuthRepository {
self.authService = authService
}

func loginWithApple(authorizationCode: String, idToken: String) -> Observable<LoginResponse> {
return authService.loginWithApple(authorizationCode: authorizationCode, idToken: idToken)
func loginWithApple(appleLoginData: AppleLoginEntity) -> Observable<LoginEntity> {
let appleLoginDataDTO = appleLoginData.toDTO()
return authService.loginWithApple(appleLoginData: appleLoginDataDTO)
.map { $0.toEntity() }
.asObservable()
}

func loginWithKakao(_ kakaoAccessToken: OAuthToken) -> Single<LoginResponse> {
func loginWithKakao(_ kakaoAccessToken: OAuthToken) -> Single<LoginEntity> {
return authService.loginWithKakao(kakaoAccessToken.accessToken)
.map { $0.toEntity() }
}

func postWithdrawId(withdrawData: WithdrawRequest) -> Observable<Void> {
Expand Down
5 changes: 3 additions & 2 deletions WSSiOS/WSSiOS/Source/Data/Repository/KeywordRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
import RxSwift

protocol KeywordRepository {
func searchKeyword(query: String?) -> Observable<SearchKeywordResult>
func searchKeyword(query: String?) -> Observable<SearchKeywordEntity>
}

struct DefaultKeywordRepository: KeywordRepository {
Expand All @@ -21,8 +21,9 @@ struct DefaultKeywordRepository: KeywordRepository {
self.keywordService = keywordService
}

func searchKeyword(query: String?) -> Observable<SearchKeywordResult> {
func searchKeyword(query: String?) -> Observable<SearchKeywordEntity> {
return keywordService.searchKeyword(query: query)
.map{ $0.toEntity() }
.asObservable()
}
}
Loading