Skip to content

Commit

Permalink
[Feat] #80 - 소식 탭 뉴스, 공지사항 배지 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
JinUng41 committed Jan 12, 2025
1 parent 8338598 commit 01bec7c
Show file tree
Hide file tree
Showing 13 changed files with 412 additions and 57 deletions.
60 changes: 48 additions & 12 deletions Wable-iOS.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Wable-iOS/Global/Literals/StringLiterals.swift
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ enum StringLiterals {
static let getTeamRank = "v1/information/rank"
static let getNews = "v1/information/news"
static let getNotice = "v1/information/notice"
static let getInfoCount = "v1/information/number"
}

enum Notification {
Expand Down
34 changes: 34 additions & 0 deletions Wable-iOS/Global/Shared/UserDefaults/CodableSerializable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// CodableSerializable.swift
// Wable-iOS
//
// Created by 김진웅 on 1/7/25.
//

import Foundation

protocol Serializable {
func serialize(_ value: Encodable) throws -> Data
}

protocol Deserializable {
func deserialize<T: Decodable>(_ type: T.Type, from data: Data) throws -> T
}

typealias CodableSerializable = Serializable & Deserializable


// MARK: - JSONSerializer

struct JSONSerializer: CodableSerializable {
private let encoder = JSONEncoder()
private let decoder = JSONDecoder()

func serialize(_ value: any Encodable) throws -> Data {
try encoder.encode(value)
}

func deserialize<T: Decodable>(_ type: T.Type, from data: Data) throws -> T {
try decoder.decode(type, from: data)
}
}
28 changes: 28 additions & 0 deletions Wable-iOS/Global/Shared/UserDefaults/UserDefaultsKey.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// UserDefaultsKey.swift
// Wable-iOS
//
// Created by 김진웅 on 1/7/25.
//

import Foundation

/// UserDefaults에 접근하기 위한 Key의 타입을 정의하는 프로토콜
///
/// 아래와 같이, 열거형으로 구현한다.
///
/// ```swift
/// enum UserDefaultsKeys: UserDefaultsKey {
/// case userInfo
///
/// var value: String {
/// switch self{
/// case .userInfo:
/// return "userInfo"
/// }
/// }
/// }
/// ```
protocol UserDefaultsKey: Hashable, CaseIterable {
var value: String { get }
}
71 changes: 71 additions & 0 deletions Wable-iOS/Global/Shared/UserDefaults/UserDefaultsManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//
// UserDefaultsManager.swift
// Wable-iOS
//
// Created by 김진웅 on 1/7/25.
//

import Foundation

protocol UserDefaultsManager {
func save<T: Codable>(_ value: T, forKey key: any UserDefaultsKey)
func load<T: Codable>(forKey key: any UserDefaultsKey, as type: T.Type) -> T?
func remove(forKey keys: any UserDefaultsKey...)
func removeAll()
}

final class UserDefaultsManagerImpl: UserDefaultsManager {
private let serializer: CodableSerializable
private let userDefaults = UserDefaults.standard

init(serializer: CodableSerializable = JSONSerializer()) {
self.serializer = serializer
}

func save<T: Codable>(_ value: T, forKey key: any UserDefaultsKey) {
if isPrimitiveType(T.self) {
userDefaults.set(value, forKey: key.value)
return
}

do {
let data = try serializer.serialize(value)
userDefaults.set(data, forKey: key.value)
} catch {
print("Failed to encode data for key \(key.value): \(error)")
}
}

func load<T: Codable>(forKey key: any UserDefaultsKey, as type: T.Type) -> T? {
if isPrimitiveType(T.self) {
return userDefaults.object(forKey: key.value) as? T
}

guard let data = userDefaults.data(forKey: key.value) else {
return nil
}

do {
return try serializer.deserialize(type, from: data)
} catch {
print("Failed to decode data for key \(key.value): \(error)")
return nil
}
}

/// 특정 키 삭제
func remove(forKey keys: any UserDefaultsKey...) {
keys.forEach { self.userDefaults.removeObject(forKey: $0.value) }
}

/// 모든 데이터 삭제
func removeAll() {
userDefaults.dictionaryRepresentation().forEach { (key, _) in
userDefaults.removeObject(forKey: key)
}
}

private func isPrimitiveType<T>(_ type: T.Type) -> Bool {
return type is Int.Type || type is Double.Type || type is Float.Type || type is Bool.Type || type is String.Type
}
}
9 changes: 9 additions & 0 deletions Wable-iOS/Network/Info/InfoAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,13 @@ extension InfoAPI {
.mapError { $0 as? WableNetworkError ?? .unknownError($0.localizedDescription) }
.eraseToAnyPublisher()
}

func getInfoCount() -> AnyPublisher<InfoCountDTO?, WableNetworkError> {
infoProvider.requestPublisher(.getInfoCount)
.tryMap { [weak self] response -> InfoCountDTO? in
return try self?.parseResponse(statusCode: response.statusCode, data: response.data)
}
.mapError { $0 as? WableNetworkError ?? .unknownError($0.localizedDescription) }
.eraseToAnyPublisher()
}
}
7 changes: 5 additions & 2 deletions Wable-iOS/Network/Info/InfoRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ enum InfoRouter {
case getTeamRank
case getNews(param: Int)
case getNotice(param: Int)
case getInfoCount
}

