【Swift】Cloud Firestore로 map형을 취득하는 Tips
수정 (02/14)
두 번째 방법은
FirebaseFirestoreSwift
를 사용하지 않으면 할 수 없다는 것은 자신의 착각이었습니다. 죄송합니다.현재는, 수정하고 있습니다.
소개
최근 Firestore를 사용한 데모 앱을 만들어 놀고 있습니다.
Firestore에서 지원되는 데이터 유형은 다양하지만, 이번에는 그 중에서도 map 타입의 데이터를 얻는 방법에 대해 썼습니다.
Firestore에서 지원하는 데이터 유형에 대한 자세한 내용은 이 공식 참조를 참조하세요.
htps : // 푹 빠져라. 오, ぇ. 코 m / 드 cs / 푹신 s 잡히다 / 마나게 - data / Data-type s
이번에는 두 가지 방법을 실어 둡니다.
운영 환경
이번에 취득하는 Firestore의 데이터 & Swift측의 오브젝트
Firestore의 map형을 취득하는 것으로, Firestore측의 데이터 구조가 있는 편이 알기 쉽다고 생각했으므로, 올려 둡니다.
■ Firestore의 map형 데이터 모델
■ Swift측의 오브젝트(구조체)
Order.swift
struct Order: Codable {
let id: String
let orderNo: Int
let imageName: String
let name: String
let price: Int
let isWasabi: Bool
var isOrderComplete: Bool
}
[String : Any]에서 직접 인스턴스를 생성하는 방법
func fetchOrderMap_A() {
db.collection("ordering").document("01").getDocument { (_document, _error) in
guard _error == nil else {
print("Firestoreからエラーを受け取りました。")
return
}
if let document = _document, document.exists {
// document.data()は、[String : Any]になる
let mapData = document.data() ?? [:]
print(mapData) // ※補足参照
var orderList: [Order] = []
// データを1件ずつ抽出
for (_, data) in mapData {
// data(Any型)をdicData([String: Any]型)にキャストする <- Point
let dicData = data as! [String : Any]
// [String: Any]にキャストされていることを確認
print(dicData)
// key - value でプロパティ別に値を取り出す。(今回は強制アンラップ。Firestoreのデータ型に合わせてキャストすれば問題なし。)
let id = dicData["id"] as! String
let orderNo: Int = dicData["orderNo"] as! Int
let imageName: String = dicData["imageName"] as! String
let name: String = dicData["name"] as! String
let price: Int = dicData["price"] as! Int
let isWasabi: Bool = dicData["isWasabi"] as! Bool
let isOrderComplete: Bool = dicData["isOrderComplete"] as! Bool
// インスタンス生成して配列に追加
let order = Order(id: id, orderNo: orderNo, imageName: imageName, name: name, price: price, isWasabi: isWasabi, isOrderComplete: isOrderComplete)
orderList.append(order)
}
// 生成された配列を出力
print(orderList)
} else {
print("ドキュメントが存在しません。")
}
}
}
※보충
print(mapData)
런타임의 mapData
내용은 이런 느낌입니다.보충
["2": {
id = 002;
imageName = samon;
isOrderComplete = 1;
isWasabi = 1;
name = "\U30b5\U30fc\U30e2\U30f3";
orderNo = 2;
price = 150;
}, "1": {
id = 001;
imageName = "maguro_akami";
isOrderComplete = 0;
isWasabi = 0;
name = "\U8d64\U8eab\U30de\U30b0\U30ed";
orderNo = 1;
price = 100;
}]
위와 같이 key, value의 배열이 되어 있으므로,
for文
로 1건씩 처리해 갑니다.데이터를 1건 취득할 수 있으면, 취득하고 싶은 데이터부를
[String : Any]
로 캐스트 합니다.현재는
name
가 유니 코드이지만 문제는 없습니다.이러한 스텝을 밟는 것으로, Swift로부터 용이하게 취급할 수 있는 형태로 하고 있습니다.
여기까지 구현할 수 있으면, 후에는 통상의 JSON 해석등과 하는 방법은 같다고 생각합니다.
JSON을 씹고 Codable을 사용하는 방법
func fetchOrderMap_B() {
db.collection("ordering").document("01").getDocument { (_document, _error) in
guard _error == nil else {
print("Firestoreからエラーを受け取りました。")
return
}
if let document = _document, document.exists {
// document.data()は、[String : Any]になる
let mapData = document.data() ?? [:]
print(mapData) // ※補足参照
var orderList: [Order] = []
// データを1件ずつ抽出
for (_, data) in mapData {
// data(Any型)をdicData([String: Any]型)にキャストする <- Point
let dicData = data as! [String : Any]
// [String: Any]にキャストされていることを確認
print(dicData)
// ここからJSONを利用する場合の固有処理
// JSON へ一時的にキャスト
let jsonData = try? JSONSerialization.data(withJSONObject: dicData)
// JSON -> Order(Codable)
let order = try? JSONDecoder().decode(Order.self, from: jsonData!)
if let order = order {
orderList.append(order)
}
}
// 生成された配列を出力
print(orderList)
} else {
print("ドキュメントが存在しません。")
}
}
}
처리 내용은 코멘트에 썼습니다만, 포인트는
[String:Any]
-> JSON
-> Order
와 같이 일시적으로 JSON
를 씹고 나서, 목적의 Order
에 도착해 있는 것입니다.자신은 이 방법 밖에 생각하지 않았습니다만, 만약 그 밖에 좋은 방법이 있으면 코멘트에서 가르쳐 주시면 기쁩니다.
요약
처음 구현하고 있었을 때는, Firestore로 map형을 취득하면, 아무것도 생각하지 않고 디코드할 수 있다고 생각했습니다만,
id = 002;
와 같은 형식으로 값이 돌아왔기 때문에 처음 당황했습니다.iOS 앱 개발시 Firestore의 map형을 사용하고 싶은 분은 참고해 주시면 감사하겠습니다.
Reference
이 문제에 관하여(【Swift】Cloud Firestore로 map형을 취득하는 Tips), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ctnc_67/items/f17472a0b40452800a6c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)