gpt4 book ai didi

swift - 覆盖核心数据(如果存在)

转载 作者:行者123 更新时间:2023-11-28 15:07:16 31 4
gpt4 key购买 nike

我一直在开发一些 Core Data 应用程序,并且只是为了练习而开发了一些其他应用程序。

我从网络上的每个人那里得到了大量帮助,在此先感谢您。

我的这个应用实际上什么都不做,它只是一个Core Data + CollectionView 实践。

无论如何,您应该添加一个新的 DataThing 并将其保存到核心数据中,然后将其显示在 CollectionView 中。

如果您单击该 Collection View ,您会加载 View Controller (用于添加新 View 的 View Controller ),但它会预先加载数据(或者这就是意图)。

最后,当您在实际添加之前“添加”时,应用程序会检查具有该标题的条目是否已存在,如果存在则应覆盖它,否则应保存一个新条目。

这是显示/加载 UICollectionView 的代码(请注意“did select”函数在崩溃后被注释掉了):

class ViewController: UIViewController {
@IBOutlet weak var addEntryBtn: UIButton!
@IBOutlet weak var xtraBtn: UIButton!
@IBOutlet weak var collectionView: UICollectionView!
let myAppDelegate = UIApplication.shared.delegate as! AppDelegate
var thingsLoaded: [DataThing]?
@IBAction func addEntryTapped(_ sender: Any) {
performSegue(withIdentifier: "addEntrySegue", sender: nil)

}

@IBAction func xtraTapped(_ sender: Any) {
//might be used to load?
viewDidLoad()
collectionView.reloadData()
}

override func viewDidLoad() {
super.viewDidLoad()

let context = myAppDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "DataThing")
request.returnsObjectsAsFaults = false
do
{
thingsLoaded = try context.fetch(request) as? [DataThing]
print ("Data Loaded")
}
catch
{
print ("Error Reading Data: \(error.localizedDescription)")
}

}
}


extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate {

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return thingsLoaded?.count ?? 0
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let customCell = collectionView.dequeueReusableCell(withReuseIdentifier: "customCell", for: indexPath) as! CustomCVCell

if thingsLoaded != nil
{
customCell.titleLabel.text = thingsLoaded![indexPath.row].title
customCell.numberLabel.text = thingsLoaded![indexPath.row].number
customCell.noteLabel.text = thingsLoaded![indexPath.row].note

if thingsLoaded![indexPath.row].active {
customCell.statusView.backgroundColor = UIColor.green
} else {
customCell.statusView.backgroundColor = UIColor.red
}

}

return customCell
}



func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// THIS WHOLE CHUNK OF CODE CREATES FATAL ERROR, FOUND NIL WHILE UNWRAPPING.

/*
let loadEntryVC = self.storyboard?.instantiateViewController(withIdentifier: "loadEntry") as! EntryVC
loadEntryVC.isActive.isOn = thingsLoaded![indexPath.row].active
loadEntryVC.titleText.text = thingsLoaded![indexPath.row].title
loadEntryVC.numberText.text = thingsLoaded![indexPath.row].number
loadEntryVC.noteText.text = thingsLoaded![indexPath.row].note
loadEntryVC.titleText.isEnabled = false

self.present(loadEntryVC, animated: true, completion: nil)
*/
}

}

这是“添加条目” View Controller 的代码。请注意,我注释掉了调用自定义获取函数导致游戏崩溃的部分:

class EntryVC: UIViewController {
var delegate: DeezNutsDelegate?
let myAppDelegate = UIApplication.shared.delegate as! AppDelegate
@IBOutlet weak var titleText: UITextField!
@IBOutlet weak var numberText: UITextField!
@IBOutlet weak var noteText: UITextField!
@IBOutlet weak var isActive: UISwitch!

@IBOutlet weak var addBtn: UIButton!

@IBAction func addTapped(_ sender: Any) {

let context = myAppDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "DataThing")
request.returnsObjectsAsFaults = false


// if let checkExist = DataThing.findByTitle(titleText.text!)
// {
// print ("HELLO WORLD!") NOTE JUST CALLING THE FUNCTION IN THIS SIMPLE MANNER MAKES THE APP CRASH.
// }

//check that this doesnt exist
// if let existingData = DataThing.findByTitle(titleText.text ?? "")
// {
// print ("DATA FOUND")
// //data already exists
// existingData.active = isActive.isOn
// existingData.number = numberText.text ?? "NA"
// existingData.note = noteText.text ?? "No Entry"
//
// print ("DATA OVEWRITTEN")
// } else {
print ("DATA DOES NOT EXISt, ATTEMPING NEW ONE!")
if let dataThing = NSEntityDescription.insertNewObject(forEntityName: "DataThing", into: context) as? DataThing {
dataThing.active = isActive.isOn
dataThing.title = titleText.text ?? "No Entry"
dataThing.number = numberText.text ?? "N.A."
dataThing.note = noteText.text ?? "No Entry"

print ("DATA STORED!")
}
//}

do
{
try context.save()
print ("CoreData: Game Saved!")
}
catch
{
print ("Error Saving Data: \(error.localizedDescription)")
}

self.dismiss(animated: true, completion: nil)

}



override func viewDidLoad() {
super.viewDidLoad()

// Do any additional setup after loading the view.
}
}

最后,这是获取 DataThings 的自定义函数:

class func findByTitle(_ title: String) -> DataThing? {
let myAppDelegate = UIApplication.shared.delegate as! AppDelegate
let context = myAppDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "DataThing")
let idPredicate = NSPredicate(format: "title = \(title)", argumentArray: nil)
request.predicate = idPredicate
var result: [AnyObject]?
var dataThingFound: DataThing? = nil
do {
result = try context.fetch(request)
} catch let error as NSError {
print("Error getting data: \(error)")
result = nil
}
if result != nil {
for resultItem : AnyObject in result! {
dataThingFound = resultItem as? DataThing
print ("DATA FOUND, RETURNING IT!")
}
}
return dataThingFound
}

编辑这是“按标题获取”崩溃的崩溃代码

