Pillanner 프로젝트 하면서 일어난 일...
Client에서 🔥Firestore로 데이터 저장하고, 가져오기
데이터 저장하기
- Firestore는
Collection
-> Document
-> Collection
-> Document
... 형태로 데이터를 쌓아서 스택처럼 사용할 수 있다.
Collection
인스턴스의 whereField(, isEqualTo:)
메서드를 사용해서 특정 조건을 만족하는 Document
로 접근할 수 있음. (whereField
메서드는 특정 Document
를 리턴하므로, SQL의 쿼리처럼 사용하면 됨!)
Document
는 getDocuments
메서드를 사용할 수 있고, 해당 메서드는 아래와 같은 방법으로 활용한다.
AA.getDocuments{ (snapshot, error) in
guard let snapshot = snapshot, !snapshot.isEmpty else {
Document가 비었을 때 실행할 구문(데이터를 새로 생성 등...)
}
Document가 있을 때 실행할 구문(데이터 수정 및 삭제 등...)
}
- 데이터 값을 함수의 매개변수로 받아,
getDocuments
메서드 내부에서 적절하게 사용하면 Firestore에 새로운 Document를 생성해서 데이터를 저장할 수 있게 된다!
데이터 가져오기
- Firestore에서 데이터를 가져올 때도 데이터를 저장할 때 처럼 함수를 생성해서 가져오게 된다.
- 데이터 저장할 때와는 다르게, 가져와서 사용하고자 할 때는 함수의 매개변수 부분에
completionHandler
를 만들어주고 사용해야 함!
- 왜냐! 우리는 데이터를 가져오기만 하고 말 것이 아니라, 가져온 데이터를 고치고, 화면에 띄워주는 등등 여러가지 작업을 할 것이기 때문임
func getData(_ data: String, _ completion: @escaping (String?) -> Void) {
var storedID = ""
var col = db.collection("collection").whereField("ID", isEqualTo: data)
col.getDocuments{ (snapshot, error) in
guard let snapshot = snapshot, !snapshot.isEmpty else {
for document in snapshot.documents {
storedID = document.data()["ID"]
}
completion(storedID)
}
}
}
- 위와 같은 식으로 데이터를 가져오는 함수 내에서
@escaping
키워드를 사용한 completionHandler
를 만들어줘야, 해당 함수 외의 부분에서 데이터를 잃어버리지 않고 화면에 띄우고, 수정하고, 저장해두고 지우는 등의 여러가지 작업을 진행할 수 있다!
왜 @escaping 키워드를 사용해야 되나?
- 추리해보자면... (뇌피셜입니다)
- 함수의 매개변수, 지역변수나 반환 값은 기기의 스택 영역에 저장되며 함수가 끝나면 해당 메모리가 반환된다.
- 원하는 데이터를 가져오는 함수인 getData가 끝나고서, 가져온 데이터를 사용해 새로운 작업을 하려고 할 때 데이터가 담긴 메모리가 반환되면 사용할 수 없다!
- 그렇기 때문에, 함수의 흐름을 벗어날 수 있도록 해주는 @escaping 키워드를 사용해야, 데이터가 반환되지 않고 원하는 작업에 쓰일 수 있도록 할 수 있다! 라고 생각한다.