Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
98391c3
[Feat] #48 - LoginVC, SplashVC 팩토리 메서드 추가 및 접근제한자 변경
L-j-h-c Dec 18, 2022
6c47026
[Feat] #48 - SpalshVC부터 HomeVC까지 화면전환
L-j-h-c Dec 18, 2022
f030f41
[Feat] #48 - HomeVC 및 StorageVC 팩토리 메서드 추가 및 탭바 연결
L-j-h-c Dec 18, 2022
b137f2f
[Feat] #48 - 홈VC 및 마이페이지 VC 플로우 연결
L-j-h-c Dec 18, 2022
586f199
[Refactor] #48 - Router 및 Service 토큰 상수 및 nonEmpty 메서드 작성
L-j-h-c Dec 19, 2022
6816b80
[Refactor] #48 - Constants 및 DefaultUserDefaultManager 네이밍 수정
L-j-h-c Dec 19, 2022
5e0f27b
[Feat] #48 - 토큰 재발급 API 구현 및 SplashVC 자동로그인 처리
L-j-h-c Dec 19, 2022
fdb74fb
[Feat] #48 - 로그아웃 및 회원탈퇴 비즈니스 로직 구현
L-j-h-c Dec 19, 2022
5789581
[Feat] #48 - 로그아웃 및 회원탈퇴 API 구현
L-j-h-c Dec 19, 2022
11284ae
[Feat] #48 - 유저 정보 불러오기 API 구현
L-j-h-c Dec 19, 2022
648bf06
[Feat] #48 - 닉네임 변경 API 구현
L-j-h-c Dec 19, 2022
051609f
[Feat] #48 - 푸시알림 OnOff, time 설정 API 및 비즈니스 로직 구현
L-j-h-c Dec 19, 2022
b79ac50
Merge branch 'develop' of https://github.com/TeamRecorDream/RecorDrea…
L-j-h-c Dec 19, 2022
752f5dd
[Feat] #48 - MyPageVC pushSetting 바인딩 로직 변경
L-j-h-c Dec 19, 2022
a5f7803
Merge branch 'develop' of https://github.com/TeamRecorDream/RecorDrea…
L-j-h-c Dec 20, 2022
62ac313
[Fix] #48 - push notice API에 isAcitve 바디 파라미터 추가
L-j-h-c Dec 20, 2022
e39d671
[Fix] #48 - 코드리뷰 반영
L-j-h-c Dec 20, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
// Copyright © 2022 RecorDream. All rights reserved.
//

