Skip to content

Suggestion: Deal with AsyncLocationManager constructed in async code #11

@tcobbs-bentley

Description

@tcobbs-bentley

I have existing code based on PromiseKit that I am migrating to Swift Concurrency, and in migrating it to use AsyncLocationKit, my actual sequence of events differed from your sample code in the README.md. Because of this, I created an AsyncLocationManager instance inside an async function, it didn't work at all, due to that fact that AsyncLocationManager's initializer creates a CLLocationManager without first switching to the main thread. It took me a long time to figure out what was wrong. Because of this, I would suggest that AsyncLocationKit do one or more of the following:

  1. Include text in the main README.md stating that when an instance of AsyncLocationManager is created, that must happen in a thread with an active RunLoop (probably the main thread). Side note on this: a globally initialized AsyncLocationManager doesn't work (I'm guessing because it is initialized before the main thread's RunLoop is created).
  2. Include a check inside AsyncLocationManager.init that throws an exception if there isn't an active RunLoop on the current thread. (I don't actually know how to check this, since RunLoop.current will create an inactive RunLoop on the current thread when called on a thread with no RunLoop.)
  3. Update the first line of AsyncLocationManager.init to be wrapped in a call to DispatchQueue.main.sync() if it is called from anything other than the main thread. (Note: calling DispatchQueue.main.sync() on the main thread will result in deadlock, so this would need to check Thread.isMainThread.)
  4. Add DocC-compatible documentation to the library and make sure the documentation for AsyncLocationManager.init and AsyncLocationManager.init(desiredAccuracy:) states the fact that they must be called from a thread with a RunLoop.

In short, given that AsyncLocationManager is designed to be used from async code, the fact that it must be constructed outside of async code is something that I feel should be either mentioned in the documentation, or corrected to not be the case. I realize that CLLocationManager itself makes it clear in its main class documentation that there must be a RunLoop at the time of initialization. But it is not at all clear (to me, anyway) that the same is also true of AsyncLocationManager, and AsyncLocationManager's very nature of being used with async code makes it much more likely to be created from an async function.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions