You're probably struggling with Swift Concurrency, I definitely was, especially when you turn on Strict Concurrency Checking. So Tom and I shared our learnings in a talk on AppDevCon last week.

Read on for the gist on how you can approach Swift Concurrency without going crazy.

First of, WWDC videos (new and old), and content creators like Donny, Matt and Antoine create awesome content. Make sure to read up with that first to get to know the principles and how all this concurrency stuff works.
Once you get the easy issues out of the way, you'll probably hit the more complex app logic, libraries and APIs using closures, dispatch queues, you probably have entangled state. This all might make it hard to apply the basic fixes, they only give you more errors.
Often this is because you try to introduce actors or make things Sendable. It's fine to use actors to protect shared mutable state.
However often you don't want (and also shouldn't) make state shared and mutable. You're just trying to make a compiler issue go away, actors are hardly ever the right tool to use. You're first response should be whether it can just live on the MainActor instead, much easier fix!
The async/await nature of an actor and Sendable requirements have a huge impact on your codebase. So even if you have shared mutable state an actor is sometimes impractical. Learn about Swift Mutex as different tool that can also do the job if you must share state over domains.
Also; Keep the complexity of shared mutable state and Sendables contained as much as you can. Don't respond to compiler issues by making more types Sendable. See if you can contain it as much as possible. Most types shouldn't be more complex then being nonisolated(nonsending).
If you have mutable stated, shared over isolation domains that can't live on the MainActor and you can await to access it. Actors might be a good option. Then they also have cool tricks, like using DispatchQueue which makes it easy to use queue based APIs
Or if you have a big part of your app that works together on state, but can't be on the MainActor. Then you can make your own Global Actor, that removes the requirement to write one big actor. Enabling to split up your code.
But once again, think twice before using an actor (or even a mutex). It's so much simpler to see if you can have that state live on the MainActor. It's so much more often possible then you might think, even if the work is heavy the state change can happen on main.
Use the power tools when you know you need them, but not just because they're there. I've made that mistake over and over again, but always ended up so much happier with the simple solution in the SDK I'm working on and our app Bezel.