Coder Social home page Coder Social logo

rxswiftcommunity / rxcorelocation Goto Github PK

View Code? Open in Web Editor NEW
181.0 12.0 83.0 12.59 MB

RxCoreLocation is a reactive abstraction to manage Core Location.

Home Page: https://github.com/RxSwiftCommunity/RxCoreLocation

License: MIT License

Swift 97.06% Ruby 1.80% Objective-C 1.14%
rxcorelocation rxswift corelocation cllocationmanager placemark location swift

rxcorelocation's People

Contributors

bobgodwinx avatar farshadtx avatar goos avatar hallee avatar jdisho avatar juliancadi avatar krezzoid avatar marcammann avatar newoo avatar nitikorndev avatar rafaelplantard 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rxcorelocation's Issues

Possible "memory effect" on .rx.location

Hi,

I am using several instances of CLLocationManager (configured slightly differently) potentially at the same time and scoped to dedicated Rx streams (for each, I initiate a new CLLocationManager() that I specifically configure, then I call startUpdatingLocation() at stream's subscription, and I call stopUpdatingLocation() at the disposal) returning what the RxCoreLocation extension .rx.location provides me in the meantime.

In this context, I have, among other things, one method that returns to me an Observable<CLLocation> every second (distanceFilter == kCLDistanceFilterNone) and another every 30m traveled (distanceFilter == 30).
In a very specific case, I noticed a kind of "memory effect" (without fully understanding it yet) when I subscribed to a new 30m stream it returned to me all the data of the last 1Hz stream that I disposed, a few seconds before. It's very strange.

Is this strange behaviour possible there?

public var location: Observable<CLLocation?> 
    let updatedLocation = self.didUpdateLocations.map { $1.last } // <--- possible memory effect here?
    let location =  self.observe(CLLocation.self, .location)
    return Observable.of(location, updatedLocation).merge()
}

Thanks

Testing rx.placemark

I have this GeolocationService:

import CoreLocation

import RxSwift
import RxCoreLocation

class GeolocationService: NSObject {

  var locationManager: CLLocationManager!

  var currentPlacemark: CLPlacemark?
  var currentLocation: CLLocation? {
    return currentPlacemark?.location
  }

  var disposeBag = DisposeBag()

  convenience init(withLocationManager loc: CLLocationManager) {
    self.init()
    locationManager = loc
    locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()

    locationManager.rx.placemark.subscribe(onNext: { [unowned self] placemark in
      self.currentPlacemark = placemark
    }).disposed(by: disposeBag)
  }

  deinit {
    locationManager.stopUpdatingLocation()
  }

  func getCurrentLocation() -> (latitude: Double, longitude: Double)? {
    guard let lat = currentLocation?.coordinate.latitude,
      let lon = currentLocation?.coordinate.longitude else { return nil }
    return (latitude: lat, longitude: lon)
  }

  func getCurrentAddress() -> Address? {
    guard let cPlacemark = currentPlacemark else { return nil}

    let address = Address(street: cPlacemark.name, zipCode: cPlacemark.postalCode, city: cPlacemark.locality, country: cPlacemark.country)

    return address
  }
}

Despite any design flaw it's working properly.
My question is, how can I unit test the placemark subscription?
Due to this dependency any other method's test would be trivial if I could just be able to test the subscription.

Looking forward for any thoughts, thanks in advance!

Documentation

Required

A human readable documentation explaining how CLLocationManager works and how to use the RxCoreLocation in solving specific need where applicable.

Circle CI

Required

Configure repo to use Circle CI verify and make sure it builds on every PR

PlaceMark and address

Required

In implementation to return the user's current or location Placemark automatically when location is updated.
The ideal type here will be CLPacemark property which also contains the address of the updated CLLocation

Same observer for UNUserNotificationCenter

It is a great library thank you.
I'm trying to observe UNUserNotificationCenter authorization status but I could not find a similar thing like this.
If you consider building such a thing, that'd be awesome.

Failure converting from Optional(<...>) to CLLocationManagerDelegate

Hi,

first of all thank you for maintaining this library ๐Ÿ™

We have been using RxCoreLocation for some time now and every then and now we see this crash:

Fatal error: Failure converting from Optional(<GjlTsjYFHdNgFERt: 0x282062300>) to CLLocationManagerDelegate: file RxCocoa/RxCocoa.swift, line 153

