在核心数据更改处理期间捕获到异常(试图用userInfo插入nil)

时间:2018-12-10 21:30:31

标签: ios json swift xcode core-data

我在应用程序中执行两个核心数据任务时遇到问题。本质上,我从URL连接中引入数据,然后将该信息保存到Core Data中。不过,在执行此操作之前,请确保已拥有新数据,然后删除核心数据中的当前内容(实质上是覆盖现有数据)。

我尝试使用异步和同步块,甚至尝试使用wait()函数来减慢速度,还有很多其他事情,但是我仍然遇到并发错误。谁能帮忙吗?非常感谢你!

这是我的视图已加载:

override func viewDidLoad() {
    super.viewDidLoad()

    //Setup app delegate to pass to sale function
    let thisAppDelegate = UIApplication.shared.delegate as! AppDelegate
    //update sale information if possible
    self.getJSONFromURLAndSaveToCoreData(appDelegate: thisAppDelegate)

}

这是实际功能:

//this function is fetching the JSON from URL
func getJSONFromURLAndSaveToCoreData(appDelegate : AppDelegate){

    //create a NSURL
    let url = NSURL(string: urlString)

    //fetch the data from the url
    URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in

        //If the retrieved information is a JSON Object, and can be treated as an NSArray...
        if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSArray {

            //iterate through the object. For each item...
            for item in jsonObj! {

                //setup array variables
                var rangeArray: [RangeObject] = []
                var contractArray: [ContractObject] = []

                //Parse all items
                if let itemObject = item as? NSObject {
                    //Identify ranges
                    let newRanges = itemObject.value(forKey: "ranges") as! NSArray
                    //for each item in ranges...
                    for item in newRanges {
                        //Create range objects
                        if let itemObject = item as? NSObject{
                            let start = Int(itemObject.value(forKey: "start") as! String)!
                            let end = Int(itemObject.value(forKey: "end") as! String)!
                            let thisRange = RangeObject(startValue: start, endValue: end)
                            //add to range array
                            rangeArray.append(thisRange)
                        }
                    }
                    //Identify contracts
                    let newContracts = itemObject.value(forKey: "contract") as! NSArray
                    //for each item in contracts...
                    for item in newContracts {
                        //Create contract objects
                        if let itemObject = item as? NSObject{
                            let newUomName = itemObject.value(forKey: "uom_name") as! String
                            let newHaulerID = Int(itemObject.value(forKey: "hauler_id") as! String)!
                            let newExpirationDate = itemObject.value(forKey: "expiration_date") as! String
                            let newSaleProductName = itemObject.value(forKey: "sale_product_name") as! String
                            let newHaulerName = itemObject.value(forKey: "hauler_name") as! String
                            let newDestinationName = itemObject.value(forKey: "destination_name") as! String
                            let newSaleProductID = Int(itemObject.value(forKey: "sale_product_id") as! String)!
                            let thisContract = ContractObject(uomName: newUomName, haulerID: newHaulerID, expirationDate: newExpirationDate, saleProductName: newSaleProductName, haulerName: newHaulerName, destinationName: newDestinationName, saleProductID: newSaleProductID)
                            //add to contract array
                            contractArray.append(thisContract)
                        }
                    }
                    //Set all other values to variables
                    let newTimberSaleName = itemObject.value(forKey: "timber_sale_name") as! String
                    let newTimberSaleID = Int(itemObject.value(forKey: "timber_sale_id") as! String)!
                    let newOperatorName = itemObject.value(forKey: "lb_operator_name") as! String
                    let newOperatorID = itemObject.value(forKey: "lb_operator_id") as! String
                    let newGeneralID = itemObject.value(forKey: "id") as! Int

                    //Use all of the variables and arrays to create a new Sale object
                    let newSaleObject = SaleObject(ranges: rangeArray, timberSaleName: newTimberSaleName, lbOperatorName: newOperatorName, lbOperatorID: newOperatorID, timberSaleID: newTimberSaleID, ID: newGeneralID, contracts: contractArray)

                    //Add the object to saleArray
                    self.saleArray.append(newSaleObject)

                }

            }

        }

        //TODO: This is where completion stuff goes

        //If data was pulled from the internet, delete current data.
        if self.saleArray.count != 0 {
            // Setup ManagedObjectContext
            let thisManagedContext =
                appDelegate.persistentContainer.viewContext

            // Setup fetch request with information
            let fetchRequest =
                NSFetchRequest<NSManagedObject>(entityName: "Sale")

            //Attempt to fetch the information
            do {
                let sales = try thisManagedContext.fetch(fetchRequest)

                //for each object in sales...
                for object in sales {
                    //delete the object
                    thisManagedContext.delete(object)
                }
                print("Deleted!")
            } catch let error {
                print("Delete all data error :", error)
            }

        }//End Delete

        //Save to Core Data
        //Create link to ManagedObject
        var sales: [NSManagedObject] = []

        // Setup ManagedObjectContext
        let currentManagedContext = appDelegate.persistentContainer.viewContext

        //For each sale...
        for item in self.saleArray {

            // Identify the sale entity information
            let saleEntity =
                NSEntityDescription.entity(forEntityName: "Sale",
                                           in: currentManagedContext)!

            //setup a managed object to manage that entity
            let sale = NSManagedObject(entity: saleEntity,
                                       insertInto: currentManagedContext)

            // Set all the values of the entity
            sale.setValue(item.timberSaleName, forKeyPath: "timberSaleName")
            sale.setValue(item.timberSaleID, forKeyPath: "timberSaleID")
            sale.setValue(item.lbOperatorName, forKeyPath: "lbOperatorName")
            sale.setValue(item.lbOperatorID, forKeyPath: "lbOperatorID")
            sale.setValue(item.ID, forKeyPath: "id")
            sale.setValue(item.ranges, forKeyPath: "ranges")
            sale.setValue(item.contracts, forKeyPath: "contracts")

            // Try to save the sale
            do {
                try currentManagedContext.save()
                sales.append(sale)
            } catch let error as NSError {
                print("Could not save. \(error), \(error.userInfo)")
            }
        }

    }).resume()

}

