0
votes

I have the below code, in both cases of having or not having the comments removed and also having unowned self changed to weak self 8 times out of 10 i have no issues getting the record id to post to core data, however, in other cases i get a run time error and it appears it is on the try.self.moContext.save() line. the error happens on different threads, and in the debug is shows abortretainunowned...

            CKContainer.defaultContainer().publicCloudDatabase.saveRecord(postRecord, completionHandler: { [unowned self] (record, error) -> Void in
               // dispatch_async(dispatch_get_main_queue()) {
                    if error != nil {
                        print("Error Saving to Cloud \(error)")
                    } else {
                    photoData.cloudKitID = record!.recordID.recordName as String
                        //Save to CoreData
                        do {
                            try self.moContext.save()
                            print("Saved Posted ReocrdID Name to CoreData \(record!.recordID.recordName)")
                            self.moContext.refreshAllObjects()
                        } catch let error {
                            //Check for Error
                            print("Error is \(error)")
                        }
                    }
               // }
            })

UPDATE

I think I found a solution, if anyone could validate if this is best practice or not would be appreciative.

Since I have to create postRecord by initializing as a CKRecord postRecord actually already has the cloud kit record name postRecord.recordID.recordName already before it is posted. So i moved my core data save to be infant of the CloudKit save operation. Essentially saving before the saverecord occurs. So far so good. This works assuming that the CkRecord Name of postRecord.recordID.recordName will always match the returned CloudKit results.recordID.recordName. Is this a right assumption?

Thanks

1
try using [weak self] and not unowned. Then you only need to add the "?" or "!" to the self with care. Obviously checking first if self is not nil.Joel
and is not good idea what you are doing. The operation could fail and then your record will exists only in your coredata.Joel
Thank you, if you put as answer will accept.TravelNVal

1 Answers

1
votes

Remember, CloudKit operation are asynchronous and there are many reason they could fail, so is not good idea to save any cache or data before you know the result (unless you mark the cache as "unsaved" or something like that, for retry purpose). What you need to do is to use [weak self] in your block/closure and then, check if self is not nil to continue. Also, all your call to self need and "?" or "!"

try self!.moContext.save()

I use a singleton for my NSOperationQueue and an observer for the operation (in case of the app go background, the observer give me more seconds in the background to finish the operation). Look for a video of the last WWDC about operations.