At first we saw that users that crashed had jailbroken devices so immediate though was that they are just messing with location manger. However, more recently we received few crashes that happened on devices that were not jailbroken i.e.:

Fatal error: Failure converting from Optional(<GjlTsjYFHdNgFERt: 0x280045400>) to CLLocationManagerDelegate: file RxCocoa/RxCocoa.swift, line 153.

We are not doing anything magical apart from subscribing to didChangeAuthorization, didUpdateLocations.

This is affecting only super small fraction of our users, but nevertheless it is interesting why this could happen. Perhaps you have any insights?

Retrieve wrapper around CLGeocoder?

I noticed, with the current implementation, all the placemark methods internally create an instance of CLGeocoder.

I would like to ask, what is your opinion on exposing them publicly, and putting a Reactive extension on CLGeocoder?
I don't mind doing it myself, so long as the idea gets approved.

Benefits would be that you can do reverse geocoding on any CLLocation, not just the user's current location.

CoreLocation service implementation issue.

Hi @here I am trying to make a CoreLocation service around this library. I have added a method that return a Single of user position. Here is my current implementation:

class CoreLocationService: LocationService {

    private let locationManager: CLLocationManager
    private let disposeBag = DisposeBag()

    init(locationManager: CLLocationManager) {
        self.locationManager = locationManager
    }

    public func requestLocation() -> Single<CLLocationCoordinate2D> {
        return Single.deferred {
            return Observable.create { [unowned self] (observer) in
                let locationError = self.locationManager
                    .rx
                    .didError
                    .subscribe( onNext: { (_, error) in
                        observer.onError(error)
                    })

                let location = self.locationManager
                    .rx
                    .didUpdateLocations
                    .filter { $1.count > 0 }
                    .map { $1.last!.coordinate }
                    .subscribe(observer)

                self.locationManager.requestLocation()

                let cancel = Disposables.create(with: {
                    self.locationManager.stopUpdatingLocation()
                })

                return CompositeDisposable(cancel, locationError, location)
            }.take(1).asSingle()
        }
    }
}

How can I ensure in this implementation that the subscription on the .didError stream is done before invocation self.locationManager.requestLocation(). This is currently not happening in this implementation and I keep getting this error message on run time as a result: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Delegate must respond to locationManager:didUpdateLocations:

Observables does not send updated value when app enters foreground

Our app requires the user to allow access to the devices location.
To handle this we first check if the location service is enabled, if it's not enabled we present a view controller letting the user know that he / she needs to enable the location service to continue.
The user would then most likely put the app in the background, enable the location service, open the app again.

In the view we present to the user when location service is disabled, we would like to automatically detect if the location service has been enabled, the code below is our attempt to react to the isEnabled event.

viewDidLoad() {
  super.viewDidLoad()
  manager.rx
    .isEnabled
    .debug("isEnabled")
    .subscribe(onNext: { isEnabled in
      if isEnabled {
        DispatchQueue.main.async {
          self.dismiss(animated: true, completion: nil)
        }
      }
    })
    .disposed(by: bag)
}

When we test this by putting the app in the background then to foreground, no event is triggered.

Is this something the library is designed to handle?

If not, how would one go about creating this functionality in an app?

didReceiveRegion available for iOS 9.3 in RxCoreLocation 1.3.2

Hi,
I was working with a native CoreLocation implementation for a geofencing feature and now I'm moving everything to RxSwift.
It was working just fine before, my project's deployment target is iOS 9.0, but I don't understand why the API below is marked for iOS 9.3 or above if the three CoreLocation methods that is using are available from iOS 4.0/5.0.

    @available(iOS 9.3, OSX 10.11, *)
    public var didReceiveRegion: RxCocoa.ControlEvent<CLRegionEvent> { get }

Could this be an issue?
Thank you!

Why RxSwift Repo Example implement different?

RxExample

import CoreLocation
import RxSwift
import RxCocoa

extension CLLocationManager: HasDelegate {
    public typealias Delegate = CLLocationManagerDelegate
}

