可以用Coredata -Swiftui保存我的对象

发布于 2025-01-24 22:37:42 字数 7964 浏览 1 评论 0原文

我有一个应用程序,应该让我手动与朋友一起计算游戏的积分。现在,出于培训原因,我也想将该游戏保存到Coredata,我不知道如何轻松调试代码。

在我的coredata文件中,我有sterain类,是乘数>乘数>的子类,这是我的类game> game

game game /code> - > MultiplayGermem - > 站立

现在,现在对我的数据模型:

我的steragy类是空的,因此它没有属性 - 但是它可以帮助我将其称为站立

所以我的乘数>类应该具有游戏的名称和players的数组

这是我的game类,以便游戏具有ID,数据和一个INT,它说了多少个回合

这是player class- PlayerColor用变压器存储一个颜色实例

因此,现在可以使用我的代码:

首先,我的视图创建站立

struct CreateStandingView: View {
    
    //Managed Object Context to store data
    @Environment(\.managedObjectContext) private var moc
    
    //Create Instance of my Standing as a MultiplayerGame
    @State private var standingGame : MultiplayerGame = Standing()
    
    //Variables for my Standing instance
    @State private var gameName : String = ""
    
    //Variables for Player
    @State private var newPlayerName : String = ""
    @State private var newPlayerColor : Color = Color.random

    //Empty Player Array for my game - it is filled here in the View
    @State private var newPlayers : [Player] = []
    
    //For my NavigationLink
    @State private var selectPlay: Int? = nil
    
    var body: some View {
        
            VStack{
                
                List{
                    Section(header: Text("Settings")){
                        TextField("Enter Game Name", text: $gameName)
                            .font(.title3.bold())
                    }
                    
                    //Player management
                    Section(header: Text("Players")){
                        
                        let textWidth : CGFloat = UIScreen.main.bounds.width - 120
                        let rowHeight : CGFloat = 30
                        
                        ForEach(newPlayers, id: \.self){ player in
                            
                            Text("\(player.playerName!)")
                                .bold()
                                .frame(width: textWidth, height: rowHeight, alignment: .leading)
                                .lineLimit(1)
                            
                        }
                        
                        //Delete player by swiping on the name
                        .onDelete(perform: {
                            indexSet in
                            newPlayers.remove(atOffsets: indexSet)
                        })
                        
                        HStack{
                        
                            TextField("Add Player Name", text: $newPlayerName)
                            
                            //Add button
                            Button(action: {
                                
                                //Create MOC object for player
                                let player : Player = Player(context: self.moc)
                                player.playerName = newPlayerName
                                
                                //Add Player to Array
                                newPlayers.append(
                                    player
                                )
                                
                                //Set value to default
                                newPlayerName = ""
                            }) {
                                Image(systemName: "plus.circle.fill")
                            }
                            .frame(width: 10, height: 10, alignment: .center)
                            .disabled(newPlayerName.isEmpty)
                        }
                    }
                }.listStyle(InsetGroupedListStyle())
                
                //Variable for disable the button
                let isDisabled : Bool = (gameName.isEmpty || newPlayers.isEmpty)
                
                //NavigationLink to EditView
                NavigationLink(destination: StandingEditStandingGameView(game: $standingGame), tag: 1, selection: $selectPlay){}
                
                //Button navigates to the next View and stores the data in the StandingGame - Instance
                Button(action: {
                    standingGame = Standing(context: moc)
                    standingGame.gameID = UUID()
                    standingGame.date = Date.now
                    standingGame.players = NSOrderedSet(array: newPlayers)
                    standingGame.name = gameName
                    standingGame.gameRounds = 0
                    
                    //Variable for Navigation Link
                    self.selectPlay = 1
                }, label: {
                    Text("Continue")
                }).disabled(isDisabled)

            }.navigationBarTitle("Create Standing")
    }
}

,现在我的视图,我可以在其中计算得分并退出游戏(退出应该将对象保存到我的Coredata中,但它总是打印出“无法保存无法保存”),

struct StandingEditStandingGameView: View {
    
    //Managed Object Context Variables
    @Environment(\.managedObjectContext) var moc
    
    //Our Binding for the Standing game from above
    @Binding var game : MultiplayerGame
    
    //Variable to add/substract the Points
    @State private var addingPoints : Bool = true
    @State private var invokeFunction : Bool = false
    
    //Array of my Players
    private var players : [Player] {
        return game.players?.array as! [Player]
    }
    
    //Variable for my NavigationLink
    @State private var quitGame: Int? = nil
    
    var body: some View {
  
            VStack{
                
                List{
                    ForEach(players, id: \.self){ player in
                        //Here is the Logic for each View - but Standing game isn't mutated here
                        StandingNameDetailView(invokeFunction: $invokeFunction, addingPoints: addingPoints, player: player)
                    }
                }
                
                Button(action: {
                    invokeFunction.toggle()
                    game.gameRounds += 1
                }, label: {
                    Text("Calculate")
                })
                
            }
            .navigationTitle(game.name ?? "Scores")
            .navigationBarBackButtonHidden(true)
            .toolbar{
                ToolbarItem(placement: .navigationBarTrailing){
                    Button("Quit Game"){
                        do{
                            //Here I try to save my data - but it always prints the "catch" method
                            try moc.save()
                            print("Standing Game was saved")
                        } catch {
                            print("Standing Game couldn't be saved")
                        }
                        
                        //Variable for NavigationLink
                        quitGame = 1
                    }
                }
            }
            
            //NavigationLink for quitting the game
            NavigationLink(destination: StartView(), tag: 1, selection: $quitGame){}
    }
}

