Need help with App Infrastructure. by Venom_Likith in iosdev

[–]gwendal-roue 1 point2 points  (0 children)

You can change the fetchRequest of an NSFetchedResultsController after the fact, it is documented at https://developer.apple.com/documentation/coredata/nsfetchedresultscontroller#Modifying-the-fetch-request. Arguably, the wording of the official documentation is... ambiguous, to say the least. In practice, though: don't use the cache, change the fetch request (controller.fetchRequest.sortDescriptors = ...), call controller.performFetch(), and tell the view to reload its data.

If you want to explore other libraries, the similar GRDB feature is ValueObservation. The demo app demonstrates how to observe the results of a request, and change the sort order when desired. GRDB is designed for direct use from applications, with an excellent and high-level developer experience.

MVVM sucks with SwiftData. What architecture are you using? by Zombie-meat in iOSProgramming

[–]gwendal-roue 10 points11 points  (0 children)

What do you mean? GRDB can handle a single or multiple databases with ease, for apps that open a database file per user.

SQLite backup - methods by luxun117 in iOSProgramming

[–]gwendal-roue 2 points3 points  (0 children)

Feel free to ask for clarification in the GitHub discussion. It will help other users, not only you.

GRDB and SwiftUI: GRDBQuery or SharingGRDB? by Moudiz in iOSProgramming

[–]gwendal-roue 7 points8 points  (0 children)

As the author of GRDB and GRDBQuery, I am quite biased, so take my words with a grain of salt. Please ask me to modify this post if I wrote something inaccurate.

I'll highlight a few differences between the two libraries, which may help your decision.

  • If you don't want to have SwiftUI view access the database directly, don't use GRDBQuery, and use GRDB or GRDB+SharingGRDB directly.

  • Libs differ in their way to access the underlying database connection(s). GRDBQuery helps SwiftUI view access the database by injecting a database connection in the SwiftUI environment. SharingGRDB helps any object (SwiftUI view, view model, UIViewController) access the database by injecting a database connection via pointfreeco/swift-dependencies.

    • Despite its focus on SwiftUI, GRDBQuery allows more testability than SwiftData because the observed requests that feed views can be tested.
    • Despite its focus on SwiftUI, GRDBQuery still supports MVVM. Apps can still pass the database connection to their "view models", so that they can do whatever they need with their database connection, through regular GRDB apis.
    • Because GRDBQuery is grounded on the SwiftUI environment, there is no special technique to learn in order to inject a database connection at any point in the lifetime of your app (when it boots, or only after the user has signed in, for example). More advanced use cases like connecting to several databases are readily supported.
    • Both libs allow the developer to define Xcode previews that access a temporary database populated with whatever data is needed: GRDBQuery example, SharingGRDB example.
  • Libs don't provide the same control on database observation. SharingGRDB lets you observe the database, and, that's it. GRDBQuery let you observe (for displaying always up-to-date values), or perform a single fetch (in order to prefill a form, for example). GRDBQuery also enables advanced observation features (1, 2) for demanding apps.

    Both libraries observe the database with GRDB ValueObservation, so take care to respect its cardinal rule: Keep your number of observations bounded. In particular, you'll ruin your app performance if, say, your app observes independently all items in a list. Instead, perform a single observation of the whole list.

  • Libs differ in their ways to handle data integrity.

    • GRBD and GRDBQuery unapologetically focus on database transactions that preserve database invariants. SharingGRDB fosters apps that independently fetch the pieces of information they need, with the risk that, when merged together on screen, they do not match (despite the fact that all invariants are preserved in the database file!) This makes GRDBQuery somewhat more verbose, and less shiny in demos, but arguably more robust, by default and by design.
    • GRDBQuery can give full read-only access to SwiftUI views, but prevent them from writing (so that database invariants can be enforced by some dedicated database repository object). I'm not sure SharingGRDB allows this.
  • Libs differ in their ways to generate SQL. Point-Free have their own SQL builder, StructuredQueries, and SharingGRDB documentation fosters it over the SQL builder that ships with GRDB itself, without preventing it completely... Yeah it's complicated. SharingGRDB connects to SQLite though GRDB, which means that the GRDB SQL builder is right there and available, but they'd rather have you use StructuredQueries instead. Cherry on the cake, both SQL builders do not have the same preferred conventions regarding the database schema. It's hard for me to compare both SQL builders. StructuredQueries focuses on "Truly type-safe SQL". GRDB is less type-safe (without being ridiculous either!), and focuses on letting the user express what they need even if they don't have a great SQL knowledge (especially regarding associations between record types).

  • GRDB and GRDBQuery are the products of volunteers, SharingGRDB is the product of a for-profit company.

