Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor [#5] MVVM 패턴 적용 #10

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
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
92 changes: 60 additions & 32 deletions SOPTWeather/SOPTWeather.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion SOPTWeather/SOPTWeather/Application/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
self.window = UIWindow(windowScene: windowScene)
let navigationController = UINavigationController(rootViewController: LocationListViewController())
let navigationController = UINavigationController(rootViewController: CityWeatherDetailViewController())
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()

Expand Down
27 changes: 27 additions & 0 deletions SOPTWeather/SOPTWeather/Global/Protocols/Observable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// Observable.swift
// SOPTWeather
//
// Created by 지희의 MAC on 12/7/23.
//

import Foundation

class Observable<T> {
private var listener: ((T) -> Void)?

var value: T {
didSet {
listener?(value)
}
}

init(_ value: T){
self.value = value
}

func bind(_ closure: @escaping (T) -> Void ) {
closure(value)
listener = closure
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ class WeatherListTableViewCell: UITableViewCell {

static let cellReuseIdentifier = "cellReuseIdentifier"

var weatherData = (cityName: "", weatherText: "", maxminTemp: "", weatherinfomation: []){
didSet{
bindData()
}
}
var weatherData = (cityName: "", weatherText: "", maxminTemp: "", weatherinfomation: [])

private let backgroundImageView: UIImageView = {
let imageView = UIImageView()
Expand Down Expand Up @@ -75,21 +71,6 @@ class WeatherListTableViewCell: UITableViewCell {
contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0))
}

func bindData() {
locationTitleLabel.text = weatherData.cityName
locationLabel.text = weatherData.subTitle
weatherLabel.text = weatherData.weatherText

if weatherData.currentTemp == "" {
tempLabel.text = weatherData.weatherinfomation.first?.tempText
} else {
tempLabel.text = weatherData.currentTemp
}

maxMinTempLabel.text = weatherData.maxminTemp
setUI()
}

private func setUI(){
setViewHierarchy()
setConstraints()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ class LocationListElementView: UIButton {

func bindData() {
locationTitleLabel.text = weatherData.cityName
locationLabel.text = weatherData.subTitle
// locationLabel.text = weatherData.subTitle
weatherLabel.text = weatherData.weatherText
tempLabel.text = weatherData.weatherinfomation.first?.tempText
// tempLabel.text = weatherData.weatherinfomation.first?.tempText
maxMinTempLabel.text = weatherData.maxminTemp
setUI()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,54 +10,23 @@ import UIKit
class LocationListViewController: UIViewController {

let pageController = WeatherDetailPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
let locationView = LocationListView()
let locationList = ["iksan", "jeonju", "jeju", "cheonan", "cheongju", "chuncheon"]
var infoList: [] = []
let locationListView = LocationListView()

override func viewDidLoad() {
super.viewDidLoad()
navigationController?.isNavigationBarHidden = true
getWeatherInfo()
bindVC()
setDelegate()
addView()
}

private func addView() {
view.addSubview(locationView)
locationView.snp.makeConstraints {
$0.edges.equalTo(view.safeAreaLayoutGuide)
}
override func loadView() {
self.view = locationListView
}

private func setDelegate() {
locationView.searchBar.delegate = self
locationView.weatherTableView.dataSource = self
locationView.weatherTableView.delegate = self
}

private func bindVC(){

for i in 0..<cityWeatherList.count {
let weatherDeatilViewController = WeatherDetailViewController()
weatherDeatilViewController.weatherData = cityWeatherList[i]
pageController.contentControllers.append(weatherDeatilViewController)
}
override func viewDidLoad() {
super.viewDidLoad()
setDelegate()
}

func getWeatherInfo(){
for i in 0..<locationList.count {
Task {
if let result = try await GetWeatherService.shared.GetWeatherInfo(location: locationList[i]) {
print(result)
let maxminText = "\(Int(result.main.tempMax))° \(Int(result.main.tempMin))°"
let krName = translateCityNameToKorean(name: locationList[i])
infoList.append((cityName: krName, weatherText: result.weather[0].description, maxminTemp: maxminText,currentTemp: "\(Int(result.main.temp))°", weatherinfomation: []))
}
locationView.weatherTableView.reloadData()
}
}

private func setDelegate() {
locationListView.searchBar.delegate = self
locationListView.weatherTableView.dataSource = self
locationListView.weatherTableView.delegate = self
}

}
Expand All @@ -70,7 +39,7 @@ extension LocationListViewController: UISearchBarDelegate {
} else {
let filteredCities = cityWeatherList.filter { $0.cityName.lowercased().contains(searchText.lowercased()) }
cityWeatherList = filteredCities
locationView.weatherTableView.reloadData()
locationListView.weatherTableView.reloadData()
}
}
}
Expand All @@ -85,13 +54,13 @@ extension LocationListViewController: UITableViewDelegate {

extension LocationListViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return infoList.count
return 4
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: WeatherListTableViewCell.cellReuseIdentifier, for: indexPath) as! WeatherListTableViewCell
cell.weatherData = infoList[indexPath.row]
// cell.weatherData = infoList[indexPath.row]
cell.selectionStyle = .none
return cell
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// LocationListViewModel.swift
// SOPTWeather
//
// Created by 지희의 MAC on 12/6/23.
//

import Foundation
import UIKit

protocol ObservableViewModelProtocol {
func fetchWeatherData()
func setError(_ message: String)
var weather: Observable<[WeatherDTO]> { get set }
var errorMessage: Observable<String?> { get set }
var error: Observable<Bool> { get set }
}

class LocationListViewModel: NSObject, ObservableViewModelProtocol {

let locationList = ["iksan", "jeonju", "jeju", "cheonan", "cheongju", "chuncheon"]

var weather: Observable<[WeatherDTO]> = Observable([])
var errorMessage: Observable<String?> = Observable(nil)
var error: Observable<Bool> = Observable(false)

func fetchWeatherData() {
locationList.forEach { city in
Task {
if let result = try await GetWeatherService.shared.GetWeatherInfo(location: city) {
print(result)
weather.value.append(result)
}
}
}

}

func setError(_ message: String) {
self.errorMessage = Observable(message)
self.error = Observable(true)
}
}


// 근데 여기서 만약 아직 네트워크가 실행되지 않았다면 ? 테이블 뷰가 나타나지 않을거임.. 고민해보자
extension LocationListViewModel: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return weather.value.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: WeatherListTableViewCell.cellReuseIdentifier, for: indexPath) as! WeatherListTableViewCell
// cell.weatherData = infoList[indexPath.row]
cell.selectionStyle = .none
return cell
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,39 +1,49 @@
//
// SummaryCollectionViewCell.swift
// HeaderView.swift
// SOPTWeather
//
// Created by 지희의 MAC on 2023/11/10.
// Created by 지희의 MAC on 12/11/23.
//

import UIKit

class SummaryCollectionViewCell: UICollectionViewCell {
import SnapKit

final class WeatherTimeHeaderView: UITableViewHeaderFooterView {
// MARK: - Variables
// MARK: Const
static var reuseId = "WeatherTimeHeaderView"

// MARK: Component
private let cityTitleLabel: UILabel = {
let label = UILabel()
label.font = .sfProRegular36
label.textColor = .white
label.text = "고양시"
return label
}()

private let tempTitleLabel: UILabel = {
let label = UILabel()
label.font = .sfProThin102
label.textColor = .white
label.text = "0℃"
return label
}()

private let weatherLabel: UILabel = {
let label = UILabel()
label.font = .sfProRegular24
label.textColor = .white
label.text = "맑음"
return label
}()

private let maxMinTempLabel: UILabel = {
let label = UILabel()
label.font = .sfProMedium20
label.textColor = .white
label.text = "최대 0℃ 최소 -12℃"
return label
}()

Expand All @@ -49,25 +59,19 @@ class SummaryCollectionViewCell: UICollectionViewCell {
return stackView
}()

override init(frame: CGRect) {
super.init(frame: frame)

// MARK: - Function
// MARK: LifeCycle
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
setUI()
}


required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}


func setData(city: String, temp: String, weather: String, maxMin: String) {
self.cityTitleLabel.text = city
self.tempTitleLabel.text = temp
self.weatherLabel.text = weather
self.maxMinTempLabel.text = maxMin
}


// MARK: Layout Helpers
private func setUI(){
setViewHierarchy()
setConstraints()
Expand All @@ -78,12 +82,16 @@ class SummaryCollectionViewCell: UICollectionViewCell {
}

private func setConstraints() {

weatherStackView.snp.makeConstraints {
$0.center.equalToSuperview()
}
}
}

extension SummaryCollectionViewCell: CollectionViewCellReuseProtocol {

func setData (city: String, temp: String, weather: String, maxmin: String) {
self.cityTitleLabel.text = city
self.tempTitleLabel.text = temp
self.weatherLabel.text = weather
self.maxMinTempLabel.text = maxmin
}
}
Loading