2018-01-16 12:42:47.189960+0800 CoreData+Collections[819:9224] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath title2 not found in entity <NSSQLEntity DataThing id=1>'
*** First throw call stack:
(
0 CoreFoundation 0x0000000110a4112b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010c7e8f41 objc_exception_throw + 48
2 CoreData 0x000000010d1b1c71 -[NSSQLGenerator newSQLStatementForRequest:ignoreInheritance:countOnly:nestingLevel:nestIsWhereScoped:requestContext:] + 1649
3 CoreData 0x000000010d1bc880 -[NSSQLiteAdapter _statementForFetchRequestContext:ignoreInheritance:countOnly:nestingLevel:] + 144
4 CoreData 0x000000010d079c12 -[NSSQLiteAdapter newSelectStatementWithFetchRequestContext:ignoreInheritance:] + 130
5 CoreData 0x000000010d1fe613 -[NSSQLFetchRequestContext _createStatement] + 67
6 CoreData 0x000000010d1fe5bc -[NSSQLFetchRequestContext fetchStatement] + 172
7 CoreData 0x000000010d1ff63b -[NSSQLFetchRequestContext executeRequestCore:] + 27
8 CoreData 0x000000010d26449c -[NSSQLStoreRequestContext executeRequestUsingConnection:] + 204
9 CoreData 0x000000010d23955b __52-[NSSQLDefaultConnectionManager handleStoreRequest:]_block_invoke + 75
10 libdispatch.dylib 0x0000000111b6333d _dispatch_client_callout + 8
11 libdispatch.dylib 0x0000000111b6a235 _dispatch_queue_barrier_sync_invoke_and_complete + 392
12 CoreData 0x000000010d239443 -[NSSQLDefaultConnectionManager handleStoreRequest:] + 339
13 CoreData 0x000000010d241294 -[NSSQLCoreDispatchManager routeStoreRequest:] + 308
14 CoreData 0x000000010d1976c5 -[NSSQLCore dispatchRequest:withRetries:] + 229
15 CoreData 0x000000010d1945fd -[NSSQLCore processFetchRequest:inContext:] + 93
16 CoreData 0x000000010d07915b -[NSSQLCore executeRequest:withContext:error:] + 571
17 CoreData 0x000000010d17a08b __65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke + 1691
18 CoreData 0x000000010d17221a -[NSPersistentStoreCoordinator _routeHeavyweightBlock:] + 378
19 CoreData 0x000000010d078ac4 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 660
20 CoreData 0x000000010d0770e4 -[NSManagedObjectContext executeFetchRequest:error:] + 564
21 libswiftCoreData.dylib 0x000000010fe72f1a _T0So22NSManagedObjectContextC8CoreDataE5fetchSayxGSo14NSFetchRequestCyxGKSo0gH6ResultRzlF + 58
22 CoreData+Collections 0x000000010beb2f81 _T020CoreData_Collections0B5ThingC11findByTitleACSgSSFZ + 1105
23 CoreData+Collections 0x000000010bebc92d _T020CoreData_Collections7EntryVCC9addTappedyypF + 1069
24 CoreData+Collections 0x000000010bebe6f8 _T020CoreData_Collections7EntryVCC9addTappedyypFTo + 72
25 UIKit 0x000000010d5d3972 -[UIApplication sendAction:to:from:forEvent:] + 83
26 UIKit 0x000000010d752c3c -[UIControl sendAction:to:forEvent:] + 67
27 UIKit 0x000000010d752f59 -[UIControl _sendActionsForEvents:withEvent:] + 450
28 UIKit 0x000000010d751e86 -[UIControl touchesEnded:withEvent:] + 618
29 UIKit 0x000000010d649807 -[UIWindow _sendTouchesForEvent:] + 2807
30 UIKit 0x000000010d64af2a -[UIWindow sendEvent:] + 4124
31 UIKit 0x000000010d5ee365 -[UIApplication sendEvent:] + 352
32 UIKit 0x000000010df3aa1d __dispatchPreprocessedEventFromEventQueue + 2809
33 UIKit 0x000000010df3d672 __handleEventQueueInternal + 5957
34 CoreFoundation 0x00000001109e4101 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
35 CoreFoundation 0x0000000110a83f71 __CFRunLoopDoSource0 + 81
36 CoreFoundation 0x00000001109c8a19 __CFRunLoopDoSources0 + 185
37 CoreFoundation 0x00000001109c7fff __CFRunLoopRun + 1279
38 CoreFoundation 0x00000001109c7889 CFRunLoopRunSpecific + 409
39 GraphicsServices 0x00000001131e59c6 GSEventRunModal + 62
40 UIKit 0x000000010d5d25d6 UIApplicationMain + 159
41 CoreData+Collections 0x000000010bebaea7 main + 55
42 libdyld.dylib 0x0000000111bdfd81 start + 1
43 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

最佳答案

获取请求永远不会返回完全未指定的 AnyObject。它至少返回 [NSFetchRequestResult],如果generic 请求更具体,则结果也更具体:这就是泛型的好处。

我建议使 findByTitle 成为一个实例方法,它会在您使用 do - catch block 时抛出 错误。该方法将请求的 title 和上下文作为参数。该方法返回:

  • 如果找到对象,则返回(非可选)对象。
  • 如果找不到该对象,请插入一个新对象并分配标题并返回。
  • 如果发生错误,则抛出错误(通过)。

    func find(byTitle title: String, in context: NSManagedObjectContext) throws -> DataThing {
    let request = NSFetchRequest<DataThing>(entityName: "DataThing")
    request.predicate = NSPredicate(format: "title == %@", title)
    let result = try context.fetch(request)
    if let dataThing = result.first {
    return dataThing
    } else {
    let dataThing = NSEntityDescription.insertNewObject(forEntityName: "DataThing", into: context) as! DataThing
    dataThing.title = title
    return dataThing
    }
    }

addTapped 中,首先检查文本字段是否为空。然后调用 find(byTitle 并分配其他值:

@IBAction func addTapped(_ sender: Any) {

let myAppDelegate = UIApplication.shared.delegate as! AppDelegate
let context = myAppDelegate.persistentContainer.viewContext
guard let title = titleText.text, !title.isEmpty else { return }
do {
let dataThing = try find(byTitle: title, in: context)
dataThing.active = isActive.isOn
dataThing.number = numberText.text ?? "NA"
dataThing.note = noteText.text ?? "No Entry"
try context.save()
print ("CoreData: Game Saved!")
} catch {
print ("Error Saving Data: \(error.localizedDescription)")
}

self.dismiss(animated: true, completion: nil)
}

关于swift - 覆盖核心数据(如果存在),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48265285/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com