티스토리 뷰

반응형

firebase-delete라는 feature 브랜치를 하나 만들어줍니다 

FirebaseManager 안에 delete라는 class fucntion을 만듭니다 

    class func delete(key: String) {
        let rootRef = Database.database().reference()
        let memoRef = rootRef.child("memos").child(key)
        memoRef.removeValue()
    }

 

 

delete하려면 각 데이터(메모)의 key 값을 알고 있어야합니다  

 

현재는 Memo를 Firebase에 추가할 때 firebase가 자동으로 key값(혹은 아이디 값) 을 만들어주게 설정되어있습니다 

    class func add(memo: Memo) {
        let rootRef = Database.database().reference()
        let memosRef = rootRef.child("memos")
        
        let memoRef = memosRef.childByAutoId()
        memoRef.setValue(memo.toDictionary())
    }

그래서 로컬 쪽에서는 서버에 어떤 아이디로 데이터가 저장되어있는지 모릅니다

Firebase에서 fetch해서 메모들을 가져올 때, key값도 메모 구조체에 같이 저장해주도록 합시다 --! ID 라는 필드를 하나 추가합니다 

 

이 구조체는 로컬에서 title로 메모를 만들때는 ID값이 안들어가고 

Firebase에서 데이터를 가져오면서 메모를 만들때는 ID값이 들어가는 형태(?)가 되겠습니다 

struct Memo {
    let ID: String
    let title: String

    init(title: String) {
        self.ID = ""
        self.title = title
    }
    
    init?(dic: [String: Any], ID: String) {
        guard let title = dic["title"] as? String else {
            return nil
        }
        
        self.ID = ID
        self.title = title
    }
}

extension Memo {
    func toDictionary() -> [String: Any] {
        return ["title": title]
    }
}

 

fetchAll 함수도 key값을 ID에 저장하게 바꿔줍니다

class func fetchAll() -> Observable<[Memo]> {
    return Observable<[Memo]>.create { observer in
        let rootRef = Database.database().reference()
        rootRef.child("memos").observe(.value) { snapshot in
            var memos: [Memo] = []
            let memosDic = snapshot.value as? [String: Any] ?? [:]
            for (key, _) in memosDic.sorted(by: {$0.key < $1.key}) {
                if let memoDic = memosDic[key] as? [String: Any], let memo = Memo(dic: memoDic, ID: key) {
                    memos.append(memo)
                }
            }
            observer.onNext(memos)
        }
        return Disposables.create()
    }
}

 

MemosViewModel에서 

print("delete \(memo)")

대신 

FirebaseManager.delete(key: memo.ID)

를 넣어줍니다 

struct MemosViewModel {
    
    struct State {
        var memos: BehaviorRelay<[Memo]> = BehaviorRelay.init(value: [])
    }
    
    struct Action {
        let deleteMemo = PublishSubject<Memo>()
        let changeMemo = PublishSubject<Memo>()
    }
    
    let state = State()
    let action = Action()
    private let bag = DisposeBag()
    
    init() {
        action.deleteMemo.subscribe(onNext: { memo in
            FirebaseManager.delete(key: memo.ID)
        }).disposed(by: bag)
        
        action.changeMemo.subscribe(onNext: { memo in
            print("change \(memo)")
        }).disposed(by: bag)
        
        FirebaseManager.fetchAll()
            .bind(to: state.memos)
            .disposed(by: bag)
    }
}

 

이렇게 테이블 뷰 셀을 trailing swipe 하면

 

이 부분의 코드가 호출되면서 

    func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let delete = deleteAction(at: indexPath)
        return UISwipeActionsConfiguration(actions: [delete])
    }
    
    private func deleteAction(at indexPath: IndexPath) -> UIContextualAction {
        let action = UIContextualAction(style: .normal, title: "삭제") { [weak self] (action, view, completion) in
            guard let `self` = self else { return }
            let memo = self.viewModel.state.memos.value[indexPath.row]
            self.viewModel.action.deleteMemo.onNext(memo)
        }
        action.backgroundColor = .red
        return action
    }

 

순간 빨간색으로 해당 데이터가 변하고


데이터가 삭제되는 것을 볼 수 있습니다 : ) 

 

반응형
댓글