我是 CoreData 的新手,我正在尝试制作游戏。我有几个问题,希望你们能帮我一些指导:
- GameKit 是否已经集成了某种 CoreData?如果 GameKit 中已经有替代它的东西,我不确定我是否对这个 CoreData 东西想得太多了。
. . .
无论如何,假设上述问题的答案是“不。GameKit 没有任何东西可以保存你的游戏”。我将继续使用当前的“保存游戏”代码,如下所示:
func saveCurrentMatch()
{
/* CORE DATA STUFF:
FIRST NEED TO VERIFY IF THIS GAME HAS BEEN PREVIOUSLY SAVED, IF SO THEN UPDATE, ELSE JUST SAVE
Entity: MatchData
Attributes: scoreArray (String), playerArray (String), myScore (Int), matchID (Int), isWaiting (Bool), isRealTime (Bool), gameLog (String)
*/
let context = myAppDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "MatchData")
request.returnsObjectsAsFaults = false
do
{
let gamesInProgress = try context.fetch(request)
print (gamesInProgress.count)
if gamesInProgress.count > 0 //HERE CHANGE THIS TO LOOK FOR THE MATCH ID OF THIS GAME!!
{
gameExistsinCD = true
}
else
{
gameExistsinCD = false
}
}
catch
{
print ("Error Reading Data: \(error.localizedDescription)")
}
if gameExistsinCD
{
//CODE TO UPDATE MATCH INSTEAD OF SAVING NEW ONE
}
else
{
// CODE TO SAVE A NEW MATCH FOR THE FIRST TIME
let matchData = NSEntityDescription.insertNewObject(forEntityName: "MatchData", into: context)
matchData.setValue(isRealTime, forKey: "isRealTime")
matchData.setValue(currentScore?[0], forKey: "myScore")
matchData.setValue(currentScore?.map{String($0)}.joined(separator: "\t"), forKey: "scoreArray") // IS THIS CODE CORRECT? I'M TRYING TO SAVE AN ARRAY OF INTS INTO A SINGLE STRING
matchData.setValue(currentPlayers?.joined(separator: "\t"), forKey: "playerArray")
matchData.setValue(true, forKey: "isWaiting") //will change later to update accordingly.
matchData.setValue(matchID, forKey: "matchID")
matchData.setValue(gameLog, forKey: "gameLog")
do
{
try context.save()
print ("CoreData: Game Saved!")
}
catch
{
print ("Error Saving Data: \(error.localizedDescription)")
}
}
}
我主要关心的是获取请求,如果这个匹配项已经保存,我该如何检查所有的核心数据?如果是这样,更新实体而不是插入新实体的代码是什么?
感谢任何指导,谢谢!
最佳答案
不要让 Core Data 吓到您。它可以是保存本地数据的好方法,尽管有一些评论,但如果做得好,速度并不慢。事实上,Core Data 可以非常快。
通过以更正常的方式使用 Object 类而不是使用 setValue 调用,您可以大大简化代码。您的创建代码可以更改为:
// CODE TO SAVE A NEW MATCH FOR THE FIRST TIME
if let matchData = NSEntityDescription.insertNewObject(forEntityName: "MatchData", into: context) as? MatchData {
matchData.isRealTime = isRealTime
matchData.myScore = currentScore?[0]
matchData.scoreArray = currentScore?.map{String($0)}.joined(separator: "\t") // IS THIS CODE CORRECT? I'M TRYING TO SAVE AN ARRAY OF INTS INTO A SINGLE STRING
// You can certainly save it this way and code it in and out. A better alternative is to have a child relationship to another managed object class that has the scores.
matchData.playerArray = currentPlayers?.joined(separator: "\t")
matchData.isWaiting = true
matchData.matchID = matchID
matchData.gameLog = gameLog
}
这是设置对象属性的一种更具可读性和常规的方式。每次更改核心数据托管对象的属性时,下次保存上下文时都会保存该属性。
就查找与 ID 匹配的当前记录而言,我喜欢将类似的类添加到我的托管对象类本身:
class func findByID(_ matchID: String) -> MatchData? {
let myAppDelegate = UIApplication.shared.delegate as! AppDelegate
let context = myAppDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "MatchData")
let idPredicate = NSPredicate(format: "matchID = \(matchID)", argumentArray: nil)
request.predicate = idPredicate
var result: [AnyObject]?
var matchData: MatchData? = nil
do {
result = try context.fetch(request)
} catch let error as NSError {
NSLog("Error getting match: \(error)")
result = nil
}
if result != nil {
for resultItem : AnyObject in result! {
matchData = resultItem as? MatchData
}
}
return matchData
}
然后在任何需要通过 ID 匹配数据的地方都可以调用类函数:
if let matchData = MatchData.findByID("SomeMatchID") {
// Match exists
}
关于ios - 更新 CoreData 实体或保存一个新实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48149602/