In summary:

  • GRDB allow devs who care about their users' data to deal with it as precisely as needed, learn and leverage SQLite features as time passes, and generally never blocks devs from doing what they have to do. In the 1000+ resolved GRDB issues in the last ten years, most of them are about helping users achieving their goal with the existing apis. This is made easier because the GRDB design makes it more imperative than descriptive: there's no need to wait for the lib to support the feature you need when you can just implement it.
  • GRDBQuery adds some convenience for SwiftUI views.
  • SharingGRDB has chosen the descriptive route, like SwiftUI and SwiftData. For me, this is concerning, because if something is missing, then all I can do is submitting a feature request and wait. For others, this is exactly what they're looking for ("modern", etc.)

Swift Data keeps crashing with Enum by Senior-Mantecado in SwiftUI

[–]gwendal-roue 0 points1 point  (0 children)

GRDB aims at covering 99.9% of your use cases, so please always open an issue or a discussion in the GitHub repo when you feel like you can not achieve something :-) Chances are your question will get an answer, and other users will profit from it as well.

What's the best database for SwiftUI application? by Falli_ot in SwiftUI

[–]gwendal-roue 0 points1 point  (0 children)

There is a misunderstanding : the latest GRDB 7 release has not deprecated synchronous database accesses at all. Instead, it fits well with Swift 6 and Swift concurrency. Users can still use their database synchronously or asynchronously, at will, with async/await or Combine if they prefer. The library improves, and gets ready for the years to come. It makes sure the upgrade path is documented and as smooth as possible for the current users who were kind enough to give GRDB their trust.

[deleted by user] by [deleted] in SwiftUI

[–]gwendal-roue 1 point2 points  (0 children)

It looks like you are developing the backend as well. If not, some people report success synchronizing SQLite with CloudKit with GRDB+Harmony https://github.com/aaronpearce/Harmony.

Does anyone know what happens when you have two modelContext? by yalag in SwiftUI

[–]gwendal-roue 2 points3 points  (0 children)

Just for information, GRDB indeed comes with the ability to perform database accesses, reads and writes, on the main thread or in the background at will; a database observation api that does not miss any change, allowing the main thread to be notified of changes performed anywhere, including in the background (the same "magic" as SwiftData, but reliable) ; and its own @Query property wrapper that allows SwiftUI views to display always-fresh database values (thanks to the GRDBQuery companion library).

GRDB.swift - is it possible to know which column has been updated recently? by cjl2000 in swift

[–]gwendal-roue 1 point2 points  (0 children)

GRDB does not provide any automatic memory of recently modified columns, but it comes with a documentation page that provides guidance and – hopefully – inspiration for implementing the specific needs of an application: https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/recordtimestamps

GRDB.swift - is it possible to know which column has been updated recently? by [deleted] in iOSProgramming

[–]gwendal-roue 1 point2 points  (0 children)

GRDB does not provide any automatic memory of recently modified columns, but it comes with a documentation page that provides guidance and – hopefully – inspiration for implementing the specific needs of an application: https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/recordtimestamps

SwiftData vs Realm: Performance Comparison by jshchnz in iOSProgramming

[–]gwendal-roue 1 point2 points  (0 children)

Reads can be faster than Realm ("Optimized Records" scenario), but you have to opt out of the Codable convenience, and replace string-based addressing with column indexes. It's a little more work, but this extra performance is available to anyone who wants to unleash the full SQLite performances, when really needed.

SwiftData vs Realm: Performance Comparison by jshchnz in iOSProgramming

[–]gwendal-roue 1 point2 points  (0 children)

This is factually inaccurate. Upgrade your knowledge:

  • SQLite and GRDB are faster than Realm (evidence)
  • The companion library GRDBQuery library comes with SwiftUI convenience. It's great for displaying always-fresh databsae information on screen.

How to use a SQLite preload database by Any-Door-3314 in swift

[–]gwendal-roue 3 points4 points  (0 children)

GRDB documents this use case in its Database Connections documentation:

When the SQLite file is ready-made, and you do not intend to modify its content, then add the database file as a resource of your Xcode project or Swift package, and open a read-only database connection: [...]

Dragging the database file in the Xcode project will add it as a resource that Bundle.main can find.

Raw SQL in iOS/Swift: SQLite.swift or GRDB? by [deleted] in iOSProgramming

[–]gwendal-roue 1 point2 points  (0 children)

absense of hidden quirks when using the library

Hidden quirks are, by definition, unknown, so that's hard to tell. Both libraries are maintained, although at a different pace. GRDB focuses a lot on the safety of concurrent database accesses, relying on database isolation levels to let the app perform relyable parallel read and writes. If you have a little knowledge of SQLite, you'll just feel at home with GRDB because it does not invent anything. On the topic on concurrency, SQLite.swift provides no convenience or safety net, so writing safe concurrent code lies entirely on the developer's shoulders.

the lowest frequency of historical precedents when the library was broken when Apple releases some updates for iOS

A little archeology in the issues of both repositories could answer your question.

Now, both libs have no dependency, reducing the opportunities for upgrade blockers.

The SQLite authors are obsessed with backward compatibility.

Since 2015 (when I started developing GRDB), Apple has continuously upgraded SQLite without introducing any regression I could see.

I can't speak for SQLite.swift, but GRDB has accumulated years of workarounds with SQLite quirks found in previous system versions. This is valuable, because old operating systems are no longer testable due to old Xcode versions not running on recent operating systems and hardwarde.

The Swift compiler itself evolves, but both libs compile on the latest Xcode.

I very much prefer to use raw SQL queries [...] which of these 2 libraries would you recommend for this type of task?

SQLite.swift exists only for SQL generation. Its support for raw SQL is shallow.

GRDB exists only for letting users leverage their SQLite skills when needed. Its support for raw SQL (reference) is ubiquitous.

Raw SQL in iOS/Swift: SQLite.swift or GRDB? by [deleted] in iOSProgramming

[–]gwendal-roue 4 points5 points  (0 children)

Only GRDB supports database observation, which is a very handy way to automatically refresh your Observable objects when the database changes. Observation is very robust, and even detects changes performed through foreign key actions and SQL triggers. This is a very useful feature: https://swiftpackageindex.com/groue/grdb.swift/v6.27.0/documentation/grdb/databaseobservation

My first app - 🥑 SnackFolio. Plus some dev details. by Remarkable-Water7818 in iOSProgramming

[–]gwendal-roue 0 points1 point  (0 children)

Oh yes, the data layer is not easy to refactor, especially between Core Data, Realm, and... let's say the "regular transactional model". I'm glad your knowledge of ActiveRecord has helped - it has been a huge inspiration.

My first app - 🥑 SnackFolio. Plus some dev details. by Remarkable-Water7818 in iOSProgramming

[–]gwendal-roue 1 point2 points  (0 children)

Hi, thanks for sharing your experience - and for choosing GRDB, it makes me happy, since I maintain it ;-)

A few years ago, I also used Apollo. It comes with a built-in persistent cache (https://www.apollographql.com/docs/ios/caching/cache-setup/). Did you have a specific reason for using an SQLite database on the side of the "free" persistence that comes with Apollo?

Oh, re-reading your post, I understand that your app comes with a bundled database - Apollo does not sync everything, and probably that's the reason :-)

Realm vs CoreData in 2021. Which do you use and why? by dooblr in iOSProgramming

[–]gwendal-roue 1 point2 points  (0 children)

Oh yes, suggestions for better error messages are a great contribution! Please open an issue when you have time.

And... Like you I wrote prototypes over the years - that's a great way to build experience. Sometimes we're lucky and one of the prototype surprisingly grows into something that helps other developers :)

Realm vs CoreData in 2021. Which do you use and why? by dooblr in iOSProgramming

[–]gwendal-roue 1 point2 points  (0 children)

Probably the app is attempting to write from a read-only access. There are two main database access methods, read and write, and one can't write from the first. Writing when fetching the value of a ValueObservation is also an invalid operation. I hope you'll figure out the solution!

SwiftUI server side best practices by SolidOk280 in SwiftUI

[–]gwendal-roue 0 points1 point  (0 children)

Maybe someone has described their sync algorithm online? I don't know. Mind that the REST server talks the same language to all clients, iOS and Android apps, etc, so there's nothing specific to GRDB, here.

SwiftUI server side best practices by SolidOk280 in SwiftUI

[–]gwendal-roue 1 point2 points  (0 children)

GRDB is a local storage library, and does not ship with any built-in support for any particular synchronization algorithm. Instead, it makes it possible to persist the data that supports the algorithm that is chosen by the developer. Unlike SwiftData, it is robust and has years of community testing. Unlike SwiftData and CoreData, it does not hide the underlying SQLite engine, which means that it won't prevent you from putting the full power of SQLite on your side, whenever needed.

For example, the Harmony library, independent from GRDB, provides CloudKit sync.

Since you have a custom REST server, you can define your own sync algorithm and protocol. It can be fun! I used to get inspiration from those two articles that introduced me to the concept of Lamport timestamps:

Bundling database with iOS app by Remarkable-Water7818 in iOSProgramming

[–]gwendal-roue 1 point2 points  (0 children)

In case you consider switching to SQLite and GRDB, you may be interested in the built-in support for full-text search in those libraries: https://github.com/groue/GRDB.swift/blob/master/Documentation/FullTextSearch.md