Giter Club home page Giter Club logo

asynclocationkit's Introduction

AsyncLocationKit

Swift Package Manager Swift Platforms

Wrapper for Apple CoreLocation framework with new Concurrency Model. No more delegate pattern or completion blocks.

Install


SPM
dependencies: [
    .package(url: "https://github.com/AsyncSwift/AsyncLocationKit.git", .upToNextMinor(from: "1.6.4"))
]

Cocoapods

pod 'AsyncLocationKit', :git => 'https://github.com/AsyncSwift/AsyncLocationKit.git', :tag => '1.6.4'

⚠️ Initialize AsyncLocationManager only synchronously on MainThread

import AsyncLocationKit

let asyncLocationManager = AsyncLocationManager(desiredAccuracy: .bestAccuracy)

let permission = await self.asyncLocationManager.requestAuthorizationWhenInUse() //returns CLAuthorizationStatus

You can use all methods from Apple CLLocationManager.

let coordinate = try await asyncLocationManager.requestLocation() //Request user location once

Start monitoring update of user location with AsyncStream.

for await locationUpdateEvent in await asyncLocationManager.startUpdatingLocation() {
    switch locationUpdateEvent {
    case .didUpdateLocations(let locations):
        // do something
    case .didFailWith(let error):
        // do something
    case .didPaused, .didResume: 
        break
    }
}

If Task was cancelled, Stream finished automaticaly.

asynclocationkit's People

Contributors

andrewdodd42 avatar elyesder avatar gre4ixin avatar humblehacker avatar intonarumori avatar romanpodymov avatar sunshiningsoo avatar tgmpaul avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

asynclocationkit's Issues

Region Monitoring

The below implementation is not invoking the print statements although the library is setup properly and working for the startUpdatingLocation().

Task{
            self.region = CLCircularRegion(center: location.coordinate, radius: 100, identifier: "DPMonitoredRegion")

                for await event in await asyncLocationManager.startMonitoring(for: region){
                    switch event{
                    case .didExitTo(let region):
                        print("did exit region \(region.identifier)")
                    case .didStartMonitoringFor(let region):
                        print("did start monitoring current region: \(region.identifier)")
                    case .monitoringDidFailFor(region: let region, error: let error):
                        print("region: \(String(describing: region?.identifier)), error: \(error.localizedDescription)")                        
                    case .didEnterTo(region: let region):
                        print("did enter to region \(region)")
                    }
}

I tried debugging and it somehow fails to enter the if statement in the AsyncDelegateProxy only when the RegionMonitoringPerformer calls it:

func eventForMethodInvoked(_ event: CoreLocationDelegateEvent) {
        for performer in performers {
            if performer.eventSupported(event) {
                performer.invokedMethod(event: event)
            }
        }
    }

thanks in advance

Crash on macOS

Hi,

I get a crash on macOS on the following line in AuthorizationPerformer.swift:

if await applicationStateMonitor.hasResignedActive {

changing it to the follow helps:

if let applicationStateMonitor, await applicationStateMonitor.hasResignedActive {

It seems as de delegate is called before

applicationStateMonitor = await ApplicationStateMonitor()

is completed in the start function.

Not sure why and not sure if my workaround is the best or have other side effects, but seems to work for me.

Can checkPermissions be public instead of private?

Discussed in #17

Originally posted by lmillett October 25, 2022
In my app I would like to check what location permissions have already been authorized before I ask them to grant me location permission. That way I'm not forced to ask for permissions before they have even used the app. I can delay it to a later point when they do an operation that really requires that authorization.

I have that change made locally to my package and it seems to work as I would like it to.

Happy to submit that change if others agree.

Cannot use framework in AppClip

Just by importing the library into my app Clip Target in Xcode I get the following error/warning when uploading to TestFlight/AppStore:

ITMS-90842: Invalid SDK usage - App clip 'BuildTarget_AC_Base.app/AppClips/BuildTarget_AppClip.app' uses the SDK selector 'requestAlwaysAuthorization', which is not supported. Ensure your app clip is using supported SDK features.

In the rest of my code I use a "#if APPCLIP" to skip code that reference API that are not allowed in AppClips. Is it possible to solve this in the framework as well?

Suggestion: Deal with AsyncLocationManager constructed in async code

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.

Support for WatchOS

Could you add support for WatchOS? Currently it is failing to build because of references to regions, beacons and visits that are note available on the Watch.

development branch

Hello.
Thank you for AsyncLocationKit.
Would you delete development? I see all pull requests are using main as target. Or what is the purpose of development?

Requesting Always authorization never returns in some circumstances

Steps:

  1. Starting with a clean app that has never requested location authorizations
  2. Request when-in-use authorization
  3. Tap "Allow Once"
  4. Request always authorization

Expected:

Always authorization request returns

Observed:

Always authorization request never returns, since the underlying call to CLLocationManager.requestAlwaysAuthorization() fails silently.

This one is tricky, as there's no straightforward way to tell the difference between when the uses taps Allow While Using App – which will allow a follow-on call to CLLocationManager.requestAlwaysAuthorization() – and Allow Once – which will not. I'm investigating this approach.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.