这是错误:

Serious application error.  Exception was caught during Core Data 
change processing.  This is usually a bug within an observer of 
NSManagedObjectContextObjectsDidChangeNotification.  -[__NSCFSet 
addObject:]: attempt to insert nil with userInfo (null)
CoreData: error: Serious application error.  Exception was caught 
during Core Data change processing.  This is usually a bug within an 
observer of NSManagedObjectContextObjectsDidChangeNotification.  - 
[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)
2018-12-10 15:16:45.076035-0600 ACTIVITY[4608:3386565] *** 
Terminating app due to uncaught exception 
'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: 
attempt to insert nil'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010ccc91bb 
__exceptionPreprocess + 331
    1   libobjc.A.dylib                     0x000000010b83f735 
objc_exception_throw + 48
    2   CoreFoundation                      0x000000010ccc9015 + . 
[NSException raise:format:] + 197
    3   CoreFoundation                      0x000000010cca48da - 
[__NSCFSet addObject:] + 202
    4   CoreData                            0x000000010c63bb2b - 
[NSManagedObjectContext(_NSInternalChangeProcessing) 
_processPendingUpdates:] + 379
    5   CoreData                            0x000000010c63632b - 
[NSManagedObjectContext(_NSInternalChangeProcessing) 
_processRecentChanges:] + 1163
    6   CoreData                            0x000000010c63a0a0 - 
[NSManagedObjectContext save:] + 416
    7   Load BOSS                           0x000000010ae5552b 

$S9ACTIVITY18MainViewControllerC31getJSONFromURLAndSaveToCoreData 
11appDelegateyAA03AppN0C_tFy10Foundation0L0VSg_So13NSURL . 
ResponseCSgs5Error_pSgtcfU_ + 19531
    8   ACTIVITY                           0x000000010ae55dfa 
$S9ACTIVITY18MainViewControllerC31getJSONFromURLAndSaveTo 
CoreData11appDelegateyAA03AppN0C_tFy10Foundation0L0VSg_ 
So13NSURLResponseCSgs5Error_pSgtcfU_TA + 26
    9   ACTIVITY                           0x000000010ae55f60 
$S10Foundation4DataVSgSo13NSURLResponseCSgs5Error 
_pSgIegggg_So6NSDataCSgAGSo7NSErrorCSgIeyByyy_TR + 336
    10  CFNetwork                           0x000000010e29f940 __75- 
[__NSURLSessionLocal 
taskForClass:request:uploadFile:bodyData:completion:]_block_invoke + 
19
    11  CFNetwork                           0x000000010e2b5b0c __49- 
[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 172
    12  Foundation                          0x000000010b2acf9e 
__NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
    13  Foundation                          0x000000010b2acea5 - 
[NSBlockOperation main] + 68
    14  Foundation                          0x000000010b2a9c14 - 
[__NSOperationInternal _start:] + 689
    15  Foundation                          0x000000010b2afc4b 
__NSOQSchedule_f + 227
    16  libdispatch.dylib                   0x000000010f274595 
_dispatch_call_block_and_release + 12
    17  libdispatch.dylib                   0x000000010f275602 
_dispatch_client_callout + 8
    18  libdispatch.dylib                   0x000000010f27854d 
_dispatch_continuation_pop + 565
    19  libdispatch.dylib                   0x000000010f277927 
_dispatch_async_redirect_invoke + 859
    20  libdispatch.dylib                   0x000000010f28600a 
_dispatch_root_queue_drain + 351
    21  libdispatch.dylib                   0x000000010f2869af 
_dispatch_worker_thread2 + 130
    22  libsystem_pthread.dylib             0x000000010f66470e 
_pthread_wqthread + 619
    23  libsystem_pthread.dylib             0x000000010f664435 
start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type 
NSException

这是我的核心数据模型:

SaleEntity

顺便说一句,该错误不是永久性的。看来是随机发生的。

0 个答案:

没有答案