public class RxCLLocationManagerDelegateProxy
    : DelegateProxy<CLLocationManager, CLLocationManagerDelegate>
    , DelegateProxyType
    , CLLocationManagerDelegate {

    public init(locationManager: CLLocationManager) {
        super.init(parentObject: locationManager, delegateProxy: RxCLLocationManagerDelegateProxy.self)
    }

    public static func registerKnownImplementations() {
        self.register { RxCLLocationManagerDelegateProxy(locationManager: $0) }
    }

    internal lazy var didUpdateLocationsSubject = PublishSubject<[CLLocation]>()
    internal lazy var didFailWithErrorSubject = PublishSubject<Error>()

    public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        _forwardToDelegate?.locationManager?(manager, didUpdateLocations: locations)
        didUpdateLocationsSubject.onNext(locations)
    }

    public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        _forwardToDelegate?.locationManager?(manager, didFailWithError: error)
        didFailWithErrorSubject.onNext(error)
    }

    deinit {
        self.didUpdateLocationsSubject.on(.completed)
        self.didFailWithErrorSubject.on(.completed)
    }
}

Carthage failed

Tested on "master" and 1.5.1
carthage update --use-xcframeworks --platform iOS

This usually indicates that project itself failed to compile.

./Carthage/Checkouts/RxCoreLocation/Sources/Helpers.swift:10:12: error: no such module 'RxSwift'
    import RxSwift
           ^
/var/folders/jk/yh46dz450lg28bywvt4jyslm0000gn/T/carthage-xcframework-SxNw/RxCocoa.framework/Modules/RxCocoa.swiftmodule/arm64-apple-ios.swiftinterface:7:8: error: no such module 'RxCocoaRuntime'
import RxCocoaRuntime
       ^
/var/folders/jk/yh46dz450lg28bywvt4jyslm0000gn/T/carthage-xcframework-SxNw/RxCocoa.framework/Modules/RxCocoa.swiftmodule/arm64-apple-ios.swiftinterface:7:8: error: no such module 'RxCocoaRuntime'
import RxCocoaRuntime
       ^
/var/folders/jk/yh46dz450lg28bywvt4jyslm0000gn/T/carthage-xcframework-SxNw/RxCocoa.framework/Modules/RxCocoa.swiftmodule/arm64-apple-ios.swiftinterface:7:8: error: no such module 'RxCocoaRuntime'
import RxCocoaRuntime
       ^
/var/folders/jk/yh46dz450lg28bywvt4jyslm0000gn/T/carthage-xcframework-SxNw/RxCocoa.framework/Modules/RxCocoa.swiftmodule/arm64-apple-ios.swiftinterface:7:8: error: no such module 'RxCocoaRuntime'
import RxCocoaRuntime

When I want to get the placemark once, the console prints the warning.

when i execute the code:
manager.rx.placemark.take(1).subscribe()

the console prints the warning:

โš ๏ธ Reentrancy anomaly was detected.
  > Debugging: To debug this issue you can set a breakpoint in /Users/huangqc/Library/Developer/Xcode/DerivedData/HiNen-cpfnagrkwcupnlcdabhuytikjqaf/SourcePackages/checkouts/RxSwift/Sources/RxSwift/Rx.swift:96 and observe the call stack.
  > Problem: This behavior is breaking the observable sequence grammar. `next (error | completed)?`
    This behavior breaks the grammar because there is overlapping between sequence events.
    Observable sequence is trying to send an event before sending of previous event has finished.
  > Interpretation: This could mean that there is some kind of unexpected cyclic dependency in your code,
    or that the system is not behaving in the expected way.
  > Remedy: If this is the expected behavior this message can be suppressed by adding `.observe(on:MainScheduler.asyncInstance)`
    or by enqueuing sequence events in some other way.

โš ๏ธ Reentrancy anomaly was detected.
  > Debugging: To debug this issue you can set a breakpoint in /Users/huangqc/Library/Developer/Xcode/DerivedData/HiNen-cpfnagrkwcupnlcdabhuytikjqaf/SourcePackages/checkouts/RxSwift/Sources/RxSwift/Rx.swift:96 and observe the call stack.
  > Problem: This behavior is breaking the observable sequence grammar. `next (error | completed)?`
    This behavior breaks the grammar because there is overlapping between sequence events.
    Observable sequence is trying to send an event before sending of previous event has finished.
  > Interpretation: This could mean that there is some kind of unexpected cyclic dependency in your code,
    or that the system is not behaving in the expected way.
  > Remedy: If this is the expected behavior this message can be suppressed by adding `.observe(on:MainScheduler.asyncInstance)`
    or by enqueuing sequence events in some other way.

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.