Skip to content

Commit

Permalink
Merge branch 'feature/searchHome' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
junho7108 committed Sep 23, 2024
2 parents 971a2b5 + 80d4754 commit 316fd93
Show file tree
Hide file tree
Showing 57 changed files with 3,061 additions and 40 deletions.
425 changes: 425 additions & 0 deletions Appstore.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Binary file not shown.
49 changes: 49 additions & 0 deletions Appstore/Components/CollectionView/BaseCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// BaseCell.swift
// Appstore
//
// Created by Junho Yoon on 9/21/24.
//

import UIKit

class BaseCell<Model: Decodable>: UICollectionViewCell {

public var model: Model?

public var indexPath: IndexPath?

func update(model: Model) { }

func measuredSize(model: Model?, indexPath: IndexPath) -> CGSize { return CGSize.zero }

func didSelect(model: Model, indexPath: IndexPath) { }
}

extension BaseCell: CollectionViewCellAdaptable {

func adaptOnBind(model: any Decodable, indexPath: IndexPath) {
self.model = model as? Model
self.indexPath = indexPath
}

func adaptOnUpdate() {
guard let model else {
fatalError()
}

self.update(model: model)
}

func adaptComputedSize(model: any Decodable, indexPath: IndexPath) -> CGSize {
return measuredSize(model: model as? Model, indexPath: indexPath)
}


func adaptDidSelect(_ indexPath: IndexPath) {
guard let model else { return }

self.didSelect(model: model, indexPath: indexPath)
}
}

32 changes: 32 additions & 0 deletions Appstore/Components/CollectionView/BaseCollectionFlowLayout.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// BaseCollectionFlowLayout.swift
// Appstore
//
// Created by Junho Yoon on 9/21/24.
//

import UIKit

