Как обрабатывать SwiftUI и основные данные в делегате сцены? - PullRequest
0 голосов
/ 12 июля 2020

Я новичок в SwiftUI и Core Data. У меня есть объект ParkingSpace с атрибутами «тип» и «текст», оба имеют тип String. После выполнения нескольких руководств у меня есть представление для отображения парковочных мест в списке. Но в моем приложении есть LoginView, который я хочу отображать сначала, а после входа в систему должен появиться ParkingSpacesList. Как я могу справиться с этим в делегате сцены?

В моем SceneDelegate у меня есть следующий код:

 func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        //let contentView = LoginView()
        let context = persistentContainer.viewContext
        let contentView = ParkingSpaceList().environment(\.managedObjectContext, context)}

lazy var persistentContainer: NSPersistentContainer = {
      let container = NSPersistentContainer(name: "CampstDa")
      container.loadPersistentStores { _, error in
        if let error = error as NSError? {
          fatalError("Unresolved error \(error), \(error.userInfo)")
        }
      }
      return container
    }()

    func saveContext() {
      let context = persistentContainer.viewContext
      if context.hasChanges {
        do {
          try context.save()
        } catch {
          let nserror = error as NSError
          fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
      }
    }
    
    func sceneDidEnterBackground(_ scene: UIScene) {
      saveContext()
    }

Мое представление выглядит так:

`struct ParkingSpaceList: View {
    @FetchRequest(
      entity: ParkingSpace.entity(),
      sortDescriptors: [
        NSSortDescriptor(keyPath: \ParkingSpace.type, ascending: true)
      ]
    ) var parkingspaces: FetchedResults<ParkingSpace>


    @Environment(\.managedObjectContext) var managedObjectContext

    
    func saveContext() {
      do {
        try managedObjectContext.save()
      } catch {
        print("Error saving managed object context: \(error)")
      }
    }
    
    
    func addParkingSpace(type: String, text: String) {

      let newParkingSpace = ParkingSpace(context: managedObjectContext)

      newParkingSpace.type = type
      newParkingSpace.text = text

      saveContext()
    }
    

    func deleteParkingSpace(at offsets: IndexSet) {
      offsets.forEach { index in
        let parkingspace = self.parkingspaces[index]
        self.managedObjectContext.delete(parkingspace)
      }
      saveContext()
    }
    

    @State var isPresented = false

    var body: some View {
    NavigationView {
      List {
        ForEach(parkingspaces, id: \.text) {
          ParkingSpaceRow(parkingspace: $0)
        }
        .onDelete(perform: deleteParkingSpace)
      }
      .sheet(isPresented: $isPresented) {
        AddFavorite { type, text in
            self.addParkingSpace(type: type, text: text)
            self.isPresented = false
        }
      }
      .navigationBarTitle(Text("Favorites"))
      .navigationBarItems(trailing:
        Button(action: { self.isPresented.toggle() }) {
          Image(systemName: "plus")
        }
      )
    }
  }
}


struct ParkingSpaceRow: View {
  let parkingspace: ParkingSpace
  static let releaseFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateStyle = .long
    return formatter
  }()

  var body: some View {
    VStack(alignment: .leading) {
      parkingspace.type.map(Text.init)
        .font(.title)
      HStack {
        parkingspace.text.map(Text.init)
          .font(.caption)
      }
    }
  }
}`

1 Ответ

0 голосов
/ 13 июля 2020

Создайте представление, которое может переключаться между представлением входа в систему или представлением парковки в зависимости от некоторого состояния. Например:

class LoginService: ObservableObject {
    @Published var userLoggedIn = false
    
    func login() {
        // login user..
        userLoggedIn = true
    }
}

struct RootView: View {
    @EnvironmentObject var loginService: LoginService

    var body: some View {
        if loginService.userLoggedIn {
            LoginView()
        } else {
            ParkingView()
        }
   }
}

Теперь вам нужно внедрить объект LoginService в среду:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        let context = persistentContainer.viewContext
        let contentView = ParkingSpaceList().environment(\.managedObjectContext, context).environmentObject(LoginService())}

...