From 28695fd1de94a658c09e4a34eb29fe6501be90e8 Mon Sep 17 00:00:00 2001 From: Yoonseo Kim Date: Sun, 15 Aug 2021 17:00:35 +0900 Subject: [PATCH] =?UTF-8?q?[#21]=20Weather=20Service=20=E1=84=89=E1=85=A2?= =?UTF-8?q?=E1=86=BC=E1=84=89=E1=85=A5=E1=86=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Apple-Weather.xcodeproj/project.pbxproj | 4 + .../Sources/APIServices/WeatherService.swift | 120 ++++++++++++++++++ .../MainPageViewController.swift | 101 +-------------- .../SearchViewController.swift | 112 ++-------------- 4 files changed, 138 insertions(+), 199 deletions(-) create mode 100644 Apple-Weather/Apple-Weather/Sources/APIServices/WeatherService.swift diff --git a/Apple-Weather/Apple-Weather.xcodeproj/project.pbxproj b/Apple-Weather/Apple-Weather.xcodeproj/project.pbxproj index 1e20f49..c485676 100644 --- a/Apple-Weather/Apple-Weather.xcodeproj/project.pbxproj +++ b/Apple-Weather/Apple-Weather.xcodeproj/project.pbxproj @@ -22,6 +22,7 @@ DD71B26F26AD3A770025F6BA /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD71B26E26AD3A770025F6BA /* MainViewController.swift */; }; DD81B2DD26C0E8EE00268F8A /* UIViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD81B2DC26C0E8EE00268F8A /* UIViewController+Extension.swift */; }; DD873C3226B05A07003857A0 /* DailyWeatherCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD873C3126B05A07003857A0 /* DailyWeatherCollectionViewCell.swift */; }; + DD894AA426C8FC580057F7C7 /* WeatherService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD894AA326C8FC580057F7C7 /* WeatherService.swift */; }; DD8FAF3B26C246A300158C31 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8FAF3A26C246A300158C31 /* APIService.swift */; }; DD8FAF3D26C24B6800158C31 /* WeatherAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8FAF3C26C24B6800158C31 /* WeatherAPI.swift */; }; DD8FAF3F26C24D4300158C31 /* MoyaLoggingPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8FAF3E26C24D4300158C31 /* MoyaLoggingPlugin.swift */; }; @@ -72,6 +73,7 @@ DD71B26E26AD3A770025F6BA /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; DD81B2DC26C0E8EE00268F8A /* UIViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Extension.swift"; sourceTree = ""; }; DD873C3126B05A07003857A0 /* DailyWeatherCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyWeatherCollectionViewCell.swift; sourceTree = ""; }; + DD894AA326C8FC580057F7C7 /* WeatherService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherService.swift; sourceTree = ""; }; DD8FAF3A26C246A300158C31 /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = ""; }; DD8FAF3C26C24B6800158C31 /* WeatherAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeatherAPI.swift; sourceTree = ""; }; DD8FAF3E26C24D4300158C31 /* MoyaLoggingPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoyaLoggingPlugin.swift; sourceTree = ""; }; @@ -178,6 +180,7 @@ DD8FAF3A26C246A300158C31 /* APIService.swift */, DD8FAF3C26C24B6800158C31 /* WeatherAPI.swift */, DD8FAF3E26C24D4300158C31 /* MoyaLoggingPlugin.swift */, + DD894AA326C8FC580057F7C7 /* WeatherService.swift */, ); path = APIServices; sourceTree = ""; @@ -485,6 +488,7 @@ DDD3F2EF26AC3C2400FD547A /* AppDelegate.swift in Sources */, DD6C72DD26BD619A00EE278A /* SearchViewController.swift in Sources */, DDD3F2F126AC3C2400FD547A /* SceneDelegate.swift in Sources */, + DD894AA426C8FC580057F7C7 /* WeatherService.swift in Sources */, DD71B26F26AD3A770025F6BA /* MainViewController.swift in Sources */, DD94BE9926BED1600042CA59 /* String+Extension.swift in Sources */, DD8FAF4D26C25C8500158C31 /* TempModel.swift in Sources */, diff --git a/Apple-Weather/Apple-Weather/Sources/APIServices/WeatherService.swift b/Apple-Weather/Apple-Weather/Sources/APIServices/WeatherService.swift new file mode 100644 index 0000000..07e94e5 --- /dev/null +++ b/Apple-Weather/Apple-Weather/Sources/APIServices/WeatherService.swift @@ -0,0 +1,120 @@ +// +// WeatherService.swift +// Apple-Weather +// +// Created by 김윤서 on 2021/08/15. +// + +import Foundation + +import Moya + +class WeatherService { + static let shared = WeatherService() + private lazy var service = MoyaProvider(plugins: [MoyaLoggingPlugin()]) + private var getWeather: GenericModel? + private var searchWeather: MainWeatherModel? + + public func requestGetWeather(lat: Double, + lon: Double, + location: String, + completion: @escaping (MainWeatherModel?) -> Void) { + service.request(WeatherAPI.getWeathers(lat: lat, lon: lon, exclude: "minutely")) { [weak self] result in + switch result { + case .success(let response): + do { + + let response = try JSONDecoder().decode(GenericModel.self, from: response.data) + self?.getWeather = response + + completion(self?.convertMainWeatherModel(response: response, location: location)) + } catch let err { + debugPrint(err) + } + case .failure(let error): + print(error.localizedDescription) + } + } + } + + private func convertMainWeatherModel(response: GenericModel, + location: String) -> MainWeatherModel? { + + let date = DateFormatter() + date.locale = Locale(identifier: "ko_KR") + date.timeZone = TimeZone(secondsFromGMT: response.timezoneOffset) + date.dateFormat = "HH" + + let date2 = DateFormatter() + date2.locale = Locale(identifier: "ko_KR") + date2.timeZone = TimeZone(secondsFromGMT: response.timezoneOffset) + date2.dateFormat = "EEEE" + + let date3 = DateFormatter() + date3.locale = Locale(identifier: "ko_KR") + date3.timeZone = TimeZone(secondsFromGMT: response.timezoneOffset) + date3.dateFormat = "HH:mm" + + var hourlyWeatherModel: [HourlyWeatherModel] = [] + var weekWeatherModel: [WeekWeaherModel] = [] + var detailWeatherModel: [DetailModel] = [] + + let hourly = response.hourly + let daily = response.daily + let current = response.current + + detailWeatherModel.append(contentsOf: [DetailModel(description: "일출", + content: date3.string(from: Date(timeIntervalSince1970: TimeInterval(current.sunrise ?? 0)))), + DetailModel(description: "일몰", + content: date3.string(from: Date(timeIntervalSince1970: TimeInterval(current.sunset ?? 0)))), + DetailModel(description: "비 올 확률", + content: "\(current.dewPoint)%"), + DetailModel(description: "습도", + content: "\(current.humidity)%"), + DetailModel(description: "바람", + content: "\(current.windSpeed)m/s"), + DetailModel(description: "체감", + content: "\(current.feelsLike)°"), + DetailModel(description: "강수량", + content: "\(String(describing: current.rain?.the1H ?? 0))"), + DetailModel(description: "기압", + content: "\(current.pressure)hPa"), + DetailModel(description: "가시거리", + content: "\(current.visibility / 1000)km"), + DetailModel(description: "자외선지수", + content: "\(current.uvi)") + + ]) + + for index in 0...23 { + hourlyWeatherModel.append(HourlyWeatherModel( + time: date.string(from: Date(timeIntervalSince1970: TimeInterval(hourly[index].dt))), + icon: hourly[index].weather[0].icon, + temperature: Int(hourly[index].temp))) + } + + print(response.hourly.count) + + for index in 0...response.daily.count - 1 { + weekWeatherModel.append(WeekWeaherModel( + day: date2.string(from: Date(timeIntervalSince1970: TimeInterval(response.daily[index].dt))), + icon: daily[index].weather[0].icon, + precipitation: daily[index].rain, + highTemperature: Int(daily[index].temp.max), + lowTemperature: Int(daily[index].temp.min))) + } + + searchWeather = MainWeatherModel(location: location, + weather: response.current.weather[0].weatherDescription, + temperature: Int(response.current.temp), + highTemperature: Int(daily[0].temp.max), + lowTemperatuer: Int(daily[0].temp.min), + timezonwOffset: response.timezoneOffset, + hourlyWeather: hourlyWeatherModel, + dailyWeather: DailyWeatherModel(weekWeather: weekWeatherModel, + detail: detailWeatherModel) + ) + + return searchWeather + } +} diff --git a/Apple-Weather/Apple-Weather/Sources/ViewControllers/MainPageViewController.swift b/Apple-Weather/Apple-Weather/Sources/ViewControllers/MainPageViewController.swift index 72a3b74..431bb79 100644 --- a/Apple-Weather/Apple-Weather/Sources/ViewControllers/MainPageViewController.swift +++ b/Apple-Weather/Apple-Weather/Sources/ViewControllers/MainPageViewController.swift @@ -12,9 +12,7 @@ import SnapKit import Then class MainPageViewController: UIViewController { - private lazy var service = MoyaProvider(plugins: [MoyaLoggingPlugin()]) - private var getWeather: GenericModel? - + private var viewControllerList: [MainViewController] = [] public var weathers: [MainWeatherModel] = [] public var myLocationWeather: [MainWeatherModel] = [] @@ -243,100 +241,13 @@ extension MainPageViewController { } extension MainPageViewController { - func requestGetWeather() { - service.request(WeatherAPI.getWeathers(lat: +37.28043530, lon: +127.11463210, exclude: "minutely")) { [weak self] result in - switch result { - case .success(let response): - do { - - let response = try JSONDecoder().decode(GenericModel.self, from: response.data) - self?.getWeather = response - - self?.convertMainWeatherModel(response: response) - } catch let err { - debugPrint(err) - } - case .failure(let error): - print(error.localizedDescription) + WeatherService.shared.requestGetWeather(lat: +37.28043530, lon: +127.11463210, location: "용인시") { [weak self] weather in + if let weather = weather { + self?.myLocationWeather.append(weather) + self?.setViewControllerList() + self?.setPageViewController(index: 0) } } } - - func convertMainWeatherModel(response: GenericModel) { - let date = DateFormatter() - date.locale = Locale(identifier: "ko_KR") - date.timeZone = TimeZone(identifier: "KST") - date.dateFormat = "HH" - - let date2 = DateFormatter() - date2.locale = Locale(identifier: "ko_KR") - date2.timeZone = TimeZone(identifier: "KST") - date2.dateFormat = "EEEE" - - let date3 = DateFormatter() - date3.locale = Locale(identifier: "ko_KR") - date3.timeZone = TimeZone(identifier: "KST") - date3.dateFormat = "HH:mm" - - var hourlyWeatherModel: [HourlyWeatherModel] = [] - var weekWeatherModel: [WeekWeaherModel] = [] - var detailWeatherModel: [DetailModel] = [] - - let hourly = response.hourly - let daily = response.daily - let current = response.current - - detailWeatherModel.append(contentsOf: [DetailModel(description: "일출", - content: date3.string(from: Date(timeIntervalSince1970: TimeInterval(current.sunrise ?? 0)))), - DetailModel(description: "일몰", - content: date3.string(from: Date(timeIntervalSince1970: TimeInterval(current.sunset ?? 0)))), - DetailModel(description: "이슬점", - content: "\(current.dewPoint)%"), - DetailModel(description: "습도", - content: "\(current.humidity)%"), - DetailModel(description: "바람", - content: "\(current.windSpeed)m/s"), - DetailModel(description: "체감", - content: "\(current.feelsLike)°"), - DetailModel(description: "강수량", - content: "\(String(describing: current.rain?.the1H ?? 0))"), - DetailModel(description: "기압", - content: "\(current.pressure)hPa"), - DetailModel(description: "가시거리", - content: "\(current.visibility / 1000)km"), - DetailModel(description: "자외선지수", - content: "\(current.uvi)") - - ]) - - for index in 0...23 { - hourlyWeatherModel.append(HourlyWeatherModel( - time: date.string(from: Date(timeIntervalSince1970: TimeInterval(hourly[index].dt))), - icon: hourly[index].weather[0].icon, - temperature: Int(hourly[index].temp))) - } - - for index in 0...response.daily.count - 1 { - weekWeatherModel.append(WeekWeaherModel( - day: date2.string(from: Date(timeIntervalSince1970: TimeInterval(response.daily[index].dt))), - icon: daily[index].weather[0].icon, - precipitation: daily[index].rain, - highTemperature: Int(daily[index].temp.max), - lowTemperature: Int(daily[index].temp.min))) - } - - myLocationWeather.append(MainWeatherModel(location: response.timezone, - weather: response.current.weather[0].weatherDescription, - temperature: Int(response.current.temp), - highTemperature: Int(daily[0].temp.max), - lowTemperatuer: Int(daily[0].temp.min), - timezonwOffset: response.timezoneOffset, - hourlyWeather: hourlyWeatherModel, - dailyWeather: DailyWeatherModel(weekWeather: weekWeatherModel, - detail: detailWeatherModel) - )) - setViewControllerList() - setPageViewController(index: 0) - } } diff --git a/Apple-Weather/Apple-Weather/Sources/ViewControllers/SearchViewController.swift b/Apple-Weather/Apple-Weather/Sources/ViewControllers/SearchViewController.swift index aac5362..f80a631 100644 --- a/Apple-Weather/Apple-Weather/Sources/ViewControllers/SearchViewController.swift +++ b/Apple-Weather/Apple-Weather/Sources/ViewControllers/SearchViewController.swift @@ -178,14 +178,8 @@ extension SearchViewController: UITableViewDelegate { return } guard let placemark = response?.mapItems[0].placemark else { return } - - let vc = MainViewController() - self.requestGetWeather(lat: placemark.coordinate.latitude, lon: placemark.coordinate.longitude, location: (placemark.locality ?? placemark.title) ?? "") { result in - if let result = result { - vc.setData(weather: result) - self.present(vc, animated: true, completion: nil) - } - } + + self.requestGetWeather(lat: placemark.coordinate.latitude, lon: placemark.coordinate.longitude, location: (placemark.locality ?? placemark.title) ?? "") } } } @@ -222,103 +216,13 @@ extension SearchViewController: UIScrollViewDelegate { } extension SearchViewController { - func requestGetWeather(lat: Double, lon: Double, location: String, completion: @escaping (MainWeatherModel?) -> Void) { - service.request(WeatherAPI.getWeathers(lat: lat, lon: lon, exclude: "minutely")) { [weak self] result in - switch result { - case .success(let response): - do { - - let response = try JSONDecoder().decode(GenericModel.self, from: response.data) - self?.getWeather = response - - completion(self?.convertMainWeatherModel(response: response, location: location)) - - } catch let err { - debugPrint(err) - } - case .failure(let error): - print(error.localizedDescription) + func requestGetWeather(lat: Double, lon: Double, location: String) { + WeatherService.shared.requestGetWeather(lat: lat, lon: lon, location: location) { [weak self] weather in + let vc = MainViewController() + if let weather = weather { + vc.setData(weather: weather) + self?.present(vc, animated: true, completion: nil) } } } - - func convertMainWeatherModel(response: GenericModel, location: String) -> MainWeatherModel? { - - let date = DateFormatter() - date.locale = Locale(identifier: "ko_KR") - date.timeZone = TimeZone(secondsFromGMT: response.timezoneOffset) - date.dateFormat = "HH" - - let date2 = DateFormatter() - date2.locale = Locale(identifier: "ko_KR") - date2.timeZone = TimeZone(secondsFromGMT: response.timezoneOffset) - date2.dateFormat = "EEEE" - - let date3 = DateFormatter() - date3.locale = Locale(identifier: "ko_KR") - date3.timeZone = TimeZone(secondsFromGMT: response.timezoneOffset) - date3.dateFormat = "HH:mm" - - var hourlyWeatherModel: [HourlyWeatherModel] = [] - var weekWeatherModel: [WeekWeaherModel] = [] - var detailWeatherModel: [DetailModel] = [] - - let hourly = response.hourly - let daily = response.daily - let current = response.current - - detailWeatherModel.append(contentsOf: [DetailModel(description: "일출", - content: date3.string(from: Date(timeIntervalSince1970: TimeInterval(current.sunrise ?? 0)))), - DetailModel(description: "일몰", - content: date3.string(from: Date(timeIntervalSince1970: TimeInterval(current.sunset ?? 0)))), - DetailModel(description: "비 올 확률", - content: "\(current.dewPoint)%"), - DetailModel(description: "습도", - content: "\(current.humidity)%"), - DetailModel(description: "바람", - content: "\(current.windSpeed)m/s"), - DetailModel(description: "체감", - content: "\(current.feelsLike)°"), - DetailModel(description: "강수량", - content: "\(String(describing: current.rain?.the1H ?? 0))"), - DetailModel(description: "기압", - content: "\(current.pressure)hPa"), - DetailModel(description: "가시거리", - content: "\(current.visibility / 1000)km"), - DetailModel(description: "자외선지수", - content: "\(current.uvi)") - - ]) - - for index in 0...23 { - hourlyWeatherModel.append(HourlyWeatherModel( - time: date.string(from: Date(timeIntervalSince1970: TimeInterval(hourly[index].dt))), - icon: hourly[index].weather[0].icon, - temperature: Int(hourly[index].temp))) - } - - print(response.hourly.count) - - for index in 0...response.daily.count - 1 { - weekWeatherModel.append(WeekWeaherModel( - day: date2.string(from: Date(timeIntervalSince1970: TimeInterval(response.daily[index].dt))), - icon: daily[index].weather[0].icon, - precipitation: daily[index].rain, - highTemperature: Int(daily[index].temp.max), - lowTemperature: Int(daily[index].temp.min))) - } - - searchWeather = MainWeatherModel(location: location, - weather: response.current.weather[0].weatherDescription, - temperature: Int(response.current.temp), - highTemperature: Int(daily[0].temp.max), - lowTemperatuer: Int(daily[0].temp.min), - timezonwOffset: response.timezoneOffset, - hourlyWeather: hourlyWeatherModel, - dailyWeather: DailyWeatherModel(weekWeather: weekWeatherModel, - detail: detailWeatherModel) - ) - - return searchWeather - } }