#ios #swift #google-cloud-firestore #swiftui
#iOS #swift #google-облако-firestore #swiftui
Вопрос:
итак, я создал проект XCode, в котором вы можете добавлять данные в Firestore и читать их, выполняя поиск сохраненных данных (серийный номер). Теперь я в основном попытался объединить эти 2 отдельных представления (вид поиска «вид формы»), чтобы получить 3-й вид, в котором вы можете искать «серийный номер», и вместо получения всего списка данных вы получаете текстовые поля с данными в нем (например, представление при добавленииэто за исключением того, что поля уже заполнены сохраненными данными). Итак, вот мои проблемы:
- Текстовые поля вроде как заполнены, но только серым текстом «заполнителя». Они должны быть заполнены обычным текстом, который можно редактировать, на случай, если манекен нажмет на сохранение, когда он только что отредактировал 1 строку, и все данные исчезнут
- Если я что-то пишу в текстовом поле, а затем нажимаю «Speichern» («Сохранить»), он всегда создает совершенно новый документ (который имеет действительно странный стиль идентификатора ([96251AF5-164A-4CBF-9BE6-9C9A482652DE ]) вместо изменения полей, и я сидел здесьвесь день пытаюсь заставить его работать.
Весь код как бы объединен из 2 разных видео. Надеюсь, вы сможете мне помочь (да, я знаю, это выглядит грязно)
Панель поиска редактирование представления SwiftUI
import SwiftUI
import Firebase
struct ContentViewVier: View {
@ObservedObject var data = getDataZwei()
var body: some View {
NavigationView{
ZStack(alignment: .top){
GeometryReader{_ in
// Home View....
Text("Bitte Seriennummer eingeben").foregroundColor(.black)
}.background(Color("FarbeSeriennummerStartbildschirm").edgesIgnoringSafeArea(.all))
CustomSearchBarEdit(data: self.$data.datas).padding(.top)
}.navigationBarTitle("")
.navigationBarHidden(true)
}
}
}
struct CustomSearchBarEdit : View {
@State var txt = ""
@Binding var data : [Gerät]
var body : some View{
VStack(spacing: 0){
HStack{
TextField("Nach Seriennummer suchen", text: self.$txt).opacity(100).foregroundColor(.black)
if self.txt != ""{
Button(action: {
self.txt = ""
}) {
Text("Abbrechen")
}
.foregroundColor(.black)
}
}.padding()
if self.txt != ""{
if
self.data.filter({$0.sn.lowercased() .contains(self.txt.lowercased())}).count == 0 {
Text("Es wurde kein Gerät mit dieser Seriennummer gefunden").foregroundColor(Color.red.opacity(0.6)).padding()
}
else{
List(self.data.filter{$0.sn.contains(self.txt.lowercased())}){i in
NavigationLink(destination: DetailZwei(data: i)) {
Text(i.sn)
}
Text(i.typ)
}.frame(height: UIScreen.main.bounds.height / 5)
}
}
}.background(Color.white)
.padding()
}
}
class getDataZwei : ObservableObject{
@Published var datas = [Gerät]()
init() {
let db = Firestore.firestore()
db.collection("Geräte").getDocuments { (snap, err) in
if err != nil{
print((err?.localizedDescription)!)
return
}
for i in snap!.documents{
let id = i.documentID
let sn = i.get("Seriennummer") as! String
let objekt = i.get("Objekt") as! String
let str = i.get("Strasse") as! String
let pos = i.get("Position") as! String
let typ = i.get("Gerätetyp") as! String
let ida = i.get("Installation")as! String
let lg = i.get("LeasingOderGekauft")as! String
let la = i.get("LeasingAblaufdatum")as! String
let ga = i.get("GarantieAblaufdatum")as! String
let nr = i.get("Hausnummer")as! String
let plz = i.get("Postleitzahl")as! String
let ort = i.get("Ort")as! String
let vp = i.get("Verantwortlich")as! String
let tel = i.get("Telefonnummer")as! String
let zusatz = i.get("Zusätzlich")as! String
self.datas.append(Gerät(id: id, sn: sn, objekt: pos, str: typ, nr: ida, ort: lg, vp: la, tel: ga, pos: objekt, typ: str, ida: nr, lg: plz, la: ort, ga: vp, zusatz: tel, plz: zusatz))
}
}
}
}
struct dataTypeZwei : Identifiable, Codable {
var id: String? = UUID().uuidString
var sn : String
var pos : String
var typ : String
var ida : String
var lg : String
var la : String
var ga : String
var objekt : String
var str : String
var nr : String
var plz : String
var ort : String
var vp : String
var tel : String
var zusatz : String
}
struct DetailZwei : View {
var data : Gerät
@State var viewModel = GerätEditieren()
@Environment(.presentationMode) var presentationMode
enum Mode {
case new
case edit
}
var mode: Mode = .edit
var body : some View{
NavigationView{
ScrollView{
VStack {
Group{
Text("Gerät")
.font(.title)
TextField(data.sn, text: $viewModel.gerät.sn).textFieldStyle(RoundedBorderTextFieldStyle())
.navigationBarTitle("Geräteinformationen")
TextField(data.objekt, text: $viewModel.gerät.objekt).textFieldStyle(RoundedBorderTextFieldStyle())
TextField(data.typ, text: $viewModel.gerät.typ).textFieldStyle(RoundedBorderTextFieldStyle())
TextField(data.pos, text: $viewModel.gerät.pos).textFieldStyle(RoundedBorderTextFieldStyle())
Text("")
TextField(data.ida, text: $viewModel.gerät.ida).textFieldStyle(RoundedBorderTextFieldStyle())
TextField(data.lg, text: $viewModel.gerät.lg).textFieldStyle(RoundedBorderTextFieldStyle())
TextField(data.la, text: $viewModel.gerät.la).textFieldStyle(RoundedBorderTextFieldStyle())
TextField(data.ga, text: $viewModel.gerät.ga).textFieldStyle(RoundedBorderTextFieldStyle())
}
Group {
Text("Adresse")
.font(.title)
TextField(data.str, text: $viewModel.gerät.str).textFieldStyle(RoundedBorderTextFieldStyle())
TextField(data.nr, text: $viewModel.gerät.nr).textFieldStyle(RoundedBorderTextFieldStyle())
TextField(data.plz, text: $viewModel.gerät.plz).textFieldStyle(RoundedBorderTextFieldStyle())
TextField(data.ort, text: $viewModel.gerät.ort).textFieldStyle(RoundedBorderTextFieldStyle())
}
Group {
Text("Kontakt")
.font(.title)
TextField(data.vp, text: $viewModel.gerät.vp).textFieldStyle(RoundedBorderTextFieldStyle())
TextField(data.tel, text: $viewModel.gerät.tel).textFieldStyle(RoundedBorderTextFieldStyle())
}
Group {
Text("Zusätzliche Informationen")
.font(.title)
TextField(data.zusatz, text: $viewModel.gerät.zusatz).textFieldStyle(RoundedBorderTextFieldStyle())
}
}.padding()
.navigationBarTitle("Gerät hinzufügen", displayMode: .inline)
.navigationBarItems(leading: Button(action: { self.handleCancelTapped() }, label: {
Text("Abbrechen")
}),
trailing: Button(action: { self.handleDoneTapped() }, label: {
Text("Speichern")
})
// .disabled(!viewModel.modified)
)
}
}
}
func handleCancelTapped() {
dismiss()
}
func handleDoneTapped() {
viewModel.save()
dismiss()
}
func dismiss() {
presentationMode.wrappedValue.dismiss()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentViewVier()
}
}
Модель представления
import Foundation
import Firebase
import Combine
class GerätEditieren: ObservableObject {
@Published var gerät: Gerät = Gerät(sn: "", objekt: "", str: "", nr: "", ort: "", vp: "", tel: "", pos: "", typ: "", ida: "", lg: "", la: "", ga: "", zusatz: "", plz: "")
private var db = Firestore.firestore()
enum Mode {
case new
case edit
}
var mode: Mode = .edit
/*
private func addGerät(_ gerät: Gerät) {
do{
let _ = try db.collection("Geräte").addDocument(from: gerät)
}
catch {
print(error)
}
}
*/
private func updateGerät(_ gerät: Gerät) {
if let ID = gerät.id {
do {
try db.collection("Geräte").document(ID).setData(from: gerät)
}
catch {
print(error)
}
}
}
private func updateOrAddGerät() { // (1)
if let _ = gerät.id {
self.updateGerät(self.gerät) // (2)
}
else {
print ("error") // (3)
}
}
func save() {
func updateGerät(_ gerät: Gerät) {
if let ID = gerät.id {
do {
try db.collection("Geräte").document(ID).setData(from: gerät, merge: true)
}
catch {
print(error)
}
}
}
updateOrAddGerät()
}
}
Другая модель (своего рода)
import Foundation
import FirebaseFirestoreSwift
struct Gerät: Identifiable, Codable {
var id: String? = UUID().uuidString
var sn: String
var objekt: String
var str: String
var nr: String
var ort: String
var vp: String
var tel: String
var pos: String
var typ: String
var ida: String
var lg: String
var la: String
var ga: String
var zusatz: String
var plz: String
enum CodingKeys: String, CodingKey {
case sn = "Seriennummer"
case objekt = "Objekt"
case str = "Strasse"
case nr = "Hausnummer"
case ort = "Ort"
case vp = "Verantwortlich"
case tel = "Telefonnummer"
case pos = "Position"
case typ = "Gerätetyp"
case ida = "Installation"
case lg = "LeasingOderGekauft"
case la = "LeasingAblaufdatum"
case ga = "GarantieAblaufdatum"
case zusatz = "Zusätzlich"
case plz = "Postleitzahl"
}
}
Комментарии:
1. Чтобы лучше понять, как настроен ваш проект, можете ли вы предоставить скриншот вашего дерева данных?
2. Ознакомьтесь с этой статьей, чтобы получить обзор того, как спроектировать ваше приложение и обновить данные в облачном Firestore из приложения SwiftUI: peterfriese.dev/swiftui-firebase-update-data
3. Здравствуйте, спасибо за ответы. Я уже смог решить свою проблему. Большая часть кода, который я использовал, взята из руководств Питера (которые просто великолепны). Проблема заключалась в том, что я использовал метод «setData ()». Либо я был слишком глуп, либо этот метод больше не работает. Вместо этого я использовал метод «updateData ()», и он работает нормально.