Firebase用のモデルをstructで作成
- 必須のフィールドには初期値を設定しないことで初期化の時点で入力漏れを防ぐ。
- nullを許容する場合Optional型にする。その場合分岐が必要。
- nullの場合はNSNull()を入れる。RDBみたいにNullを格納するというよりNull型になる。
- FirebaseFirestore.GeoPoint 、FirebaseFirestore.Timestampなどは読み込み時と保存時にSwiftの型から変換する。
- enumは保存時はrawValueを入れて、読み込み時はenumに戻す。
struct User {
var uid: String
var name: String
var imageUrl: String = ""
var memberClass: MemberClass = .free
var createdAt: Date?
var currentLocation: CLLocationCoordinate2D?
enum MemberClass: String {
case free
case paid
}
init(uid: String, name: String) {
self.uid = uid
self.name = name
}
init(_ uid: String, data: [String: Any]) {
self.uid = uid
name = data["name"] as? String ?? ""
imageUrl = data["imageUrl"] as? String ?? ""
if let memberClassString = data["memberClass"] as? String {
if let memberClass = MemberClass(rawValue: memberClassString) {
self.memberClass = memberClass
}
}
if let geopoint = data["currentLocation"] as? FirebaseFirestore.GeoPoint {
currentLocation = CLLocationCoordinate2DMake(geopoint.latitude, geopoint.longitude)
}
if let dataCreatedAt = data["createdAt"] as? FirebaseFirestore.Timestamp {
createdAt = dataCreatedAt.dateValue()
}
}
var dictionary: [String: Any] {
var dictionary = [String: Any]()
dictionary["name"] = name
dictionary["imageUrl"] = imageUrl
dictionary["memberClass"] = memberClass.rawValue
if let currentLocation = currentLocation {
dictionary["currentLocation"] = FirebaseFirestore
.GeoPoint(latitude: Double(currentLocation.latitude),
longitude: Double(currentLocation.longitude))
} else {
dictionary["currentLocation"] = NSNull()
}
dictionary["createdAt"] = FieldValue.serverTimestamp()
return dictionary
}
}
使い方
- Firebaseから取り出す場合の初期化関数initを用意する。User(document.documentID, data: document.data()) でstructに値が格納される。
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let data = document.data() ?? [:]
user = User(document.documentID, data: data)
} else {
print("User not found")
}
- Firebaseに入れる場合にdictionaryを返す関数を[String: Any]で用意する。setData(user.dictionary)でdictionaryに変換して取り出せる。
let docRef = firestore.collection("Users").document()
docRef.setData(user.dictionary) { error in
if let error = error {
print("Error updating document: \(error)")
} else {
print("Document added with ID: \(docRef.documentID)")
}
}