drewmccormack / ensembles

A synchronization framework for Core Data.
MIT License
1.63k stars 132 forks source link

Ensembles; Handling errors #267

Open MickStupp opened 6 years ago

MickStupp commented 6 years ago

I'd very much like to handle the error 'CDEErrorCode.cloudIdentityChange' as a run-time alert, but cannot get any line to work. Logic would suggest the following in the completion block:

  func sync(_ completion: (() -> Void)?) {
    if !ensemble.isLeeched {
        ensemble.leechPersistentStore {
            error in
            completion?()
        }        
    } else {
        //ensemble.merge
        ensemble.merge(completion: {
            error in
            if error == CDEErrorCode.cloudIdentityChanged {
                iCloudAlert()
            }
            completion?()  
        })
    }        
}

But the 'if error == ...' line returns the message, " Binary operator '==' cannot be applied to operands of type 'Error?' and 'CDEErrorCode' "

Have tried many variants & type casts to no avail. Suggestions would be hugely appreciated. PS This is Swift 3, with Ensembles v1.7.1. Everything works wonderfully, just can't catch this error specifically.

drewmccormack commented 6 years ago

Would think you just cast to CDEErrorCode.

if let cdeError = error as? CDEErrorCode, cdeError == .cloudIdentityChanged {
    iCloudAlert()
}
MickStupp commented 6 years ago

You make it sound so simple. Many thanks. I revisited various casts I tried and still can't see why they didn't work, so setting time aside today to get this figured out and properly understood.

MickStupp commented 6 years ago

For the benefit of anyone missing the point like I did: Comma separated conditions in a 'if' statement are not the same as && (which is where I went wrong in one of my many 'nearly there' attempts). In this example, cdeError will not be of type CDEErrorCode if the two conditions are anything but two separate conditions, comma separated! Thanks again to Drew for this idiots guide to Swift.

drewmccormack commented 6 years ago

There are similarities to &&, but indeed not the same. It evaluates each condition in turn, and will not proceed unless they are all true. That much is the same. But they are separate statements, and evaluated separately.

Effectively, you are doing this:

if let cdeError = error as? CDEErrorCode {
    if cdeError == .cloudIdentityChanges {
        ...