How to use MainActor with Observable Macro in SwiftUI | Swift Concurrency #19

Поділитися
Вставка
  • Опубліковано 28 січ 2025

КОМЕНТАРІ • 31

  • @AdailtonSilvaSP
    @AdailtonSilvaSP 10 місяців тому

    Thank you for this Bootcamp Nick. Now I finally could understand the swift concurrency and apply it to my project!! you're the guy!

  • @Pepe_the_raver
    @Pepe_the_raver 6 місяців тому

    One of my favourite bootcamps of your channel, I can't wait to start calling apis and parsing jsons asynchronously 🥳
    Thanks a lot!!

  • @tejaspatelia8179
    @tejaspatelia8179 8 місяців тому

    Very informative playlist! Kudos to your dedication Nick!

  • @federicoramos
    @federicoramos 11 місяців тому

    Thank you Nick once again for sharing your knowledge!

  • @asadchattha3470
    @asadchattha3470 8 місяців тому

    Thank you so much Nick! Wonderful playlist

  • @7themryze638
    @7themryze638 9 місяців тому

    Thanks for your contents, Nick!

  • @foeroon
    @foeroon 11 місяців тому +3

    Thanks for the video :)
    One question: I have "Strict Concurrency Checking" set to "Complete" and I'm getting a warning here:
    Task { @MainActor in
    self.title = await database.getNewTitle() // < Capture of 'self' with non-sendable type 'ObservableViewModel' in a `@Sendable` closure
    }
    I can make the warning go away by making 'updateTitle' async (and deleting the @MainActor) which seems to be a bad idea. Should I just ignore that warning and/or turn "Strict Concurrency Checking" off? Is the warning an actual issue?

    • @SwiftfulThinking
      @SwiftfulThinking  11 місяців тому +2

      Good callout.. I usually have it on and forgot to turn it on for this video. Seems like marking the function as async and/or @MainActor works. The main thing I wanted to confirm here is to always update the UI from main thread. I'm gunna have to look into this more.

    • @foeroon
      @foeroon 11 місяців тому

      I‘d love to know more about this, I get that warning constantly and the solution I‘ve come up with seems to make things worse more often than not. I‘ll try what you suggested, thanks :)

  • @RichardBaileyrichoncode
    @RichardBaileyrichoncode 4 місяці тому

    Nice. I stumbled on this when in a crunch and just stuck with observableobject until i could come back and figure out why it was not right.

  • @steveloengard5139
    @steveloengard5139 9 місяців тому

    Aha! I wondered what happened to my purple warnings. Thanks, Nick.

  • @danielcrompton7818
    @danielcrompton7818 3 місяці тому

    8:26 PLEASE HELP 😭
    I get an error saying I cannot use Thread.current from asynchronous code, why is yours just a warning?

    • @SwiftfulThinking
      @SwiftfulThinking  3 місяці тому

      Change your Swift Language version to Swift 5, which is what I used while recording

  • @lukaszc.1653
    @lukaszc.1653 4 місяці тому

    If body runs on MainActor, why would I want to annotate properties of @Observable with MainActor if they are gonna end up in the MainActor anyway? Am I missing something?

    • @SwiftfulThinking
      @SwiftfulThinking  4 місяці тому

      If you “await” to get into the Observable, and it’s not on MainActor, there’s a chance that it switches context. I don’t think that it should happen but the compiler doesn’t know that. Adding this annotation seems to fix compiler warnings.

  • @tiam303
    @tiam303 11 місяців тому +1

    I don't have any experience with @Observable, but I think the error @ 9:03 should go away if you anotate your View with @MainActor.
    By default SwiftUI implicitly marks the body property with @MainActor if I remember correctly, but not the whole struct.

    • @SwiftfulThinking
      @SwiftfulThinking  11 місяців тому +1

      I think that works but could cause other upstream initialization problems too

    • @tiam303
      @tiam303 11 місяців тому

      @@SwiftfulThinking Yes that @MainActor requirement will propagate upstream unfortunately.
      It's not a big issue at the moment because of a hidden feature of property-wrappers.
      But that's going to change in Swift 6 due to a recently accepted swift evolution proposal (SE-0401).

    • @alexvaiman4966
      @alexvaiman4966 10 місяців тому

      ​@@tiam303there is no problem or limitation mark @MainActor
      @Observable on the view model. and no not only the body, both body, and init method of any view must be on main thread, so I it is xcode bug, I think they will fix it in next version. for now you can mark the view init method to be @main actor, which is totally safe. also as i mentioned in another comment, I think all developers should start using the strict concurrency flag asap, many will discover many surprises once the set this flag to true...

    • @alexvaiman4966
      @alexvaiman4966 10 місяців тому

      @@SwiftfulThinkingin Uikit if I am not mistaken, you could not call init, on a view from out side main thread. in swiftUI it is not an error? in any case... if you are correct, then calling init on an view model, wich is main actor, from not inside main thread is an error in swift 6. aka "Main actor-isolated default value in a nonisolated context; this is an error in Swift 6 ", so you may decide that your view init will run or main actor, or you cannot init inside it a view model which is marked as @main actor...

  • @w0mblemania
    @w0mblemania 11 місяців тому

    Thank you for all your work on this. It's a very confusing topic, and Xcode's error messages really don't help provide the bigger picture.
    Just to clarify: we shouldn't decorate our data manager with both @MainActor and @Observable now, correct?
    I was doing just that, and then having to decorate the View with @MainActor as well, to shut up the errors.
    Also, another question: does decorating an object with @MainActor actually provide concurrency safety? Or just it just ensure that any values will be changed on the main thread?

    • @Spacer-l3j
      @Spacer-l3j 10 місяців тому

      for safety i'd recommend to use .task modifier instead of .onAppear { Task {} } modifier to avoid retain cycles

  • @shamnadpk-ft8ut
    @shamnadpk-ft8ut 11 місяців тому

    Thanks Nick ❤❤❤

  • @wonton120
    @wonton120 11 місяців тому

    Thanks for sharing.

  • @amir12184
    @amir12184 3 місяці тому

    Thanks so much for this playlist.
    Last time I coded for iOS was with swift 3, just came back and everything is different.
    Feels like speaking medieval English in the modern era.

  • @taylorchapman7860
    @taylorchapman7860 10 місяців тому

    Thanks Nick! I think using @Model provides similar concurrency behavior to @Observable macro and I've definitely got crashes by trying to update a swift data model off the main thread. However, I recall someone mentioning there's also a ModelActor that helps make changes to swift data objects safely? Have you used that actor before?

    • @SwiftfulThinking
      @SwiftfulThinking  10 місяців тому

      No, I haven’t but my guess is the concept is always the same. Update UI from the MainActor only

  • @HUNTELAAR11W
    @HUNTELAAR11W 10 місяців тому

    Thanks for the video!! How did you notice that it was not in the main thread?

  • @alexvaiman4966
    @alexvaiman4966 10 місяців тому

    hmmm... you missed a point, you will have a warning(even in compile time), if you set your swift concurrency checking from minimal, to "targeted". which I think all developers start doing asap, to get ready for swift 6.
    "In Swift 6 mode, all code will be checked completely for missing Sendable conformances and other concurrency violations, with mistakes generally diagnosed as errors. The -warn-concurrency flag will diagnose these violations as warnings in older language versions."