WeatherApp Project (2)

ulls12·2024년 2월 8일
0

Swift TIL

목록 보기
39/60

저장해야할 속성

CoreData로 어떤 속성을 저장해야 앱을 다시 켰을 때, 사용자가 저장된 위치에 해당하는 날씨를 제공할 수 있을지 고민해보았다.
1. 사용자가 검색창에 자신이 원하는 지역을 검색한다.
2. 원하는 지역의 날씨 정보창에서 추가하기를 눌러 지역의 데이터를 저장한다.
3. 지역의 데이터만 CoreData에 저장해놓고 앱이 다시 실행될 때 지역의 데이터를 불러온다.
4. API 통신을 통해 불러와진 지역의 데이터를 통해 그 지역의 날씨를 확인할 수 있게 만들어준다.
그렇다면 지역의 데이터를 저장하는 방법은 크게 두가지 방식으로 나뉠 수 있다.
첫 번째 방법은 zip code를 저장해서 불러내는 것이였다. 해당 지역에 속하는 zip code를 CoreData에 저장해놓고 불러오는 방식이다.
두 번째 방법은 위도와 경도를 저장해서 불러내는 것이었다. 위와 같은 방식이지만, 저장해야할 속성 값이 두개이며, 데이터 관리가 좀 더 복잡해진다.

우선, OneWeatherMap에서 지역의 데이터를 뽑아내는 방식은 위도와 경도이다. 그래서 선택의 여지 없이 위도와 경도로 구성해야했다.

.xcdatamodel 구성


Entity 이름은 MapData, Attribute에서 위도와 경도는 각각 lat lon 으로 구성했으며 Double 타입으로 구성하여 소수점까지 저장될 수 있도록 구성했다.
Entity Inspector 에서 Codegen을 Class Definition으로 설정해놓으면, 따로 swift파일에서 class를 설정하지 않아도 자동으로 설정이 되있다.
이제 나는 MapData라는 Class에 lat 과 lon 이라는 변수가 들어있는 것이다.

CRUD 구성

날씨앱에서 자신이 지역을 추가하고 읽어서 다시 보여주고 지워주는 기능은 필요하지만, 자신이 설정한 지역을 수정하는 부분은 구현하지 않아도 된다고 반단했다. 그래서 CRUD에서 U를 뺀 CRD만 구성하게 되었다.

import Foundation
import CoreData
import UIKit

class CoreDataManager {
    // 싱글톤 패턴 적용
    static var shared = CoreDataManager()
    
    private let persistentContainer: NSPersistentContainer
    
    private init() {
        persistentContainer = NSPersistentContainer(name: "Thefirstorecast")
        persistentContainer.loadPersistentStores { (_, error) in
            if let error = error {
                fatalError("Failed to lad persistent storess: \(error)")
            }
        }
    }

우선 싱글톤 패턴을 적용하여 UI에서 관리하기 편하게 만들어 봤다.

    
    // Mapdata 생성하는 메서드
    func createMapData(lat: Double, lon: Double) {
        let context = persistentContainer.viewContext
        
        let mapData = MapData(context: context)
        mapData.lat = lat
        mapData.lon = lon
        
        do {
            try context.save()
            print("맵 데이터 생성이 성공적으로 진행")
        } catch {
            context.rollback()
            print("맵 데이터 생성 실패: \(error.localizedDescription)")
        }
        
    }
    
    // MapData 읽는 메서드
    func readMapData() -> [NSManagedObject] {
        let context = persistentContainer.viewContext
        let fetchRequest: NSFetchRequest<MapData> = MapData.fetchRequest()
        
        do {
            let mapData = try context.fetch(fetchRequest)
            return mapData
        } catch {
            print("맵 데이터 로드 실패: \(error.localizedDescription)")
            return []
        }
    }
    
    // MapData 삭제 메서드
    func deleteMapData(at indexPath: IndexPath) {
        let context = persistentContainer.viewContext
        let mapData = readMapData()
        let dataToDelete = mapData[indexPath.row]
        context.delete(dataToDelete)
        
        do {
            try context.save()
            print("맵 데이터 삭제 성공")
        } catch {
            context.rollback()
            print("맵 데이터 삭제 실패: \(error.localizedDescription)")
        }
    }
}

기초적인 틀은 다 잡은 것 같고 가장 중요한 것은 API와의 연결, UI와 잘 녹이는 게 가장 큰 핵심인 것 같다.

내일 할 일

  • API와 데이터 바인딩
  • UI에 dataflow 구성
profile
I am 개발해요

0개의 댓글