Skip to content

iOS 14 User logout does not erase session #44

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

Closed
pmmlo opened this issue Dec 30, 2020 · 19 comments · Fixed by #43
Closed

iOS 14 User logout does not erase session #44

pmmlo opened this issue Dec 30, 2020 · 19 comments · Fixed by #43
Labels
type:bug Impaired feature or lacking behavior that is likely assumed

Comments

@pmmlo
Copy link
Contributor

pmmlo commented Dec 30, 2020

Hi All - Wanted to check if I am having an implementation issue. I have tried calling logout both synchronously and asynchronously. No trouble removing the keychain object, but the session object in database persists.

Anybody having this issue in iOS 14?

@cbaker6
Copy link
Contributor

cbaker6 commented Dec 30, 2020

By database do you mean still exists on the Parse server?

@pmmlo
Copy link
Contributor Author

pmmlo commented Dec 30, 2020

By database do you mean still exists on the Parse server?

Yup. When I login again, the session objectId is changed. I am not familiar enough with parse-server and Parse-Swift, so I am not sure if this is a failure in parse-server promise/callback or Parse-Swift not issuing API call.

@cbaker6
Copy link
Contributor

cbaker6 commented Dec 30, 2020

Thanks for filing the issue! I think this is a bug in the SDK. I believe I know where the problem is.

@pmmlo
Copy link
Contributor Author

pmmlo commented Dec 30, 2020

Thanks for filing the issue! I think this is a bug in the SDK. I believe I know where the problem is.

Got it! Thanks @cbaker6. Your PRs are always on point. Love the rotating keys in parse-server.

@cbaker6
Copy link
Contributor

cbaker6 commented Dec 30, 2020

Your PRs are always on point. Love the rotating keys in parse-server.

appreciate you 🙏🏾

@pmmlo
Copy link
Contributor Author

pmmlo commented Dec 31, 2020

@cbaker6 Thanks for the quick fix. Would have taken me a long time to figure out the updated API endpoint. Cheers!

@cbaker6
Copy link
Contributor

cbaker6 commented Dec 31, 2020

No problem @pmmlo thanks for reporting! How do you like using the framework so far (pros/cons)? Also, are you coming from the objective-c iOS SDK? If so, any challenges, things you like better/worse?

Of course, let us know if you find any other issues and if you find something you want to tackle, open a PR and we can help.

@pmmlo
Copy link
Contributor Author

pmmlo commented Dec 31, 2020

I actually haven't used Parse+Objective-C SDK since the pre-acquisition days and the initial transition to an open source project. I believe there wasn't an open source SDK at that time, so I wrote my own wrapper around the web API. So, I can't speak much to the comparison, but skimming through both SDKs, they look like a nearly direct port.

Overall, I think Parse+Open Source is excellent. I mostly use SwiftUI with the changing times, unless I need lower-level.

These are just initial thoughts from my short use.
Pros:

  • SPM (what made me use Parse-Swift over Parse-SDK-iOS)
  • Plans for integrated Livequery
  • Very straightforward open source contribution.

Cons:

  • No Livequery.

@pmmlo pmmlo closed this as completed Dec 31, 2020
@cbaker6
Copy link
Contributor

cbaker6 commented Jan 1, 2021

The public parts of the framework are made to look a little similar to the objective-c one, but they are only minor pieces that have been ported (Keychain and FileManager come to mind). Hopefully the similarity of the public parts makes it easier to use. Under the hood, Parse-Swift is a lot different from it’s counterpart.

@cbaker6
Copy link
Contributor

cbaker6 commented Jan 1, 2021

Opening this back up. The linked PR fixing the bug will close it once it’s merged

@cbaker6 cbaker6 reopened this Jan 1, 2021
@pmmlo
Copy link
Contributor Author

pmmlo commented Jan 3, 2021

@cbaker6 I had a little time to dig into Parse-Swift's query syntax. I think the QueryConstraint encoder methods are powerful, more explicit, manageable and extensible.

On initial thought, I think QueryConstraint methods are overall better than passing arguments. It's been a number of years, but I recall constraints being passed as arguments. This really made it difficult to extend complex compound queries and arguably, readability suffered.

This choice of making QueryConstraint methods wrap encoders is definitely more explicit and seems to be very extensible as new cases arise. I think one of the downsides of this new conceptual choice is a loss of parity with the other Parse SDKs, so the associated challenges have to be balanced.

I did have one question: do you think we should potentially create a public init for the QueryConstraint struct, so end users can wrap their own methods around the encoder rather than having to wrap the methods? Then we could call something like this:

let query = GameScore.query(QueryConstraint(key: "score", value: 0, comparator: Comparator.greatherThanOrEqualTo))

query.find(callbackQueue: .main) { results in
    switch results {
    case .success(let scores):
        if scores.count >= 1 {
            scores.forEach { score in
                print("\(score)")
            }
        }
    case .failure(let error):
        print("Error querying: \(error)")
    }
}

Just a thought to give developers another syntax option, and allow them to write their own methods that directly wrap the encoder, as needed (rather than contributors writing all permutations).