class BaseCollectionFlowLayout: UICollectionViewFlowLayout {
enum Direction { case vertical, horizontal }

override init() {
super.init()
}

init(direction: UICollectionView.ScrollDirection,
sectionInset: UIEdgeInsets = .zero,
lineSpacing: CGFloat = 8,
itemSpacing: CGFloat = 8) {
super.init()

self.scrollDirection = direction
self.sectionInset = sectionInset
self.minimumInteritemSpacing = itemSpacing
self.minimumLineSpacing = lineSpacing
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
42 changes: 42 additions & 0 deletions Appstore/Components/CollectionView/CellModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// CellModel.swift
// Appstore
//
// Created by Junho Yoon on 9/21/24.
//

import Foundation

struct CellModel: ModelAdaptable, Hashable {

static func == (lhs: CellModel, rhs: CellModel) -> Bool {
if let lhsModel = lhs.model as? AnyHashable, let rhsModel = rhs.model as? AnyHashable {
return lhsModel == rhsModel
} else {
return lhs.id == rhs.id
}
}

func hash(into hasher: inout Hasher) {
if let model = model as? AnyHashable {
hasher.combine(model)
} else {
hasher.combine(id)
}
}


var id: UUID = UUID()
var identifier: String
var model: any Decodable

init(identifier: String, model: any Decodable) {
self.identifier = identifier
self.model = model
}

init<T>(identifier: T.Type, model: any Decodable) {
self.identifier = String(describing: identifier)
self.model = model
}
}
20 changes: 20 additions & 0 deletions Appstore/Coordinator/SearchHomeCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,24 @@ final class SearchHomeCoordinator: ReactiveCoordinator<Void>,
CoordinatorTransitable {

override func start(_ type: CoordinatorTransitionType) -> Observable<Void> {

self.navigationController.setNavigationBarHidden(false, animated: false)

let repository = SearchRepository()
let usecase = SearchUsecase(repository: repository)
let viewModel = SearchHomeViewModel(usecase: usecase)
let viewController = SearchHomeViewController(viewModel: viewModel)

viewModel.coordinate.coordinateToSearchDetail
.withUnretained(self)
.bind { (self, result) in
self.coordinateToSearchDetail(with: result)
.subscribe(onNext: { })
.disposed(by: self.disposeBag)
}
.disposed(by: disposeBag)


self.transition(to: viewController,
navigationController: navigationController,
type: .push,
Expand All @@ -27,3 +38,12 @@ final class SearchHomeCoordinator: ReactiveCoordinator<Void>,
return Observable.empty()
}
}

private extension SearchHomeCoordinator {
func coordinateToSearchDetail(with result: SearchResult) -> Observable<Void> {
let coordinator = SearchResultDetailCoordinator(dependency: SearchResultDetailCoordinator.Dependency(data: result),
navigationController: navigationController)

return coordinate(to: coordinator, type: .push, animated: true)
}
}
37 changes: 37 additions & 0 deletions Appstore/Coordinator/SearchResultDetailCoordinator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// SearchResultDetailCoordinator.swift
// Appstore
//
// Created by Junho Yoon on 9/22/24.
//

import UIKit
import RxSwift
import RxRelay

final class SearchResultDetailCoordinator: ReactiveCoordinator<Void>,
CoordinatorTransitable {

typealias Dependency = SearchResultDetailViewModel.Dependency

private(set) var dependency: Dependency

init(dependency: Dependency, navigationController: UINavigationController) {
self.dependency = dependency
super.init(navigationController: navigationController)
}

override func start(_ type: CoordinatorTransitionType) -> Observable<Void> {


let viewModel = SearchResultDetailViewModel(dependency: dependency)
let viewController = SearchResultDetailViewController(viewModel: viewModel)

self.transition(to: viewController,
navigationController: navigationController,
type: .push,
animated: true)

return Observable.empty()
}
}
34 changes: 34 additions & 0 deletions Appstore/Extensions/CollectionView+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// CollectionView+Extensions.swift
// Appstore
//
// Created by Junho Yoon on 9/20/24.
//

import UIKit

extension UICollectionView {
public func register<T: UICollectionViewCell>(cellWithClass name: T.Type) {
register(T.self, forCellWithReuseIdentifier: String(describing: name))
}

public func register<T: UICollectionReusableView>(supplementaryViewOfKind kind: String, withClass name: T.Type) {
register(T.self, forSupplementaryViewOfKind: kind, withReuseIdentifier: String(describing: name))
}

public func dequeueReusableCell<T: UICollectionViewCell>(withClass name: T.Type, for indexPath: IndexPath) -> T {
guard let cell = self.dequeueReusableCell(withReuseIdentifier: String(describing: name), for: indexPath) as? T else {
fatalError("Couldn't find UICollectionViewCell for \(String(describing: name))")
}

return cell
}

public func dequeueReusableSupplementaryView<T: UICollectionReusableView>(ofKind kind: String, withClass name: T.Type, for indexPath: IndexPath) -> T {

guard let view = dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: String(describing: name), for: indexPath) as? T else { fatalError("Couldn't find UICollectionReusableView for \(String(describing: name))")
}

return view
}
}
15 changes: 15 additions & 0 deletions Appstore/Extensions/Double+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// Double+Extensions.swift
// Appstore
//
// Created by Junho Yoon on 9/22/24.
//

import Foundation

extension Double {
func truncateToOneDecimalPlace() -> Double {
let factor = pow(10.0, 1.0)
return floor(self * factor) / factor
}
}
15 changes: 15 additions & 0 deletions Appstore/Extensions/String+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// String+Extensions.swift
// Appstore
//
// Created by Junho Yoon on 9/21/24.
//

import Foundation

extension String {
func getClassType() -> AnyClass? {
let name = Bundle.main.infoDictionary!["CFBundleName"] as! String
return NSClassFromString("\(name).\(self)")
}
}
20 changes: 20 additions & 0 deletions Appstore/Extensions/UIScreen+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// UIScreen+Extensions.swift
// Appstore
//
// Created by Junho Yoon on 9/20/24.
//

import UIKit

extension UIScreen {
public static var width: CGFloat {

return UIScreen.main.bounds.size.width
}

public static var height: CGFloat {

return UIScreen.main.bounds.size.height
}
}
33 changes: 33 additions & 0 deletions Appstore/Extensions/UserDefaults+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// UserDefaults+Extensions.swift
// Appstore
//
// Created by Junho Yoon on 9/21/24.
//

import Foundation

extension UserDefaults {
public subscript(key: String) -> Any? {
get {
return object(forKey: key)
}
set {
set(newValue, forKey: key)
}
}

public func object<T: Codable>(_ type: T.Type, forKey key: String, usingDecoder decoder: JSONDecoder = JSONDecoder()) -> T? {

guard let data = value(forKey: key) as? Data else { return nil }

return try? decoder.decode(type.self, from: data)
}

public func set<T: Codable>(object: T, forKey key: String, usingEncoder encoder: JSONEncoder = JSONEncoder()) {

let data = try? encoder.encode(object)

set(data, forKey: key)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//
// ScreenShotsCellModel.swift
// Appstore
//
// Created by Junho Yoon on 9/22/24.
//

import Foundation

9 changes: 9 additions & 0 deletions Appstore/Model/CellConvertingModel/ScreenshotCellModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//
// ScreenshotCellModel.swift
// Appstore
//
// Created by Junho Yoon on 9/23/24.
//

import Foundation

10 changes: 10 additions & 0 deletions Appstore/Model/CellModelProtocol.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// CellModelProtocol.swift
// Appstore
//
// Created by Junho Yoon on 9/23/24.
//

import Foundation

protocol CellModelProtocol: Codable, Hashable, CellModelConvertible { }
21 changes: 21 additions & 0 deletions Appstore/Model/MediaType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// MediaType.swift
// Appstore
//
// Created by Junho Yoon on 9/20/24.
//

import Foundation

enum MediaType: String {
case movie
case podcast
case music
case musicVideo
case audiobook
case shortFilm
case tvShow
case software
case ebook
case all
}
12 changes: 12 additions & 0 deletions Appstore/Model/SearchKeywordType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// SearchKeywordType.swift
// Appstore
//
// Created by Junho Yoon on 9/22/24.
//

import Foundation

protocol SearchKeywordType: Codable, Hashable {
var keyword: String { get set }
}
Loading

0 comments on commit 316fd93

Please sign in to comment.