본문 바로가기
iOS Swift/Study

[Swift] 알람앱 - 타이머(6) 최근 타이머 목록 저장, 삭제, 실행

by 야고이 2024. 5. 21.
728x90

최근 항목을 담을 빈배열 생성

private var timerLists: [(time: Int, name: String?)] = []

 

Core Data에 타이머 최근 항목 저장

코어데이터 모델을 만들어 줍니다

타이머 이름과 시간만 저장하므로 두개 생성!

주의사항! 엔티티 이름을 Timer 라고 했었는데 Swift 에 Timer 클래스가 이미 존재해서 오류가 났다 그래서 MyTimer 로 수정해줌

 

코어데이터 저장, 불러오기, 삭제 메서드 생성

func saveTimer(name: String, time: Int) {
    guard let context = persistentContainer?.viewContext else { return }
    let myTimer = MyTimer(context: context)
    myTimer.name = name
    myTimer.time = Int32(time)

    do {
        try context.save()
        print("타이머가 성공적으로 저장되었습니다.")
    } catch {
        print("타이머 저장에 실패했습니다: \(error)")
    }
}
// core data 불러오기
func fetchTimers() {
    guard let context = persistentContainer?.viewContext else { return }
    let fetchRequest = MyTimer.fetchRequest()

    do {
        let timers = try context.fetch(fetchRequest)
        timerLists = timers.map { timer in // 저장된 데이터를 timerLists 에 담아준다
            let time = Int(timer.time)
            let name = timer.name
            return (time: time, name: name)
        }
        timerLists.reverse()
        reloadTableView()
    } catch {
        print("타이머를 가져오는데 실패했습니다: \(error)")
    }
}

// core data 삭제
func deleteTimer(timer: (time: Int, name: String?)) {
    guard let context = persistentContainer?.viewContext else { return }
    let fetchRequest = MyTimer.fetchRequest()
    fetchRequest.predicate = NSPredicate(format: "name == %@ AND time == %d", timer.name ?? "", timer.time)

    do {
        let fetchedTimers = try context.fetch(fetchRequest)
        for fetchedTimer in fetchedTimers {
            context.delete(fetchedTimer)
        }
        try context.save()
        print("타이머가 성공적으로 삭제되었습니다.")
    } catch {
        print("타이머 삭제에 실패했습니다: \(error)")
    }
}

fetchTimers() 는 viewDidLoad 에 호출해줌

 

timerLists.reverse()

어플을 재실행 하면 코어데이터 저장한 순서대로 보여져서 배열을 반대로 재정렬 해주었다

 

 

최근 실행한 타이머 추가 해주는 함수 생성

func addRecentTimer() {
    let timerName = nameInputTextField.text ?? ""
    let timerTime = setTime

    // Core Data에 저장
    saveTimer(name: timerName, time: timerTime)

    // 메모리 내 목록과 UI 업데이트
    timerLists.insert((time: timerTime, name: timerName), at: 0) //배열의 첫번째에 저장

    nameInputTextField.text = "" // 저장 후 텍스트 필드 비워주기
    reloadTableView()
}

 

타이머 이름은 있을 수도 없을 수도 있다

코어 데이터에 저장 후 빈배열에 담아준다 가장 최근이 위에 담기게 하기 위해서 insert 메서드를 사용한다

Start 버튼을 누르면 타이머 이름을 설정하는 텍스트 필드를 비어준다

그리고 테이블뷰 리로드! 테이블뷰는 배열의 갯수에 따라 높이가 달라져서 함수를 만들어 실행해 줬다

 

Start 버튼을 누를 때 최근 항목 저장 및 테이블뷰 리로드를 실행해주기

@objc func didTapStartButton() { switch timerState {
    case .started, .resumed :
        // 시작을 누르면 버튼을 pause 로 바꿔야함
        timer.invalidate()
        timerState = .pause
        updateTimerState()
    case .pause:
        // 일시정지를 누르면 resume 으로 버튼 변경, 시간 멈춤
        setTimer(with: setTime)
    case .canceled, .finished:
        self.setTime = Int(timerDurationPicker.duration) // 설정 된 시간
        addRecentTimer() // 최근항목 추가
        reloadTableView() // 테이블뷰 리로드
        setTimer(with: setTime)
    }
}

 

앱을 종료 했다가 켜도 그대로!

최근 항목 선택시 해당 타이머 실행

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let time = timerLists[indexPath.row]
    setTimer(with: Int(time.time))
}

didSelectRowAt 에서 클릭한 행의 타이머를 실행해 줍니다

타이머실행 함수

 

최근 항목 삭제

func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
    .delete
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        let timerToDelete = timerLists[indexPath.row]
        deleteTimer(timer: timerToDelete) // 코어데이터에서 삭제
        timerLists.remove(at: indexPath.row) // 배열에서 삭제
        recentlyUsedTabelView.deleteRows(at: [indexPath], with: .fade) // 테이블뷰 행 삭제
        reloadTableView()
        print("timerLists\(timerLists)")
    }
}

삭제하는 순서 중요!!

728x90

댓글