extension InfoRouter: BaseTargetType {
Expand All @@ -30,19 +31,21 @@ extension InfoRouter: BaseTargetType {
return StringLiterals.Endpoint.Info.getNews
case .getNotice:
return StringLiterals.Endpoint.Info.getNotice
case .getInfoCount:
return StringLiterals.Endpoint.Info.getInfoCount
}
}

var method: Moya.Method {
switch self {
case .getMatchInfo, .getGameType, .getTeamRank, .getNews, .getNotice:
case .getMatchInfo, .getGameType, .getTeamRank, .getNews, .getNotice, .getInfoCount:
return .get
}
}

var task: Moya.Task {
switch self {
case .getMatchInfo, .getGameType, .getTeamRank:
case .getMatchInfo, .getGameType, .getTeamRank, .getInfoCount:
return .requestPlain
case .getNews(let cursor), .getNotice(let cursor):
return .requestParameters(parameters: ["cursor": cursor], encoding: URLEncoding.queryString)
Expand Down
18 changes: 18 additions & 0 deletions Wable-iOS/Network/Info/ResponseDTO/InfoCountDTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// InfoCountDTO.swift
// Wable-iOS
//
// Created by 김진웅 on 1/7/25.
//

import Foundation

struct InfoCountDTO: Codable {
let newsCount: Int
let noticeCount: Int

enum CodingKeys: String, CodingKey {
case newsCount = "newsNumber"
case noticeCount = "noticeNumber"
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// InfoView.swift
// InfoPageView.swift
// Wable-iOS
//
// Created by 변상우 on 8/18/24.
Expand All @@ -10,7 +10,7 @@ import UIKit
import SnapKit
import Lottie

final class InfoView: UIView {
final class InfoPageView: UIView {

// MARK: - UI Component

Expand Down Expand Up @@ -64,7 +64,7 @@ final class InfoView: UIView {

// MARK: - Private Method

private extension InfoView {
private extension InfoPageView {
func setupView() {
backgroundColor = .wableWhite

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// InfoLogoView.swift
// InfoPageLogoView.swift
// Wable-iOS
//
// Created by 박윤빈 on 8/20/24.
Expand All @@ -9,7 +9,7 @@ import UIKit

import SnapKit

final class InfoLogoView: UIView {
final class InfoPageLogoView: UIView {
private let imageView: UIImageView = {
let imageView = UIImageView()
imageView.image = ImageLiterals.Icon.icInfoPurple
Expand Down Expand Up @@ -40,7 +40,7 @@ final class InfoLogoView: UIView {

// MARK: - Private Method

private extension InfoLogoView {
private extension InfoPageLogoView {
func setupView() {
backgroundColor = .wableBlack

Expand Down
Loading

0 comments on commit 01bec7c

Please sign in to comment.