public struct C {
public struct Constants {
public static let KAKAO_APP_KEY = "000e1e31f022f98fbe16c76ab287abd1"
public static let accessToken = "accessToken"
public static let refreshToken = "refreshToken"
public static let nickname = "nickname"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,17 @@
// Copyright © 2022 RecorDream. All rights reserved.
//

public enum Key: String {
public enum UserDefaultKey: String {
case platform = "key.platform"
case userToken = "key.userToken"
case accessToken = "key.accessToken"
case refreshToken = "key.refreshToken"
case nickname = "key.nickname"
}

public extension UserDefaultKey {
enum Constants {
static var kakao = "kakao"
static var apple = "apple"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,44 @@
import Foundation

public protocol UserDefaultManager {
static func set(value: Any, keyPath: Key.RawValue)
static func string(key: Key) -> String?
static func int(key: Key) -> Int?
static func remove(key: Key)
static func set(value: Any, keyPath: UserDefaultKey)
static func string(key: UserDefaultKey) -> String?
static func int(key: UserDefaultKey) -> Int?
static func remove(key: UserDefaultKey)
static func clearUserData()
}

public class DefaultUserDefaultManager: UserDefaultManager {
public static func set(value: Any, keyPath: Key.RawValue) {
UserDefaults.standard.setValue(value, forKeyPath: keyPath)
public static func set(value: Any, keyPath: UserDefaultKey) {
UserDefaults.standard.setValue(value, forKeyPath: keyPath.rawValue)
}
public static func string(key: Key) -> String? {
public static func string(key: UserDefaultKey) -> String? {
return UserDefaults.standard.string(forKey: key.rawValue)
}
public static func int(key: Key) -> Int? {
public static func int(key: UserDefaultKey) -> Int? {
return UserDefaults.standard.integer(forKey: key.rawValue)
}
public static func remove(key: Key) {
public static func remove(key: UserDefaultKey) {
UserDefaults.standard.removeObject(forKey: key.rawValue)
Comment thread
Suyeon9911 marked this conversation as resolved.
}
public static func clearUserData() {
self.remove(key: .platform)
self.remove(key: .userToken)
self.remove(key: .accessToken)
self.remove(key: .refreshToken)
self.remove(key: .nickname)
}
}

public extension DefaultUserDefaultManager {
static var accessToken: String? {
return string(key: .accessToken)
}

static var refreshToken: String? {
return string(key: .refreshToken)
}

static var isKakaoUser: Bool {
return string(key: .platform) == UserDefaultKey.Constants.kakao
}
}
24 changes: 24 additions & 0 deletions RecorDream-iOS/Projects/Core/Sources/UIKit+/UIApplication+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
import UIKit

public extension UIApplication {
static var topRootViewController: UIViewController? {
UIWindow.keyWindowGetter?.rootViewController
}

class func getMostTopViewController(base: UIViewController? = nil) -> UIViewController? {

var baseVC: UIViewController?
Expand All @@ -33,5 +37,25 @@ public extension UIApplication {
}
return baseVC
}

static func setRootViewController(window: UIWindow, viewController: UIViewController, withAnimation: Bool) {
if !withAnimation {
window.rootViewController = viewController
window.makeKeyAndVisible()
return
}

if let snapshot = window.snapshotView(afterScreenUpdates: true) {
viewController.view.addSubview(snapshot)
window.rootViewController = viewController
window.makeKeyAndVisible()

UIView.animate(withDuration: 0.4, animations: {
snapshot.layer.opacity = 0
}, completion: { _ in
snapshot.removeFromSuperview()
})
}
}
Comment thread
Suyeon9911 marked this conversation as resolved.
}

22 changes: 22 additions & 0 deletions RecorDream-iOS/Projects/Core/Sources/UIKit+/UIWindow+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// UIWindow+.swift
// RD-Core
//
// Created by Junho Lee on 2022/12/19.
// Copyright © 2022 RecorDream-iOS. All rights reserved.
//

import UIKit

public extension UIWindow {
static var keyWindowGetter: UIWindow? {
if #available(iOS 13, *) {
return (UIApplication.shared.connectedScenes
.compactMap { $0 as? UIWindowScene }
.flatMap { $0.windows }
.first { $0.isKeyWindow })
} else {
return UIApplication.shared.keyWindow
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// UserInfoTransform.swift
// Data
//
// Created by Junho Lee on 2022/12/19.
// Copyright © 2022 RecorDream-iOS. All rights reserved.
//

import Domain
import RD_Network

import Foundation

extension UserInfoResponse {
func toDomain() -> MyPageEntity? {
var notEmptyName = self.nickname
notEmptyName = self.nickname == ""
? "닉네임"
: self.nickname
return .init(userName: notEmptyName,
email: self.email,
pushOnOff: self.time != nil,
pushTime: self.time)
}
Comment thread
Suyeon9911 marked this conversation as resolved.
}
Empty file.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import Foundation

import Domain
import RD_Core
import RD_Network

import RxSwift
Expand All @@ -18,7 +19,7 @@ public final class DefaultAuthRepository {
private let authService: AuthService
private let disposeBag = DisposeBag()

init(authService: AuthService) {
public init(authService: AuthService) {
self.authService = authService
}
}
Expand All @@ -29,7 +30,36 @@ extension DefaultAuthRepository: AuthRepository {
self.authService.login(kakaoToken: request.kakaoToken, appleToken: request.appleToken, fcmToken: request.fcmToken)
.subscribe(onNext: { response in
guard let response = response else { return }
observer.onNext(.init(duplicated: response.duplicated, accessToken: response.accessToken, refreshToken: response.refreshToken))
observer.onNext(.init(duplicated: response.duplicated, accessToken: response.accessToken, refreshToken: response.refreshToken, nickname: response.nickname))
}, onError: { err in
observer.onError(err)
})
.disposed(by: self.disposeBag)
return Disposables.create()
}
}

public func requestReissuance() -> Observable<Bool> {
return Observable.create { observer in
self.authService.reissuance()
.subscribe(onNext: { response in
guard let response = response else {
observer.onNext(false)
return
}

if response.status == 403 {
observer.onNext(true)
return
}

Comment thread
Suyeon9911 marked this conversation as resolved.
guard let token = response.data else {
observer.onNext(false)
return
}
DefaultUserDefaultManager.set(value: token.accessToken, keyPath: .accessToken)
DefaultUserDefaultManager.set(value: token.refreshToken, keyPath: .refreshToken)
observer.onNext(true)
Comment on lines +51 to +63
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

슬랙에서 논의하셨던 + 줌에서 말씀해주셨던 부분이네요!
저는 단순히 토큰 재발급 API를 앱 실행 시마다 호출하여 다시 로그인하는 방식을 생각했는데, 이렇게 처리하게 되면 백・프론트 모두에서 효율적이겠네요... 배워갑니다 👍

}, onError: { err in
observer.onError(err)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,54 +7,134 @@
//

import Domain
import RD_Core
import RD_Network

import RxSwift

public class DefaultMyPageRepository {

private let disposeBag = DisposeBag()

public init() {
private var authService: AuthService
private var userService: UserService

public init(authService: AuthService, userService: UserService) {
self.authService = authService
self.userService = userService
}
}

extension DefaultMyPageRepository: MyPageRepository {
public func changeUserNickname(nickname: String) -> RxSwift.Observable<Bool> {
return Observable.create { observer in
self.userService.changeNickname(nickname: nickname)
.subscribe(onNext: { nicknameChangeSuccessed in
guard nicknameChangeSuccessed else {
observer.onNext(false)
return
}
observer.onNext(true)
}, onError: { err in
observer.onError(err)
})
.disposed(by: self.disposeBag)
return Disposables.create()
}
}

public func fetchUserInformation() -> Observable<MyPageEntity> {
return Observable.create { observer in
observer.onNext(.init(userName: "샘플닉네임",
email: "[email protected]",
pushOnOff: true,
pushTime: "08:00"))
self.userService.fetchUserInfo()
.subscribe(onNext: { response in
guard let entity = response?.toDomain() else {
return
}
observer.onNext(entity)
}, onError: { err in
observer.onError(err)
})
.disposed(by: self.disposeBag)
return Disposables.create()
}
}

public func userLogout() -> Observable<Bool> {
return Observable.create { observer in
observer.onNext(true)
guard let fcmToken = DefaultUserDefaultManager.string(key: UserDefaultKey.userToken) else { return Disposables.create() }
self.authService.logout(fcmToken: fcmToken)
.subscribe(onNext: { logoutSuccess in
guard logoutSuccess else {
observer.onNext(false)
return
}
Comment thread
L-j-h-c marked this conversation as resolved.
DefaultUserDefaultManager.clearUserData()
observer.onNext(true)
}, onError: { err in
observer.onError(err)
})
.disposed(by: self.disposeBag)
return Disposables.create()
}
}

public func userWithdrawal() -> Observable<Bool> {
return Observable.create { observer in
observer.onNext(true)
self.userService.withDrawal()
.subscribe(onNext: { withDrawalSuccess in
guard withDrawalSuccess else {
observer.onNext(false)
return
}
DefaultUserDefaultManager.clearUserData()
observer.onNext(true)
}, onError: { err in
observer.onError(err)
})
.disposed(by: self.disposeBag)
return Disposables.create()
}
}

public func enablePushNotice(time: String) -> Observable<String> {
public func enablePushNotice(time: String) -> Observable<Bool> {
return Observable.create { observer in
observer.onNext("AM 08:20")
self.userService.changeNoticeStatus(isActive: true)
.compactMap { $0?.isActive }
.do(onNext: { isActive in
guard isActive else {
observer.onNext(false)
return
}
})
Comment on lines +102 to +107
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

이 부분은 토글 on/off 동작이 연속적으로 수행될 때를 잡아주는... 그런 부분인가요...???

.filter { $0 }
.flatMap { _ in self.userService.postNoticeTime(time: time) }
.subscribe(onNext: { changeTimeSuccessed in
guard changeTimeSuccessed else {
observer.onNext(false)
return
}
observer.onNext(true)
}, onError: { err in
observer.onError(err)
})
.disposed(by: self.disposeBag)
return Disposables.create()
}
}

public func disablePushNotice() -> Observable<Void> {
public func disablePushNotice() -> Observable<Bool> {
return Observable.create { observer in
observer.onNext(())
self.userService.changeNoticeStatus(isActive: false)
.subscribe(onNext: { response in
guard let isActive = response?.isActive else {
observer.onNext(false)
return
}

observer.onNext(!isActive)
}, onError: { err in
observer.onError(err)
})
.disposed(by: self.disposeBag)
return Disposables.create()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ public struct AuthEntity: Codable {
public let duplicated: Bool
public let accessToken: String
public let refreshToken: String
public let nickname: String

public init(duplicated: Bool, accessToken: String, refreshToken: String) {
public init(duplicated: Bool, accessToken: String, refreshToken: String, nickname: String) {
self.duplicated = duplicated
self.accessToken = accessToken
self.refreshToken = refreshToken
self.nickname = nickname
}
}
Loading