I may end up thinking this is a dumb idea later but wanted to share while I'm working with Parse Swift.

Not sure if you wrote it, but very well-written IMO.

@cbaker6
Copy link
Contributor

cbaker6 commented Jan 3, 2021

Thanks looking and taking advantage of the framework! Flo started the project and left a strong foundation. My goal has been to stick with (as much as possible) his suggestions in this comment #3 (comment)

Some relevant points he made are:

The guidelines are quite simple, I want to make the SDK as less intrusive as possible, as you may have noticed, pretty much every functionality is coded as protocols.

Backwards compatibility/in-place replacement is not a goal, this is a new SDK with a new philosophy.

Of course, this relieves this SDK of the restrictions of the other SDKs, but introduces a learning curve for experienced parse devs.

As you’ve mentioned, Query works differently. It looks like you already know to use them, but I’ll leave some examples for those who find this later

let pointToFind = ParseGeoPoint(latitude: 40.0, longitude: -30.0)
var constraints = [QueryConstraint]()
constraints.append(near(key: "location", geoPoint: pointToFind))
let query = GameScore.query(constraints)
query.find { results in
switch results {
case .success(let scores):
assert(scores.count >= 1)
scores.forEach { (score) in
print("Someone with objectId \"\(score.objectId!)\" has a score of \"\(score.score)\" near me")
}
case .failure(let error):
assertionFailure("Error querying: \(error)")
}
}

Or like this:

var query3 = GameScore.query("score" > 50, doesNotExist(key: "location"))
query3.find { results in
switch results {
case .success(let scores):
assert(scores.count >= 1)
scores.forEach { (score) in
print("""
Someone has a score of \"\(score.score)\" with no geopoint \(String(describing: score.location))
""")
}
case .failure(let error):
assertionFailure("Error querying: \(error)")
}
}

To your question:

I did have one question: do you think we should potentially create a public init for the QueryConstraint struct, so end users can wrap their own methods around the encoder rather than having to wrap the methods?

I’m not sure, but maybe I don’t understand the usecases for it. How do you envision this making it easier?

@pmmlo
Copy link
Contributor Author

pmmlo commented Jan 3, 2021

Thanks for the examples! I was looking at the source to figure out how queries work.

I did have one question: do you think we should potentially create a public init for the QueryConstraint struct, so end users can wrap their own methods around the encoder rather than having to wrap the methods?

I’m not sure, but maybe I don’t understand the usecases for it. How do you envision this making it easier?

The reason why I asked was because I couldn't figure out how to query by Pointers. It seems like in the other SDK you can simply do an equals query, something like this:

let playerPointer = Player(objectId: X) // From separate struct
let query = GameScore.query("lastScorer" == playerPointer) // Let's assume GameScore has a pointer to Player called lastScorer.
query.find { results in
...

If QueryConstraints were public, we could do something like this:

public func equalsPointer(key: String, value: Pointer) -> QueryConstraint {
    return QueryConstraint(key: key, value: value, comparator: .equals)  // This encodes to $eq for the API via enum
}

let playerPointer = Player(objectId: X)
let query = GameScore.query(equalsPointer(key: "lastScorer", value: playerPointer))
query.find { results in
...

@cbaker6
Copy link
Contributor

cbaker6 commented Jan 4, 2021

What happens when you try your first example? Does it not compile or is it the results from the query wrong?

@pmmlo
Copy link
Contributor Author

pmmlo commented Jan 4, 2021

What happens when you try your first example? Does it not compile or is it the results from the query wrong?

Compiles. Succeeds without issue, but cannot find the object. Always success([]).

@cbaker6
Copy link
Contributor

cbaker6 commented Jan 4, 2021

What about the with latest on the main that was just merged? I suspect the older versions of Query were going through the ParseEncoder, treating them as ParseObjects and removing the objectId of the Pointer before it got to the server. I think I switched to not skipping keys for queries in the latest merged.

@cbaker6
Copy link
Contributor

cbaker6 commented Jan 4, 2021

If that doesn’t work, can you submit a PR and add an example test case to https://github.com/parse-community/Parse-Swift/blob/main/Tests/ParseSwiftTests/ParseQueryTests.swift

@pmmlo
Copy link
Contributor Author

pmmlo commented Jan 4, 2021

Sorry called away for a moment. No luck, but the update looks really good. Thanks for contributing. I'll try to dig into my issue later and see if I can contribute a fix. Cheers!

@pmmlo
Copy link
Contributor Author

pmmlo commented Jan 7, 2021

Ok, so it turns out I needed to query the pointer by the objectId. Makes sense. Example just in case someone stumbles onto this issue.

// let playerPointer = Player(objectId: X) // <-- DOES NOT WORK
let playerPointer = X // <-- This works.  X is the PlayerPointer object objectId
let query = GameScore.query("lastScorer" == playerPointer) // Let's assume GameScore has a pointer to Player called lastScorer.
query.find { results in
...

@cbaker6 cbaker6 added the type:bug Impaired feature or lacking behavior that is likely assumed label Apr 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:bug Impaired feature or lacking behavior that is likely assumed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants