groue / GRDBCombine

GRDB ❤️ Combine
MIT License
223 stars 16 forks source link

Obtaining unique items and displaying them in a list with SwiftUI #20

Closed EricG-Personal closed 4 years ago

EricG-Personal commented 4 years ago

I have a sample test project at https://github.com/EricG-Personal/grdb_test.git

In ContentView.swift, I currently have one list that shows all of the items in the Database.

Below that, I would like another list that shows all of the unique 'names' from the test table. While I think I know one or two ways to accomplish this task, I am pretty sure neither of them would be the recommended method.

How do you recommend I do this the correct way using GRDBCombine? Would it involve another publisher?

groue commented 4 years ago

Hello @EricG-Personal,

I'm not sure if your question is about what you want to do (pick a choice), or about how to do what you want (actual implementation of the choice).

EricG-Personal commented 4 years ago

The implementation.

I am not sure what the code for the second List {}, that would only display the distinct names from the test table, should look like or what GRDBCombine related code would need to be added to the model, etc.

groue commented 4 years ago

What did you try?

Did you try, for example, to derive a publisher of distinct names from the publisher of items?

This is the GRDBCombine repository. You'll get answers about this library and GRDB, but not about how to build applications with Combine and SwiftUI. Apple developers forums and Stack Overflow are better places to ask this kind of question.

EricG-Personal commented 4 years ago

I am trying to ask about how to use your library with SwiftUI and am getting lost in the details about where the line is drawn between your particular library, combine, and swiftui. An answer to this question, which involves the “right” way to use your library in this context, would help me to determine where that line is.

I am not sure how to derive a publisher of distinct names from the publisher of items at this time. I assume that since you suggested it, it would be the correct answer. I will see if I can figure it out on my own, but would appreciate it if you could show me what that would look like.

groue commented 4 years ago

I understand. Yes, it is difficult to discover so many technologies at the same time. And you know what? I'm in the exact same situation as yours. That's one of the reasons why I don't feel comfortable suggesting anything. I'm just not versatile enough with SwiftUI to be able to do that. Just like you, I hope I'll improve with time.

I am not sure how to derive a publisher of distinct names from the publisher of items at this time.

With Combine, you use map:

// Grab a publisher of [Item], from GRDBCombine, I guess.
let itemsPublisher = ...
// Turn it into a publisher of distinct names
let namesPublisher = itemsPublisher.map { (items: [Item]) -> Set<String> in
    let names = items.map { $0.name }
    let distinctNames = Set(names)
    return distinctNames
}
// Plug the namesPublisher on your UI

The techniques that you have to use in order to plug Combine publishers on to SwiftUI views is described in your favorite SwiftUI tutorials.

Now, as your experience grows, if you eventually find that a Combine/SwiftUI technique you wish to use is made difficult or contrived because of GRDBCombine, then please open an issue, and use your experience in order to explain how GRDBCombine could be improved in order to ease its integration with its environment. That will be a very welcome contribution.

EricG-Personal commented 4 years ago

Understood. It is, unfortunately, still unclear to me exactly where I would put that code or what should surround it.

I have posted this question to StackOverflow and the Apple Developer Forums as suggested. Perhaps someone will be able to provide some assistance to help us both out. I am sure the answer, once learned, will be both interesting and educational.

Thank you for your reply.

EricG-Personal commented 4 years ago

I was able to figure out an answer and, if you are interested, you can take a look at it to see if you can recommend any improvements to it as it is likely there are better ways to use your framework.

I was unable to figure out how to make use of the solution you suggested, however, upon considering it further, I am not sure how well it would work as it would seem to require that all of the data be loaded from the database first and then the unique processing would be handled by Swift. In my solution, ask the database to perform the unique test and return to me only those results...I think performance will be much better this way.

I would still be interested in learning more about what you had in mind with your solution as well. It would be something interesting to learn.

At least one flaw I can see with my solution is I believe I am making more requests on the database than are strictly necessary and this may be what your solution resolved.

In any case, you can check the commit out at:

https://github.com/EricG-Personal/grdb_test/commit/79cc0488f8ac6d387236973040817a79126265d8

groue commented 4 years ago

[...] In my solution, ask the database to perform the unique test and return to me only those results...I think performance will be much better this way. [...] At least one flaw I can see with my solution is I believe I am making more requests on the database than are strictly necessary and this may be what your solution resolved.

I indeed has in mind to run less SQL queries. But I'm not sure this is very important at all.

What is important is that your app works as expected. And I'm happy you found a solution.

Later, if you have the time, you'll be able to tweak it and address any issue you notice (whether it is code clarity, or performance, or whatever you decide is worth your time).

I suppose this issue can be closed, now.

EricG-Personal commented 4 years ago

Is it a solution? It works for the moment, but I am not certain there will be no conflicts between the two publishers which may result in unexpected behavior.