因此谢谢您阅读此问题 - 希望我能为我的未来项目获得一些帮助并学习...谢谢!

I have an application which should let me calculate standings of a game with my friends manually. Now I also want to save that Game to CoreData for training reasons and I don't know how I could debug my code easily.

In my CoreData File I have Standing Class which is a SubClass of MultiplayerGame and that is a SubClass of my Class Game:

Game -> MultiplayerGame -> Standing

So now to my Data Model:

My Standing Class is empty so it has no attributes - but it helps me to name it as a Standing
Standing Class

So my MultiplayerGame Class should have a name of the game and an Array of the Players
Multiplayer Class

This is my Game Class so that the game have an ID, a Data and an Int which says how much rounds were played
Game Class

This is the Player Class - playerColor stores a Color instance with a Transformer
Player Class

So now to my Code:

At first my View where I create my Standing

struct CreateStandingView: View {
    
    //Managed Object Context to store data
    @Environment(\.managedObjectContext) private var moc
    
    //Create Instance of my Standing as a MultiplayerGame
    @State private var standingGame : MultiplayerGame = Standing()
    
    //Variables for my Standing instance
    @State private var gameName : String = ""
    
    //Variables for Player
    @State private var newPlayerName : String = ""
    @State private var newPlayerColor : Color = Color.random

    //Empty Player Array for my game - it is filled here in the View
    @State private var newPlayers : [Player] = []
    
    //For my NavigationLink
    @State private var selectPlay: Int? = nil
    
    var body: some View {
        
            VStack{
                
                List{
                    Section(header: Text("Settings")){
                        TextField("Enter Game Name", text: $gameName)
                            .font(.title3.bold())
                    }
                    
                    //Player management
                    Section(header: Text("Players")){
                        
                        let textWidth : CGFloat = UIScreen.main.bounds.width - 120
                        let rowHeight : CGFloat = 30
                        
                        ForEach(newPlayers, id: \.self){ player in
                            
                            Text("\(player.playerName!)")
                                .bold()
                                .frame(width: textWidth, height: rowHeight, alignment: .leading)
                                .lineLimit(1)
                            
                        }
                        
                        //Delete player by swiping on the name
                        .onDelete(perform: {
                            indexSet in
                            newPlayers.remove(atOffsets: indexSet)
                        })
                        
                        HStack{
                        
                            TextField("Add Player Name", text: $newPlayerName)
                            
                            //Add button
                            Button(action: {
                                
                                //Create MOC object for player
                                let player : Player = Player(context: self.moc)
                                player.playerName = newPlayerName
                                
                                //Add Player to Array
                                newPlayers.append(
                                    player
                                )
                                
                                //Set value to default
                                newPlayerName = ""
                            }) {
                                Image(systemName: "plus.circle.fill")
                            }
                            .frame(width: 10, height: 10, alignment: .center)
                            .disabled(newPlayerName.isEmpty)
                        }
                    }
                }.listStyle(InsetGroupedListStyle())
                
                //Variable for disable the button
                let isDisabled : Bool = (gameName.isEmpty || newPlayers.isEmpty)
                
                //NavigationLink to EditView
                NavigationLink(destination: StandingEditStandingGameView(game: $standingGame), tag: 1, selection: $selectPlay){}
                
                //Button navigates to the next View and stores the data in the StandingGame - Instance
                Button(action: {
                    standingGame = Standing(context: moc)
                    standingGame.gameID = UUID()
                    standingGame.date = Date.now
                    standingGame.players = NSOrderedSet(array: newPlayers)
                    standingGame.name = gameName
                    standingGame.gameRounds = 0
                    
                    //Variable for Navigation Link
                    self.selectPlay = 1
                }, label: {
                    Text("Continue")
                }).disabled(isDisabled)

            }.navigationBarTitle("Create Standing")
    }
}

And now my View, where I can calculate the Scores and Quit the Game (quitting should save the object to my CoreData, but it always prints "Standing couldn't be saved")

struct StandingEditStandingGameView: View {
    
    //Managed Object Context Variables
    @Environment(\.managedObjectContext) var moc
    
    //Our Binding for the Standing game from above
    @Binding var game : MultiplayerGame
    
    //Variable to add/substract the Points
    @State private var addingPoints : Bool = true
    @State private var invokeFunction : Bool = false
    
    //Array of my Players
    private var players : [Player] {
        return game.players?.array as! [Player]
    }
    
    //Variable for my NavigationLink
    @State private var quitGame: Int? = nil
    
    var body: some View {
  
            VStack{
                
                List{
                    ForEach(players, id: \.self){ player in
                        //Here is the Logic for each View - but Standing game isn't mutated here
                        StandingNameDetailView(invokeFunction: $invokeFunction, addingPoints: addingPoints, player: player)
                    }
                }
                
                Button(action: {
                    invokeFunction.toggle()
                    game.gameRounds += 1
                }, label: {
                    Text("Calculate")
                })
                
            }
            .navigationTitle(game.name ?? "Scores")
            .navigationBarBackButtonHidden(true)
            .toolbar{
                ToolbarItem(placement: .navigationBarTrailing){
                    Button("Quit Game"){
                        do{
                            //Here I try to save my data - but it always prints the "catch" method
                            try moc.save()
                            print("Standing Game was saved")
                        } catch {
                            print("Standing Game couldn't be saved")
                        }
                        
                        //Variable for NavigationLink
                        quitGame = 1
                    }
                }
            }
            
            //NavigationLink for quitting the game
            NavigationLink(destination: StartView(), tag: 1, selection: $quitGame){}
    }
}

So thank you for reading this problem - I hope I can get some help and learn for my future projects... Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文