Skip to content

Commit

Permalink
Merge pull request #13 from GO-SOPT-iOS-Part/4thWeek
Browse files Browse the repository at this point in the history
🕓 4주차 세미나
  • Loading branch information
ena-isme authored Aug 14, 2023
2 parents 0d082c6 + e017704 commit d7a4534
Show file tree
Hide file tree
Showing 13 changed files with 447 additions and 1 deletion.
2 changes: 1 addition & 1 deletion 3rdWeek/Assignment/Assignment/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,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: HomeViewController())
let navigationController = UINavigationController(rootViewController: MypageViewController())
navigationController.navigationBar.isHidden = true
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
Expand Down
36 changes: 36 additions & 0 deletions 4thWeek/Seminar/Seminar/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// AppDelegate.swift
// Seminar
//
// Created by 신지원 on 2023/08/15.
//

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {



func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}

// MARK: UISceneSession Lifecycle

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}


}

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
6 changes: 6 additions & 0 deletions 4thWeek/Seminar/Seminar/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
23 changes: 23 additions & 0 deletions 4thWeek/Seminar/Seminar/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
</dict>
</plist>
16 changes: 16 additions & 0 deletions 4thWeek/Seminar/Seminar/NetworkResult.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// NetworkResult.swift
// Seminar
//
// Created by 신지원 on 2023/08/15.
//

import Foundation

enum NetworkResult<T> {
case success(T) // 서버 통신 성공
case requestErr(T) // 요청에러 발생
case pathErr // 경로 에러
case serverErr // 서버 내부 에러
case networkErr // 네트워크 연결 실패
}
52 changes: 52 additions & 0 deletions 4thWeek/Seminar/Seminar/SceneDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// SceneDelegate.swift
// Seminar
//
// Created by 신지원 on 2023/08/15.
//

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.rootViewController = UINavigationController(rootViewController: WeatherViewController())
window?.makeKeyAndVisible()
}

func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}

func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}

func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}

func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}

func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}


}

26 changes: 26 additions & 0 deletions 4thWeek/Seminar/Seminar/UIImageView+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// UIImageView+.swift
// Seminar
//
// Created by 신지원 on 2023/08/15.
//

import UIKit

import Kingfisher

extension UIImageView{
func kfSetImage(url : String?){

guard let url = url else {
print("Q")
return }

if let url = URL(string: url) {
kf.indicatorType = .activity
kf.setImage(with: url,
placeholder: nil,
options: [.transition(.fade(1.0))], progressBlock: nil)
}
}
}
35 changes: 35 additions & 0 deletions 4thWeek/Seminar/Seminar/WeatherResponse.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// WeatherResponse.swift
// Seminar
//
// Created by 신지원 on 2023/08/15.
//

import Foundation

struct Weathers: Codable {
let weather: [Weather]
let main: Main
let wind: Wind
let name: String
}

struct Weather: Codable {
let id: Int
let main: String
let description: String
let icon: String
}

struct Main: Codable {
let temp: Double
let feels_like: Double
let temp_min: Double
let temp_max: Double
let pressure: Int
let humidity: Int
}

struct Wind: Codable {
let speed: Double
}
59 changes: 59 additions & 0 deletions 4thWeek/Seminar/Seminar/WeatherService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// WeatherService.swift
// Seminar
//
// Created by 신지원 on 2023/08/15.
//

import Foundation

import Alamofire

final class WeatherService {

let baseURL = "https://api.openweathermap.org/data/2.5/weather?"
static let shared = WeatherService()

private init() {}

func getWeather(city : String, completion : @escaping (NetworkResult<Any>) -> Void) {
let url = "https://api.openweathermap.org/data/2.5/weather"
let header: HTTPHeaders = ["Content-Type" : "application/json"]
let body: Parameters = [
"q": city,
"appid": "9c7fa18b50b00954d1159672fb66a924",
]

let dataRequest = AF.request(url, method: .get,
parameters : body,
headers: header)

dataRequest.responseData { response in
switch response.result {
case .success:
guard let statusCode = response.response?.statusCode else { return }
guard let value = response.value else { return }
let networkResult = self.judgeStatus(by: statusCode, value)
completion(networkResult)
case .failure:
completion(.networkErr)
}
}
}
private func judgeStatus(by statusCode: Int, _ data: Data) -> NetworkResult<Any> {
switch statusCode {
case 200: return isValidData(data: data)
case 400...409: return isValidData(data: data)
case 500: return .serverErr
default: return .networkErr
}
}

private func isValidData(data: Data) -> NetworkResult<Any> {
let decoder = JSONDecoder()

guard let decodedData = try? decoder.decode(Weathers.self, from: data) else { return .pathErr }

return .success(decodedData as Any)
}
}
80 changes: 80 additions & 0 deletions 4thWeek/Seminar/Seminar/WeatherTableViewCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//
// WeatherTableViewCell.swift
// Seminar
//
// Created by 신지원 on 2023/08/15.
//

import UIKit

import SnapKit
import Then

class WeatherTableViewCell: UITableViewCell {

static let identifier = "WeatherTableViewCell"
private lazy var weatherImage = UIImageView()
private let cityLabel = UILabel()
private let temperLabel = UILabel()
private let humidityLabel = UILabel()

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)

setStyle()
setLayout()
}

@available(*, unavailable)
required init?(coder: NSCoder) {
super.init(coder: coder)
}

func setStyle() {

cityLabel.do {
$0.font = UIFont.systemFont(ofSize: 30)
}
temperLabel.do {
$0.font = UIFont.systemFont(ofSize: 15)
}
humidityLabel.do {
$0.font = UIFont.systemFont(ofSize: 15)
}

}

func setLayout() {

[weatherImage, cityLabel, temperLabel, humidityLabel].forEach { contentView.addSubview($0) }

weatherImage.snp.makeConstraints {
$0.height.width.equalTo(80)
$0.top.equalToSuperview().inset(30)
$0.leading.equalToSuperview().inset(30)
}
cityLabel.snp.makeConstraints {
$0.top.equalToSuperview().inset(10)
$0.trailing.equalToSuperview().inset(20)
}
temperLabel.snp.makeConstraints {
$0.top.equalTo(cityLabel).offset(50)
$0.trailing.equalTo(cityLabel).inset(10)
}
humidityLabel.snp.makeConstraints {
$0.top.equalTo(temperLabel).offset(20)
$0.trailing.equalTo(cityLabel).inset(10)
}

}

func configureCell(_ weather: Weathers) {
guard let icon = weather.weather.first?.icon else { return }
let url = "http://openweathermap.org/img/wn/\(icon).png"
print(url)
weatherImage.kfSetImage(url: url)
cityLabel.text = String(weather.name)
temperLabel.text = "현재 온도 : " + String(weather.main.temp) + "°C"
humidityLabel.text = "습도 : " + String(weather.main.humidity) + "%"
}
}
Loading

0 comments on commit d7a4534

Please sign in to comment.