Skip to content

Commit

Permalink
feat: CoreLocation 추가, 위치에 따른 날씨 데이터 fetch 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
maxhyunm committed Sep 13, 2023
1 parent 5e650f9 commit a98cabd
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 25 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ xcuserdata/
*.moved-aside
*.xccheckout
*.xcscmblueprint
Key.plist

## Obj-C/Swift specific
*.hmap
Expand Down
8 changes: 8 additions & 0 deletions Diary.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
BABBDAE52A9F13A200D8D50B /* DecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BABBDAE42A9F13A200D8D50B /* DecodingError.swift */; };
BABBDB342AA6D05A00D8D50B /* ShareDisplayable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BABBDB332AA6D05A00D8D50B /* ShareDisplayable.swift */; };
BABBDB362AAD904100D8D50B /* CoreDataError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BABBDB352AAD904100D8D50B /* CoreDataError.swift */; };
BAECB2CF2AB15742006B4A46 /* Key.plist in Resources */ = {isa = PBXBuildFile; fileRef = BAECB2CE2AB15742006B4A46 /* Key.plist */; };
BAECB2D12AB157CB006B4A46 /* NetworkConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAECB2D02AB157CB006B4A46 /* NetworkConfiguration.swift */; };
C739AE25284DF28600741E8F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C739AE24284DF28600741E8F /* AppDelegate.swift */; };
C739AE27284DF28600741E8F /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C739AE26284DF28600741E8F /* SceneDelegate.swift */; };
C739AE29284DF28600741E8F /* DiaryListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C739AE28284DF28600741E8F /* DiaryListViewController.swift */; };
Expand Down Expand Up @@ -54,6 +56,8 @@
BABBDAE42A9F13A200D8D50B /* DecodingError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecodingError.swift; sourceTree = "<group>"; };
BABBDB332AA6D05A00D8D50B /* ShareDisplayable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareDisplayable.swift; sourceTree = "<group>"; };
BABBDB352AAD904100D8D50B /* CoreDataError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataError.swift; sourceTree = "<group>"; };
BAECB2CE2AB15742006B4A46 /* Key.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Key.plist; sourceTree = "<group>"; };
BAECB2D02AB157CB006B4A46 /* NetworkConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkConfiguration.swift; sourceTree = "<group>"; };
C739AE21284DF28600741E8F /* Diary.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Diary.app; sourceTree = BUILT_PRODUCTS_DIR; };
C739AE24284DF28600741E8F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
C739AE26284DF28600741E8F /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -99,6 +103,7 @@
isa = PBXGroup;
children = (
632F74EF2AB14D2C003E1B97 /* NetworkManager.swift */,
BAECB2D02AB157CB006B4A46 /* NetworkConfiguration.swift */,
);
path = Network;
sourceTree = "<group>";
Expand Down Expand Up @@ -182,6 +187,7 @@
C739AE18284DF28600741E8F = {
isa = PBXGroup;
children = (
BAECB2CE2AB15742006B4A46 /* Key.plist */,
63E527342A9D7EBF0000FBA6 /* .swiftlint.yml */,
C739AE23284DF28600741E8F /* Diary */,
C739AE22284DF28600741E8F /* Products */,
Expand Down Expand Up @@ -277,6 +283,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BAECB2CF2AB15742006B4A46 /* Key.plist in Resources */,
63E527352A9D7EBF0000FBA6 /* .swiftlint.yml in Resources */,
C739AE34284DF28600741E8F /* LaunchScreen.storyboard in Resources */,
C739AE31284DF28600741E8F /* Assets.xcassets in Resources */,
Expand Down Expand Up @@ -342,6 +349,7 @@
BA1A55ED2A9D90810012C89D /* DateFormatter+.swift in Sources */,
63E527372A9D87660000FBA6 /* DiaryListTableViewCell.swift in Sources */,
C739AE2F284DF28600741E8F /* Diary.xcdatamodeld in Sources */,
BAECB2D12AB157CB006B4A46 /* NetworkConfiguration.swift in Sources */,
63BB62B52AA182AA00524DCB /* CoreDataManager.swift in Sources */,
632F74F02AB14D2C003E1B97 /* NetworkManager.swift in Sources */,
63E527392A9D97160000FBA6 /* DiaryDetailViewContoller.swift in Sources */,
Expand Down
44 changes: 43 additions & 1 deletion Diary/Controller/DiaryDetailViewContoller.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ final class DiaryDetailViewContoller: UIViewController, AlertDisplayable, ShareD
private let container = CoreDataManager.shared.persistentContainer
private var diary: Diary
private var isNew: Bool
private var latitude: Double?
private var longitude: Double?

init() {
init(latitude: Double?, longitude: Double?) {
self.diary = CoreDataManager.shared.createDiary()
self.isNew = true
self.latitude = latitude
self.longitude = longitude

super.init(nibName: nil, bundle: nil)
fetchWeather()
}

init(_ diary: Diary) {
Expand Down Expand Up @@ -194,3 +200,39 @@ extension DiaryDetailViewContoller: UITextViewDelegate {
diary.body = body
}
}

extension DiaryDetailViewContoller {
func fetchWeather() {
guard let latitude, let longitude else { return }

NetworkManager.shared.fetchData(
NetworkConfiguration.weatherAPI(latitude: latitude, longitude: longitude)
) { [weak self] result in
guard let self else { return }

switch result {
case .success(let data):
do {
let decodingData: WeatherResult = try DecodingManager.decodeData(from: data)
print(decodingData.weather.first!.main) // TODO: 마이그레이션 후 삭제
} catch {
DispatchQueue.main.async {
let confirmAction = UIAlertAction(title: ButtonNamespace.confirm, style: .default)
self.showAlert(title: AlertNamespace.networkErrorTitle,
message: nil,
actions: [confirmAction],
preferredStyle: .alert)
}
}
case .failure:
DispatchQueue.main.async {
let confirmAction = UIAlertAction(title: ButtonNamespace.confirm, style: .default)
self.showAlert(title: AlertNamespace.networkErrorTitle,
message: nil,
actions: [confirmAction],
preferredStyle: .alert)
}
}
}
}
}
33 changes: 30 additions & 3 deletions Diary/Controller/DiaryListViewController.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
//
// Diary - ViewController.swift
// Diary - DiaryListViewController.swift
// Created by yagom.
// Copyright © yagom. All rights reserved.
// Last modified by Maxhyunm, Hamg.

import UIKit
import CoreLocation

final class DiaryListViewController: UIViewController {
private var locationManager = CLLocationManager()
private let tableView: UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
Expand All @@ -18,9 +20,13 @@ final class DiaryListViewController: UIViewController {
private let container = CoreDataManager.shared.persistentContainer
private var diaryList = [Diary]()

private var latitude: Double?
private var longitude: Double?

override func viewDidLoad() {
super.viewDidLoad()

setupLocationManager()
updateLocation()
configureUI()
setupNavigationBarButton()
setupTableView()
Expand Down Expand Up @@ -49,7 +55,7 @@ final class DiaryListViewController: UIViewController {
private func setupNavigationBarButton() {
let addDiary = UIAction(image: UIImage(systemName: "plus")) { [weak self] _ in
guard let self else { return }
let createDiaryView = DiaryDetailViewContoller()
let createDiaryView = DiaryDetailViewContoller(latitude: latitude, longitude: longitude)
self.navigationController?.pushViewController(createDiaryView, animated: true)
}

Expand Down Expand Up @@ -156,3 +162,24 @@ extension DiaryListViewController: UITableViewDelegate, ShareDisplayable {
return UISwipeActionsConfiguration(actions: [delete, share])
}
}

extension DiaryListViewController: CLLocationManagerDelegate {
private func setupLocationManager() {
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}

private func updateLocation() {
let locationStatus: [CLAuthorizationStatus] = [.authorizedAlways, .authorizedWhenInUse]

guard locationStatus.contains(locationManager.authorizationStatus) else { return }

locationManager.startUpdatingLocation()

guard let location: CLLocationCoordinate2D = locationManager.location?.coordinate else { return }

latitude = location.latitude
longitude = location.longitude
}
}
2 changes: 2 additions & 0 deletions Diary/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,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>NSLocationWhenInUseUsageDescription</key>
<string>위치 정보 수집을 수락합니다</string>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
Expand Down
1 change: 1 addition & 0 deletions Diary/Model/AlertNamespace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
enum AlertNamespace {
static let deleteTitle = "진짜요?"
static let deleteMessage = "정말로 삭제하시겠어요?"
static let networkErrorTitle = "네트워크 오류입니다"
}
32 changes: 32 additions & 0 deletions Diary/Network/NetworkConfiguration.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// NetworkConfiguration.swift
// Diary
//
// Created by Maxhyunm, Hamg on 2023/09/13.
//

import Foundation

enum NetworkConfiguration {
case weatherAPI(latitude: Double, longitude: Double)
case weatherIcon(id: String)

var url: String? {
switch self {
case .weatherAPI(let latitude, let longitude):
guard let apiKey = NetworkConfiguration.apiKey else { return nil }
return "https://api.openweathermap.org/data/2.5/weather?lat=\(latitude)&lon=\(longitude)&appid=\(apiKey)"
case .weatherIcon(let id):
return "https://openweathermap.org/img/wn/\(id).png"
}
}

static var apiKey: String? {
guard let path = Bundle.main.url(forResource: "Key", withExtension: "plist"),
let plist = NSDictionary(contentsOf: path),
let key = plist.value(forKey: "WeatherAPIKey") else {
return nil
}
return "\(key)"
}
}
28 changes: 7 additions & 21 deletions Diary/Network/NetworkManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@
import CoreLocation

final class NetworkManager {
static let shared = NetworkManager()
private var dataTask: URLSessionDataTask?

func fetchData(url: String, completionHandler: @escaping(Result<Data, APIError>) -> Void) {
guard let url = URL(string: url) else {
completionHandler(.failure(.invalidURL))
private init() {}

func fetchData(_ networkType: NetworkConfiguration, completionHandler: @escaping(Result<Data, APIError>) -> Void) {
guard let urlString = networkType.url,
let url = URL(string: urlString) else {
completionHandler(.failure(APIError.invalidURL))
return
}

Expand All @@ -35,22 +39,4 @@ final class NetworkManager {
}
self.dataTask?.resume()
}

func fetchLocation(location: CLLocation, _ completionHandler: @escaping(Result<WeatherResult, APIError>) -> Void) {
let urlStr = "https://api.openweathermap.org/data/2.5/weather?lat=\(location.coordinate.latitude)&lon=\(location.coordinate.longitude)&appid=aaa5700cbd82d1a09e738731002f97be"

fetchData(url: urlStr) { result in
switch result {
case .success(let data):
do {
let decodingData: WeatherResult = try DecodingManager.decodeData(from: data)
completionHandler(.success(decodingData))
} catch {
completionHandler(.failure(APIError.decodingFail))
}
case .failure(let error):
completionHandler(.failure(error))
}
}
}
}
8 changes: 8 additions & 0 deletions Key.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?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>WeatherAPIKey</key>
<string>aaa5700cbd82d1a09e738731002f97be</string>
</dict>
</plist>

0 comments on commit a98cabd

Please sign in to comment.