OmerFlame / SwiftRant

devRant API library made in Swift.
GNU General Public License v3.0
3 stars 1 forks source link

Getting duplicate rants in feed #11

Open WilhelmOks opened 2 years ago

WilhelmOks commented 2 years ago

I'm trying to implement the pagination or infinite loading feature in the feed and I'm getting duplicate rants after loading the third or fourth "page" (= skipping a couple of times).

Maybe I got the system wrong but here is what I'm doing:

First I get the rant feed with skip: 0 and prevSet: nil. I store the rants array and the set (session). Next time I get the rant feed with skip: storedRants.count, prevSet: storedSession. I add the rants to the stored rants array and store the new set (session). Then it repeats like this.

I found it weird that the returned set (session) is always different from the session that I pass. Should it be like this?

I also tried to store only the very first session and then pass it to the next feed rants requests, so that it remains the same. But I still get duplicate rants this way.

Another question would be if it is normal to have duplicate rants in a feed? I never noticed duplicates using the official devRant app, but I'm not sure. Maybe I just missed it.

OmerFlame commented 2 years ago

The official app actually filters out duplicates, this is an issue that is yet to be fixed even in my app. I sat for a long time on this. It sucks.

Edit: fixed typos.

WilhelmOks commented 2 years ago

Thanks for the info. That really sucks because we need to remember the number of filtered out duplicates and subtract them from the "skip" value for the next request (or not?).

Can you tell me what of the two is correct, please:

OmerFlame commented 2 years ago

Every time you load another set of rants from the server, you need to send in the current amount of rants you already have in the skip parameter and your last set in the prevSet parameter, and the filtering has to be done manually in your own code. This sucks, but it works.

WilhelmOks commented 2 years ago

I've implemented the filtering now and realized that after the second "page", every rant is a duplicate. So I don't get any new rants.

I'm doing it like you said: loading the first page of rants by passing skip: 0, prevSet: nil. Then the second page by passing the number of rants of the first page to "skip" and the session from the first page as prevSet. When I then try to load the third page by passing the number of all rants that I have by now to skip, and the set from the second page (or even from the first page, doesn't matter) as prevSet, then all that I get is duplicates and I filter all of them out and don't get any new rants.

I've looked into AltRant (I know it doesn't have filtering duplicates yet) and it looks like it behaves the same, because I get very many duplicates. Can you please check if you get any new rants at all after the second page? Just to know if the issue is in SwiftRant or in the usage of it.

OmerFlame commented 2 years ago

I will try now and let you know.

OmerFlame commented 2 years ago

I am getting slightly different feeds every time, this is really odd. This requires further investigation.

WilhelmOks commented 2 years ago

From the doc of SwiftRant.getRantFeed():

  • prevSet: The RantFeed/set you got in the last fetch. Set to nil if the SwiftRant instance was configured to use the Keychain and User Defaults, the SwiftRant instance will get the set from the last fetch from User Defaults.

Maybe it has something to do with this?

SwiftRant instance was configured to use the Keychain and User Defaults

I don't understand what that means.

OmerFlame commented 2 years ago

You can use SwiftRant in 2 ways, with Keychain and User Defaults and without.

SwiftRant.shared is a SwiftRant instance that was configured to use the Keychain and User Defaults by default.

If you want to override this behavior, you can just make your own instance of SwiftRant that always searches for a token in the token parameter of every API method.

I am pretty sure that this is not related to the issue though. SwiftRant.getRantFeed() DOES store the last set in User Defaults under the key DRLastSet (you can get it outside of the SwiftRant library by calling this method: UserDefaults.standard.string(forKey: "DRLastSet") (returns a String?, be careful for potential nil values)). I am pretty sure that the call to store the last set in User Defaults doesn't fail, since there is no documented reason for it to fail.

WilhelmOks commented 2 years ago

Thanks for clarifying. Is this documented already?

WilhelmOks commented 2 years ago

I tested with the official iOS app again and to my surprise, I get kind of similar results for the "sort by Algo" setting. I scroll down, get the next set of rants. Then I scroll down more and no new rants are loaded anymore. No matter how often I trigger the load of more rants. So, it may be that all the new rants are duplicates and are filtered out.

I wonder if it could be something special to my devRant account. Maybe the algo doesn't have that many different rants for me? :) Or maybe even related to the devRant++ subscription?

OmerFlame commented 2 years ago

I wonder if it could be something special to my devRant account. Maybe the algo doesn't have that many different rants for me? :) Or maybe even related to the devRant++ subscription?

Absolutely not. This is not isolated, this also happens on my account.

Thanks for clarifying. Is this documented already?

The User Defaults key, the default Keychain/User Defaults behavior, or both?

WilhelmOks commented 2 years ago

The User Defaults key, the default Keychain/User Defaults behavior, or both?

I mean the fact that you can use SwiftRant in two ways and what the differences are, as you have discribed.

OmerFlame commented 2 years ago

Yes, this is documented in the the SwiftRant class initializer.