Group Group Group Group Group Group Group Group Group

Realm with SwiftUI Tutorial: Getting Started | raywenderlich.com

In this SwiftUI Realm tutorial, you’ll learn how to use Realm with SwiftUI as a data persistence solution by building a potion shopping list app.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/12235561-realm-with-swiftui-tutorial-getting-started

app doesn’t respond to delete action once ingredients were created, but only responds after clearing background and reopen, can you help in this

Hi Fahath, how are you?
Can you tell me at which section of the article this happened? Also, can you share your code with us?
Thanks!

Hey,

I really like your tutorial for getting into Realm. One Question: What is the reason for converting the RealmResult to the array with ingredients? I tried to make the result non-public and had the same function when I put the result in the foreach and took the props out of every row. Does it make the procedure safer or is it for a different reason?

Stefan

Hi @stefan51278! I’m really glad you like it! Thank you very much.

As for your question, Realm keeps track of its objects (Managed Objects) and whenever an object is changed it reactively updates all its references across your app. When an object is deleted from realm the framework invalidates that object (marking it as invalid) and if you try to access its properties, through any of its references, the framework throws an exception. internally SwiftUIs ForEach keeps a reference to the old objects for diffing the diferences once a view reload is triggered. When a view reload is triggers, SwiftUI tries to access the deleted object and triggers that exception. By converting to a model object (Ingredient) we can freely work with its references.

Hope that answers your question! Feel free to make more questions. :]

1 Like

Thanks for the tutorial. It was very helpful for me. I’d love to see more tutorials diving deeper into how to use Realm with SwiftUI and combine.

One minor nitpick… in the “Deleting Objects” section, you find the object using the code:

guard let ingredientDB = boughtIngredientResults.first(where: { $0.id == ingredientID })

That will force the predicate to be run over every single entry, which is pretty wasteful if there is a lot of data. Instead you could just look it up by its primary key (which will use a quick index lookup):

guard let ingredientDB = realm.object(ofType: IngredientDB.self, forPrimaryKey: ingredientID)

Hi @drivingjohn. Thank you so much, I’m really happy you like it!
Indeed using Realm to look up the object is a more efficient way, nice catch! I’ll be looking into updating the article. Thank you! :]

Thanks for the tutorial. Is it possible to make Realm work with previews?

Hi @tudatn.

Yes it is possible, however, you may run into a series of problems. Since each preview is a kind of simulator, you’d have to take care of model migrations inside each preview, just like any other simulator, for example. That might be a bit troublesome since Xcode previews are a bit undercooked yet when it comes to displaying errors.

A nice way you could go about this is using a realm in memory, that way you don’t have to worry about that and you can use a in memory realm for your preview data.

After working through the first part of the tutorial to Add and Fetch data (but before updating the model with a new property), I ran the app and got this error:

"Fatal error: Failed to open Realm. Error. Provided schema version 0 is less than last set version 1".

I was able to fix this by going into the Simulator, then going to the Device menu and choosing “Erase All Content and Settings…” After that, the app ran. Thought I’d share this in case someone else runs into that problem. I must have run the app at some earlier stage to cause this difference in the schema version number. That’s my guess.

Is this book still available? https://store.raywenderlich.com/products/realm-building-modern-swift-apps-with-realm-database

Hi @tomp.

You are most certainly right. This probably happen by you running the final project or changing the model’s properties in someway (just by renaming because of a typo for example might cause this).

Another way to fix this, during development, is by deleting the app from the simulator and running it again.

Hi @spencerfeng

This book has been deprecated, so we don’t support it anymore. You can still read it and find its material here: https://bit.ly/2N30PKO

Thank you @renan.dias, may I know the reason why this book is deprecated?

Thank you Renan for the great tutorial. I just finished working through it today and learned a lot about working with Realm in SwiftUI. I like how this way of working with Realm allows you to still use structs in Views instead of using the Realm objects directly.

I did have one general question about how this might be extended to a common scenario. If you have a list of items and you want to reorder them using the .onMove method built into the SwiftUI List, what might that look like in the Store code (in general terms)? In other words, how would you update the order of a Realm List property?

Hi @tomp. I’m really glad you liked it! The team worked really hard on this article. :]

Regarding your question about the order of the list. I don’t think you’d be able to use SwiftUIs .onMove directly like you could with a simple array. You’d have to have a method to handle .onMove and then move the objects yourself. A way to do this is by adding a property “order” to the realm object and updating it whenever it changes. That way when fetching objects from realm you can use the sort method to do this. Something around the like of this:
realm.objects(IngredientDB.self).sort(byKeyPath: "order", ascending: false)

This is an excellent tutorial and I really enjoy the approach. I have tried to extend this with another app that I am testing where I have one class that is Category and another that is Questions where a Category object has a realm LIST of questions.

class CategoryDB Object {
  @objc dynamic var id = 0
  @objc dynamic var name = ""
  let questions = List<QuestionDB>()

 override class func primaryKey() -> String? {
    "id"
 }

}

The problem I am having is that when I navigation to the category’s list of questions and try to add a question it updates the realm database, but my view does not refresh. I have to back out back the Category list and then back to Question list view to see the list of updated questions.
I don’t know how to send updates to the Store so that when I add a new question and append it to my realm list object that it would also refresh that view.

Now, I don’t expect an answer here, but It would be great to see more tutorials with Realm and SwiftUI that will deal with more complex models where we do have List or a LinkingObject

Hi @createch . Thank you for reading this article. I’m really glad you enjoyed it.

Regarding the problem you’re having, this might be happening because your view is observing changes to the Category object and not to the array itself. An example of this is when you have an array and you change an object of this array. Depending the way you do this SwiftUI won’t see the changes. I can’t say much without looking at the code but you could also try sending updates to the UI manually by using objectWillChange on your ObservableObject. You usually don’t need this but like I said I can’t say much without reading the code.

As to more tutorials with Realm and SwiftUI, I’ll talk to our team lead about the possibility of releasing more tutorials with these subjects. :]

You can still learn a lot from this book, but it hasn’t been updated in a while. Since working with SwiftUI and Realm is a bit different from what’s depicted in the book (it doesn’t even have a section for SwiftUI) and new features were introduced to the framework, the book does not contain all these new feature and it has been deprecated.
Realm has been updating to give full support for SwiftUI and it should release some new features in the near future.

@spencerfeng You can access all of our deprecated books over here for free:

I hope it helps!

1 Like