核心数据如果存在则覆盖

时间:2018-01-15 14:47:31

标签: swift core-data uicollectionview

我一直在开发一些Core Data应用程序,只是做了一些其他的应用程序。

我已经得到了网络上每个人的大量帮助,所以提前感谢。

我有这个应用程序没有做任何事情,但它只是Core Data + CollectionView练习。

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

如果单击该集合视图,则加载视图控制器(用于添加新视图控制器的视图控制器),但它会预先加载数据(或意图)。

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

这里显示/加载UICollectionView的代码(注意功能"确实选择"因崩溃而被注释掉):

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)
 */
    }

}

此处&#34;添加条目&#34;的代码查看控制器。注意,我注释掉了导致游戏崩溃的部分,它调用了自定义提取功能:

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
    }

修改 继承人&#39; &#34;按标题获取的崩溃代码&#34;崩溃

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

1 个答案:

答案 0 :(得分:1)

获取请求永远不会返回非常未指定的For Each P In WD.Paragraphs Temp = P.Range.Text If P.Range.Information(wdWithInTable) Then 'Other stuff done here Next P 。它至少返回For Each T In WD.Tables Rcount = T.Rows.Count Ccount = T.Columns.Count 'temp = T.Cell(R, C).Range.Text 'can get individual cell info like this Next T ,如果更多地指定了泛型请求,则会更明确地指定结果:这是泛型的好处。

我建议AnyObject使用[NSFetchRequestResult]作为错误的实例方法,因为您正在使用findByTitle块。该方法将请求的throws和上下文作为参数。该方法返回:

  • 如果找到对象,则返回(非可选)对象。
  • 如果找不到该对象,请插入一个新对象,然后返回该标题。
  • 如果发生错误,则抛出错误(传递)。

    do - catch

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