Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add async/await wrappers #212

Merged
merged 104 commits into from
Oct 4, 2021
Merged

feat: Add async/await wrappers #212

merged 104 commits into from
Oct 4, 2021

Conversation

cbaker6
Copy link
Contributor

@cbaker6 cbaker6 commented Aug 6, 2021

New Pull Request Checklist

Issue Description

Add all necessary async/await wrappers. Requires Xcode 13 beta and Swift 5.5.

Developers wanting to use async/await should point their SPM to this branch.

Related issue: #234

Approach

Add async/await using wrappers around async completion methods.

TODOs before merging

  • add async/await for all ParseObject variants and other types
  • add async/await for ParseAuthentication types
  • bump CI to Xcode 13
  • update documentation for async/await
  • add test cases
  • add change log entry
  • wait for codecov.io to support Xcode 13 codecov Letting codecov slip for now since codecov.io can't read Xcode 13 xcrun llvm-cov properly. The codecov is really at 85%, will rerun when the website can read latest Xcode.

@codecov
Copy link

codecov bot commented Aug 6, 2021

Codecov Report

Merging #212 (577c5d3) into main (97011ac) will decrease coverage by 7.14%.
The diff coverage is 23.86%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #212      +/-   ##
==========================================
- Coverage   83.83%   76.68%   -7.15%     
==========================================
  Files          80       99      +19     
  Lines        7392    10351    +2959     
==========================================
+ Hits         6197     7938    +1741     
- Misses       1195     2413    +1218     
Impacted Files Coverage Δ
...cation/3rd Party/ParseApple/ParseApple+async.swift 0.00% <0.00%> (ø)
...thentication/3rd Party/ParseApple/ParseApple.swift 82.50% <ø> (ø)
.../3rd Party/ParseFacebook/ParseFacebook+async.swift 0.00% <0.00%> (ø)
...cation/3rd Party/ParseFacebook/ParseFacebook.swift 100.00% <ø> (ø)
...tication/3rd Party/ParseLDAP/ParseLDAP+async.swift 0.00% <0.00%> (ø)
...Authentication/3rd Party/ParseLDAP/ParseLDAP.swift 100.00% <ø> (ø)
...on/3rd Party/ParseTwitter/ParseTwitter+async.swift 0.00% <0.00%> (ø)
...tication/3rd Party/ParseTwitter/ParseTwitter.swift 100.00% <ø> (ø)
...Authentication/Internal/ParseAnonymous+async.swift 0.00% <0.00%> (ø)
...Swift/Authentication/Internal/ParseAnonymous.swift 100.00% <ø> (ø)
... and 106 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 97011ac...577c5d3. Read the comment docs.

@cbaker6 cbaker6 marked this pull request as draft August 7, 2021 23:56
@vdkdamian
Copy link
Contributor

@cbaker6 Are SubscriptionCallback's supported? .handleEvent seems to look the same?

@cbaker6
Copy link
Contributor Author

cbaker6 commented Sep 30, 2021

@cbaker6 Are SubscriptionCallback's supported? .handleEvent seems to look the same?

What would be the use case for using async/await with a subscription callback or with subscriptions for LiveQuery in general?

@vdkdamian
Copy link
Contributor

@cbaker6 Are SubscriptionCallback's supported? .handleEvent seems to look the same?

What would be the use case for using async/await with a subscription callback or with subscriptions for LiveQuery in general?

I notice that I can't run my own async code this way. Is there an alternative approach I am missing?
I call the function like this

let query = NVMFile.query("project" == app.rawValue)
let subscription = query.subscribeCallback!
await handleSynchronisation(subscription: subscription)

Schermafbeelding 2021-09-30 om 17 21 16

@vdkdamian
Copy link
Contributor

@cbaker6 Also another question, what is the correct/best way to compare errors when using async?

I used to check it like this:

let query = NVMFile.query()
query.first() { results in
    switch results {
    case .success(_):
        //Do stuff
    case .failure(let error):
        if error.code == ParseError.Code.objectNotFound {
            //Do stuff
        } else {
            //Do other stuff
        }
    }
}

i thought of something like this, but I doubt it will be good:

do {
    //Stuff
} catch let queryError {
    if let parseError = queryError as? ParseError, parseError.code == ParseError.Code.objectNotFound {
        //Do stuff
    }
    else {
        //Do other stuff
    }
}

@cbaker6
Copy link
Contributor Author

cbaker6 commented Sep 30, 2021

I suggest reading https://www.avanderlee.com/swift/async-await/#async-methods-call-in-a-function-that-does-not-support-concurrency and https://www.andyibanez.com/posts/understanding-async-await-in-swift/

The rest of that article discusses when and how to use async/await and it's important to note it's not the solution for everything.

@vdkdamian
Copy link
Contributor

@cbaker6 Also another question, what is the correct/best way to compare errors when using async?

I used to check it like this:


let query = NVMFile.query()

query.first() { results in

    switch results {

    case .success(_):

        //Do stuff

    case .failure(let error):

        if error.code == ParseError.Code.objectNotFound {

            //Do stuff

        } else {

            //Do other stuff

        }

    }

}

i thought of something like this, but I doubt it will be good:


do {

    //Stuff

} catch let queryError {

    if let parseError = queryError as? ParseError, parseError.code == ParseError.Code.objectNotFound {

        //Do stuff

    }

    else {

        //Do other stuff

    }

}

@cbaker6

Do you have an idea on how to cleanly compare Errors catched from a trycatch with ParseError?

You think my method is the best, or are there better options?

@cbaker6
Copy link
Contributor Author

cbaker6 commented Oct 3, 2021

Your process is fine, though you can shrink the code some and handle errors with a switch:

do {

    //try Stuff

} catch {

   guard let parseError = error as? ParseError else {
        //Do stuff for different error
      return
    }

    // Handle ParseError.
   switch parseError.code {
                case .objectNotFound: 
                    // Handle object not found
                default:
                    // There was a different issue that we don't know how to handle
                }

}

You can see similar in my SDK, though it's currently not using async, https://github.com/netreconlab/ParseCareKit/blob/949393ea1e74eb01ef99c165e1966ff4490a0bae/Sources/ParseCareKit/Objects/Patient.swift#L114-L144

@vdkdamian
Copy link
Contributor

vdkdamian commented Oct 3, 2021

@cbaker6 Question, would it be possible to merge 1.10.1 into this branch?

My SPM is set on your async branch, and this way I could test te changes in 1.10.1

If this isn't an option, no problem, but I think it's worth the question.

Thanks in advance!

@cbaker6 cbaker6 merged commit 9cab7f1 into main Oct 4, 2021
@cbaker6 cbaker6 deleted the async branch October 4, 2021 00:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add async/await for Swift 5.5
2 participants