Skip to content
Merged
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
56 changes: 40 additions & 16 deletions Wable-iOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,21 @@
DD29686E2D6DAD5F00143851 /* Bundle+.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD29676D2D6DAC3100143851 /* Bundle+.swift */; };
DD29686F2D6DAD5F00143851 /* MoyaLoggingPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD29676C2D6DAC3100143851 /* MoyaLoggingPlugin.swift */; };
DD2968702D6DAD5F00143851 /* TokenStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2967652D6DAC3100143851 /* TokenStorage.swift */; };
DD2968712D6DAD5F00143851 /* KeychainWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2967672D6DAC3100143851 /* KeychainWrapper.swift */; };
DD2968722D6DAD5F00143851 /* KeychainError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2967682D6DAC3100143851 /* KeychainError.swift */; };
DD2968732D6DAD5F00143851 /* APIProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD29676A2D6DAC3100143851 /* APIProvider.swift */; };
DD2968742D6DAD5F00143851 /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD29676B2D6DAC3100143851 /* NetworkError.swift */; };
DD2968792D6DAE3500143851 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DD2968772D6DAE2200143851 /* GoogleService-Info.plist */; };
DD29687C2D6DB27F00143851 /* OAuthenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD29687B2D6DB27200143851 /* OAuthenticator.swift */; };
DD29687E2D6DC70700143851 /* OAuthCredential.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD29687D2D6DC70100143851 /* OAuthCredential.swift */; };
DD69C5902D71A3BE000A3349 /* OAuthTokenProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD69C58F2D71A3B6000A3349 /* OAuthTokenProvider.swift */; };
DD87931C2D7044E7001212AE /* OAuthErrorMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD87931B2D7044E0001212AE /* OAuthErrorMonitor.swift */; };
DDCCA3932D738CD500658122 /* UserSessionRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCCA3922D738CD100658122 /* UserSessionRepository.swift */; };
DDCCA3952D73928900658122 /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCCA3942D73928400658122 /* UserSession.swift */; };
DDCCA3972D73988000658122 /* UserSessionRepositoryImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCCA3962D73987600658122 /* UserSessionRepositoryImpl.swift */; };
DDED594C2D784EB100A0BEF1 /* KeychainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDED594A2D784EB100A0BEF1 /* KeychainStorage.swift */; };
DDED594D2D784EB100A0BEF1 /* UserDefaultsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDED594B2D784EB100A0BEF1 /* UserDefaultsStorage.swift */; };
DDED594F2D784EC000A0BEF1 /* LocalKeyValueStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDED594E2D784EC000A0BEF1 /* LocalKeyValueStorage.swift */; };
DDED59512D7850E600A0BEF1 /* LocalError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDED59502D7850E300A0BEF1 /* LocalError.swift */; };
DDED59532D785B9700A0BEF1 /* TokenError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDED59522D785B9400A0BEF1 /* TokenError.swift */; };
DDF2CC842D71FA8A000F1919 /* Then in Frameworks */ = {isa = PBXBuildFile; productRef = DDF2CC832D71FA8A000F1919 /* Then */; };
DDF2CC872D71FA96000F1919 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = DDF2CC862D71FA96000F1919 /* SnapKit */; };
DDF2CC8A2D71FADB000F1919 /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = DDF2CC892D71FADB000F1919 /* Lottie */; };
Expand Down Expand Up @@ -175,8 +181,6 @@
DD2967602D6DAC3100143851 /* Publisher+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Publisher+.swift"; sourceTree = "<group>"; };
DD2967622D6DAC3100143851 /* WableLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WableLogger.swift; sourceTree = "<group>"; };
DD2967652D6DAC3100143851 /* TokenStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenStorage.swift; sourceTree = "<group>"; };
DD2967672D6DAC3100143851 /* KeychainWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainWrapper.swift; sourceTree = "<group>"; };
DD2967682D6DAC3100143851 /* KeychainError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainError.swift; sourceTree = "<group>"; };
DD29676A2D6DAC3100143851 /* APIProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIProvider.swift; sourceTree = "<group>"; };
DD29676B2D6DAC3100143851 /* NetworkError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkError.swift; sourceTree = "<group>"; };
DD29676C2D6DAC3100143851 /* MoyaLoggingPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoyaLoggingPlugin.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -299,6 +303,14 @@
DD8CEF472D6A007900DBE580 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
DD8CEF482D6A007900DBE580 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
DD8CEFF82D6A00BB00DBE580 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = "Base.lproj/LaunchScreen 2.storyboard"; sourceTree = "<group>"; };
DDCCA3922D738CD100658122 /* UserSessionRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionRepository.swift; sourceTree = "<group>"; };
DDCCA3942D73928400658122 /* UserSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSession.swift; sourceTree = "<group>"; };
DDCCA3962D73987600658122 /* UserSessionRepositoryImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionRepositoryImpl.swift; sourceTree = "<group>"; };
DDED594A2D784EB100A0BEF1 /* KeychainStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainStorage.swift; sourceTree = "<group>"; };
DDED594B2D784EB100A0BEF1 /* UserDefaultsStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsStorage.swift; sourceTree = "<group>"; };
DDED594E2D784EC000A0BEF1 /* LocalKeyValueStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalKeyValueStorage.swift; sourceTree = "<group>"; };
DDED59502D7850E300A0BEF1 /* LocalError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalError.swift; sourceTree = "<group>"; };
DDED59522D785B9400A0BEF1 /* TokenError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenError.swift; sourceTree = "<group>"; };
DE67A9EA2D7211070021BDE1 /* Like.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Like.swift; sourceTree = "<group>"; };
DE67A9EE2D7213D90021BDE1 /* Opacity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Opacity.swift; sourceTree = "<group>"; };
DEDC29112D7207610073D512 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
Expand Down Expand Up @@ -421,19 +433,11 @@
isa = PBXGroup;
children = (
DD2967652D6DAC3100143851 /* TokenStorage.swift */,
DDED59522D785B9400A0BEF1 /* TokenError.swift */,
);
path = Token;
sourceTree = "<group>";
};
DD2967692D6DAC3100143851 /* Keychain */ = {
isa = PBXGroup;
children = (
DD2967672D6DAC3100143851 /* KeychainWrapper.swift */,
DD2967682D6DAC3100143851 /* KeychainError.swift */,
);
path = Keychain;
sourceTree = "<group>";
};
DD29676E2D6DAC3100143851 /* Bundle */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -708,8 +712,8 @@
DD2967BC2D6DAC3100143851 /* Infra */ = {
isa = PBXGroup;
children = (
DDED59492D784E9000A0BEF1 /* Local */,
DD2967662D6DAC3100143851 /* Token */,
DD2967692D6DAC3100143851 /* Keychain */,
DD2967BB2D6DAC3100143851 /* Network */,
);
path = Infra;
Expand All @@ -718,6 +722,7 @@
DD2967CA2D6DAC3100143851 /* RepositoryImpl */ = {
isa = PBXGroup;
children = (
DDCCA3962D73987600658122 /* UserSessionRepositoryImpl.swift */,
DD2967BD2D6DAC3100143851 /* LoginRepositoryImpl.swift */,
DD2967BE2D6DAC3100143851 /* AccountRepositoryImpl.swift */,
DD2967BF2D6DAC3100143851 /* ProfileRepositoryImpl.swift */,
Expand Down Expand Up @@ -771,6 +776,7 @@
DD2967E52D6DAC3100143851 /* RepositoryInterface */ = {
isa = PBXGroup;
children = (
DDCCA3922D738CD100658122 /* UserSessionRepository.swift */,
DD2967D82D6DAC3100143851 /* LoginRepository.swift */,
DD2967D92D6DAC3100143851 /* AccountRepository.swift */,
DD2967DA2D6DAC3100143851 /* ProfileRepository.swift */,
Expand All @@ -791,6 +797,7 @@
DD2967F72D6DAC3100143851 /* Entity */ = {
isa = PBXGroup;
children = (
DDCCA3942D73928400658122 /* UserSession.swift */,
DD2967E72D6DAC3100143851 /* User.swift */,
DD2967E82D6DAC3100143851 /* Token.swift */,
DD2967E92D6DAC3100143851 /* Account.swift */,
Expand Down Expand Up @@ -866,6 +873,17 @@
path = App;
sourceTree = "<group>";
};
DDED59492D784E9000A0BEF1 /* Local */ = {
isa = PBXGroup;
children = (
DDED594E2D784EC000A0BEF1 /* LocalKeyValueStorage.swift */,
DDED594A2D784EB100A0BEF1 /* KeychainStorage.swift */,
DDED594B2D784EB100A0BEF1 /* UserDefaultsStorage.swift */,
DDED59502D7850E300A0BEF1 /* LocalError.swift */,
);
path = Local;
sourceTree = "<group>";
};
DEDC29122D7208650073D512 /* Enum */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -996,9 +1014,12 @@
DD2968122D6DACF700143851 /* Community.swift in Sources */,
DD2968132D6DACF700143851 /* TriggerType.swift in Sources */,
DD2968142D6DACF700143851 /* AccountInfo.swift in Sources */,
DDCCA3972D73988000658122 /* UserSessionRepositoryImpl.swift in Sources */,
DD2968152D6DACF700143851 /* Announcement.swift in Sources */,
DD2968512D6DAD4400143851 /* UpdateUserProfile.swift in Sources */,
DD2968522D6DAD4400143851 /* DTO.swift in Sources */,
DDED594C2D784EB100A0BEF1 /* KeychainStorage.swift in Sources */,
DDED594D2D784EB100A0BEF1 /* UserDefaultsStorage.swift in Sources */,
DD2968532D6DAD4400143851 /* BaseResponse.swift in Sources */,
DD2968542D6DAD4400143851 /* CreateBan.swift in Sources */,
DD2968552D6DAD4400143851 /* CreateComment.swift in Sources */,
Expand Down Expand Up @@ -1028,10 +1049,9 @@
DD2968412D6DAD2F00143851 /* Empty.swift in Sources */,
DD2968422D6DAD2F00143851 /* FetchNotices.swift in Sources */,
DD29686E2D6DAD5F00143851 /* Bundle+.swift in Sources */,
DDED59532D785B9700A0BEF1 /* TokenError.swift in Sources */,
DD29686F2D6DAD5F00143851 /* MoyaLoggingPlugin.swift in Sources */,
DD2968702D6DAD5F00143851 /* TokenStorage.swift in Sources */,
DD2968712D6DAD5F00143851 /* KeychainWrapper.swift in Sources */,
DD2968722D6DAD5F00143851 /* KeychainError.swift in Sources */,
DD2968732D6DAD5F00143851 /* APIProvider.swift in Sources */,
DD2968742D6DAD5F00143851 /* NetworkError.swift in Sources */,
DD2968432D6DAD2F00143851 /* FetchGameSchedules.swift in Sources */,
Expand All @@ -1058,6 +1078,7 @@
DD2968372D6DAD1700143851 /* ProfileRepositoryImpl.swift in Sources */,
DD2968382D6DAD1700143851 /* ReportRepositoryImpl.swift in Sources */,
DD29687C2D6DB27F00143851 /* OAuthenticator.swift in Sources */,
DDED59512D7850E600A0BEF1 /* LocalError.swift in Sources */,
DD2968602D6DAD5500143851 /* GhostTargetType.swift in Sources */,
DD2968612D6DAD5500143851 /* ViewitTargetType.swift in Sources */,
DD2968622D6DAD5500143851 /* CommentLikedTargetType.swift in Sources */,
Expand All @@ -1077,11 +1098,13 @@
DD29683A2D6DAD1700143851 /* NotificationRepositoryImpl.swift in Sources */,
DD2967F92D6DAC4800143851 /* AnyPublisher+.swift in Sources */,
DD2967FA2D6DAC4800143851 /* Publisher+.swift in Sources */,
DDCCA3952D73928900658122 /* UserSession.swift in Sources */,
DD2967FB2D6DAC4800143851 /* DIContainer.swift in Sources */,
DD2968022D6DAC9B00143851 /* ViewController.swift in Sources */,
DD2967FC2D6DAC4800143851 /* Injected.swift in Sources */,
DD2967FD2D6DAC4800143851 /* CancelBag.swift in Sources */,
DD2967FE2D6DAC4800143851 /* WableLogger.swift in Sources */,
DDCCA3932D738CD500658122 /* UserSessionRepository.swift in Sources */,
DD2967FF2D6DAC8900143851 /* SceneDelegate.swift in Sources */,
DD2968172D6DAD0200143851 /* ContentRepository.swift in Sources */,
DD2968182D6DAD0200143851 /* CommunityRepository.swift in Sources */,
Expand All @@ -1102,6 +1125,7 @@
DD2968252D6DAD0B00143851 /* ViewitMapper.swift in Sources */,
DD2968262D6DAD0B00143851 /* CommunityMapper.swift in Sources */,
DD2968272D6DAD0B00143851 /* LoginMapper.swift in Sources */,
DDED594F2D784EC000A0BEF1 /* LocalKeyValueStorage.swift in Sources */,
DD2968282D6DAD0B00143851 /* InformationMapper.swift in Sources */,
DD2968292D6DAD0B00143851 /* WableError.swift in Sources */,
DD29682A2D6DAD0B00143851 /* ErrorMapper.swift in Sources */,
Expand Down
111 changes: 111 additions & 0 deletions Wable-iOS/Data/RepositoryImpl/UserSessionRepositoryImpl.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//
// UserSessionRepositoryImpl.swift
// Wable-iOS
//
// Created by YOUJIM on 3/2/25.
//


import Foundation

class UserSessionRepositoryImpl {
private enum Keys {
static let userSessions = "sessionDictionary"
static let activeUserID = "activeID"
}

private let userDefaults = UserDefaultsStorage(
userDefaults: UserDefaults.standard,
jsonEncoder: JSONEncoder(),
jsonDecoder: JSONDecoder()
)
}

// MARK: - UserSessionRepository

extension UserSessionRepositoryImpl: UserSessionRepository {
func fetchAllUserSessions() -> [String: UserSession] {
return (try? userDefaults.getValue(for: Keys.userSessions)) ?? [:]
}

func fetchUserSession(forUserID userID: String) -> UserSession? {
return fetchAllUserSessions()[userID]
}

func fetchActiveUserSession() -> UserSession? {
guard let activeUserID = fetchActiveUserID() else {
return nil
}
return fetchUserSession(forUserID: activeUserID)
}

func fetchActiveUserID() -> String? {
return try? userDefaults.getValue(for: Keys.activeUserID)
}

func updateUserSession(_ session: UserSession, forUserID userID: String) {
var sessions = fetchAllUserSessions()

sessions[userID] = session

try? userDefaults.setValue(sessions, for: Keys.userSessions)

if fetchActiveUserID() == nil {
updateActiveUserID(forUserID: userID)
}
}

func updateAutoLogin(enabled: Bool, forUserID userID: String) {
var sessions = fetchAllUserSessions()

if let session = sessions[userID] {
let updatedSession = UserSession(
id: session.id,
nickname: session.nickname,
profileURL: session.profileURL,
isPushAlarmAllowed: session.isPushAlarmAllowed,
isAdmin: session.isAdmin,
isAutoLoginEnabled: enabled,
notificationBadgeCount: session.notificationBadgeCount
)

sessions[userID] = updatedSession
try? userDefaults.setValue(sessions, for: Keys.userSessions)
}
}

func updateNotificationBadge(count: Int, forUserID userID: String) {
var sessions = fetchAllUserSessions()

if let session = sessions[userID] {
let updatedSession = UserSession(
id: session.id,
nickname: session.nickname,
profileURL: session.profileURL,
isPushAlarmAllowed: session.isPushAlarmAllowed,
isAdmin: session.isAdmin,
isAutoLoginEnabled: session.isAutoLoginEnabled,
notificationBadgeCount: count
)
sessions[userID] = updatedSession
try? userDefaults.setValue(sessions, for: Keys.userSessions)
}
}

func updateActiveUserID(forUserID userID: String?) {
if let userID = userID {
try? userDefaults.setValue(userID, for: Keys.activeUserID)
}
}

func removeUserSession(forUserID userID: String) {
var sessions = fetchAllUserSessions()

sessions.removeValue(forKey: userID)
try? userDefaults.setValue(sessions, for: Keys.userSessions)

if fetchActiveUserID() == userID {
updateActiveUserID(forUserID: nil)
}
}
}
19 changes: 19 additions & 0 deletions Wable-iOS/Domain/Entity/UserSession.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// UserSession.swift
// Wable-iOS
//
// Created by YOUJIM on 3/2/25.
//


import Foundation

struct UserSession: Codable, Identifiable {
let id: Int
let nickname: String
let profileURL: String
let isPushAlarmAllowed: Bool
let isAdmin: Bool
let isAutoLoginEnabled: Bool?
let notificationBadgeCount: Int?
}
23 changes: 23 additions & 0 deletions Wable-iOS/Domain/RepositoryInterface/UserSessionRepository.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// UserSessionRepository.swift
// Wable-iOS
//
// Created by YOUJIM on 3/2/25.
//


import Foundation

// MARK: - UserSessionRepository

protocol UserSessionRepository {
func fetchAllUserSessions() -> [String: UserSession]
func fetchUserSession(forUserID userID: String) -> UserSession?
func fetchActiveUserSession() -> UserSession?
func fetchActiveUserID() -> String?
func updateUserSession(_ session: UserSession, forUserID userID: String)
func updateAutoLogin(enabled: Bool, forUserID userID: String)
func updateNotificationBadge(count: Int, forUserID userID: String)
func updateActiveUserID(forUserID userID: String?)
func removeUserSession(forUserID userID: String)
}
26 changes: 0 additions & 26 deletions Wable-iOS/Infra/Keychain/KeychainError.swift

This file was deleted.

Loading