Conversation
- 메인도시 이름 및 현재온도, 최소/최대온도, 날씨 이미지 표기 뷰 구현
- 현재시간 API 값과 연동되는 Model 생성
- API 연결 메소드 구현
- ViewModel 생성 및 API 연결 메소드 추가
- ImageIcon 호출 코드 추가(이슈: 해당 사이트에서 샘플 이미지 한개를 제외하고 전체 사용불가, 임시로 하나만 로드하게 해놓음)
- 과거 날씨 정보 모델 추가 - 과거 날씨 API 로직 추가 - 과거 날씨 출력 뷰 생성 - 메인 뷰에서 날씨 정보를 나타내는 컴포넌트를 컬랙션 뷰에 삽입 및 전홤 표출 - 과거 정보 표기 추가
Summary of ChangesHello @godzx3-ctrl, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 이 풀 리퀘스트는 날씨 예측 애플리케이션의 핵심 기능 개발을 완료합니다. 외부 라이브러리(SnapKit, Then)를 통합하고, OpenWeather API를 통해 날씨 데이터를 가져오고 표시하기 위한 데이터 모델, 서비스 계층, UI 컴포넌트 및 뷰 모델을 포함하는 구조화된 아키텍처를 구현합니다. 이를 통해 현재 날씨 정보와 여러 날의 예보를 효율적으로 관리하고 사용자에게 제공할 수 있습니다. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
| if let data = try? Data(contentsOf: imageUrl) { | ||
| if let image = UIImage(data: data) { | ||
| self.mainImage = image | ||
| } | ||
| } |
There was a problem hiding this comment.
Data(contentsOf:)는 동기적으로 네트워크 요청을 수행하여 현재 스레드를 차단합니다. 이 코드는 백그라운드 스레드에서 실행되지만, 여전히 스레드를 차단하는 것은 좋지 않은 방식이며 성능 저하를 유발할 수 있습니다. URLSession.dataTask를 사용하여 이미지를 비동기적으로 로드해야 합니다.
self.openApi.loadImage(url: imageUrl) { [weak self] data in
guard let self = self, let data = data, let image = UIImage(data: data) else {
return
}
self.mainImage = image
DispatchQueue.main.async {
self.UpdateCurrentUIClousure?()
}
}| guard let imageUrl = URLComponents(string: "https://openweathermap.org/payload/api/media/file/10d@2x.png")?.url else | ||
| { | ||
| print("Create URL Failed") | ||
| return | ||
| } |
There was a problem hiding this comment.
이미지 URL이 하드코딩되어 있어 항상 같은 날씨 아이콘이 표시됩니다. 이는 버그입니다. API 응답으로 받은 weather 데이터의 icon 프로퍼티를 사용하여 동적으로 이미지 URL을 생성해야 합니다. 올바른 URL 형식은 https://openweathermap.org/img/wn/{icon_id}@2x.png 입니다.
guard let iconId = result.weather.first?.icon,
let imageUrl = URL(string: "https://openweathermap.org/img/wn/\(iconId)@2x.png") else| vm.UpdateCurrentUIClousure = { [weak self] in | ||
| guard let self else { return } | ||
| cell.currentWheatherView.UpdateUIData ( | ||
| cityName: vm.currentWheaterModel?.name ?? "", | ||
| currentTemp: vm.currentWheaterModel?.main.temp ?? 0.0, | ||
| minTemp: vm.currentWheaterModel?.main.tempmin ?? 0.0, | ||
| maxTemp: vm.currentWheaterModel?.main.tempmax ?? 0.0, | ||
| image: vm.mainImage | ||
| ) | ||
| } |
| case currentWheatherView | ||
| /// 과거 날씨 뷰 | ||
| case ForecastView | ||
| } | ||
|
|
||
| // MARK: - Closures | ||
| /// 현재 날씨 UI 업데이트 요청 클로저 | ||
| var UpdateCurrentUIClousure: (()-> Void)? | ||
| /// 과거 날씨 UI 업데이트 요청 클로저 | ||
| var UpdateForecastUIClosure: (()-> Void)? | ||
|
|
||
| //MARK: - Properties | ||
| /// API 클래스 | ||
| let openApi = OpenWeatherAPIService() | ||
| /// 현재 정보 모델 | ||
| var currentWheaterModel: CurrentWeatherModel? = nil | ||
| /// 과거 정보 모델 | ||
| var forecastWheaterModel: ForecastWeatherModel? = nil | ||
| /// 기상 이미지 | ||
| var mainImage: UIImage? = nil | ||
| /// 뷰 타입 지정 | ||
| var viewTypes: [ViewType] = [.currentWheatherView, .ForecastView] |
| static func getImageUrl() -> URL? { | ||
| return URLComponents(string: "https://openweathermap.org/payload/api/media/file/10d@2x.png")?.url | ||
| } |
There was a problem hiding this comment.
이미지 URL이 하드코딩되어 있어 항상 같은 날씨 아이콘을 보여주는 버그가 있습니다. OpenWeatherMap API 응답에 포함된 icon ID를 사용하여 동적으로 URL을 생성해야 합니다. 예를 들어, https://openweathermap.org/img/wn/{icon_id}@2x.png 형식으로 URL을 만들어야 합니다.
| static func getImageUrl() -> URL? { | |
| return URLComponents(string: "https://openweathermap.org/payload/api/media/file/10d@2x.png")?.url | |
| } | |
| static func getImageUrl(iconId: String) -> URL? { | |
| return URL(string: "https://openweathermap.org/img/wn/\(iconId)@2x.png") | |
| } |
|
|
||
| // MARK: - Closures | ||
| /// 현재 날씨 UI 업데이트 요청 클로저 | ||
| var UpdateCurrentUIClousure: (()-> Void)? |
| guard let decodeData = try? JSONDecoder().decode(T.self, from: data) else { | ||
| print("Decoding Failed") | ||
| completion(nil) | ||
| return | ||
| } | ||
| print("Decoding Success") | ||
| completion(decodeData) |
There was a problem hiding this comment.
try?를 사용하여 디코딩 오류를 무시하면 디버깅이 어려워집니다. do-catch 블록을 사용하여 어떤 오류가 발생했는지 로그를 남기는 것이 좋습니다.
| guard let decodeData = try? JSONDecoder().decode(T.self, from: data) else { | |
| print("Decoding Failed") | |
| completion(nil) | |
| return | |
| } | |
| print("Decoding Success") | |
| completion(decodeData) | |
| do { | |
| let decodeData = try JSONDecoder().decode(T.self, from: data) | |
| print("Decoding Success") | |
| completion(decodeData) | |
| } catch { | |
| print("Decoding Failed: \(error)") | |
| completion(nil) | |
| } |
|
|
||
| class OpenWeatherAPIService { | ||
| /// API 호출 메소드 | ||
| func requestAPI<T: Decodable>(Url: URL, completion: @escaping (T?)-> Void) { |
| extension MainViewModel { | ||
|
|
||
| /// 현재 기상 정보 API 요청 메소드 | ||
| func requestCurrentWheaterData() { |
| } | ||
|
|
||
| /// 과거 기상 정보 API 요청 메소드 | ||
| func requestForecastWheatherData() { |
No description provided.