Indoor location with Swift 3, iOS 10 and iPhone 7

Does the indoor location API work with the iPhone 7 / iOS 10 / Swift 3?

I set up a small demo program, but after starting the location manager (startPositionUpdates(for:) no location updates are ever delivered, nor are any errors delivered (didUpdatePosition and didFailToUpdatePositionWithError are never called).

Below is a small minimal example which shows this behaviour. info.plist has both “Privacy - Location Always Usage Description” and the permission for location in background mode set). This is a small class which is initialized and started from the AppDelegate.

let locactionManager = EILIndoorLocationManager()
var location : EILLocation

//MARK: Event handling
func indoorLocationManager(_ manager: EILIndoorLocationManager, didUpdatePosition position: EILOrientedPoint, with positionAccuracy: EILPositionAccuracy, in location: EILLocation) {
    NSLog("retrieved location")
}

func indoorLocationManager(_ manager: EILIndoorLocationManager, didFailToUpdatePositionWithError error: Error) {
    NSLog("error")
}

//MARK: life cycle
func startUpdates() {
    NSLog("Started location updates")
    self.locactionManager.delegate = self
    self.locactionManager.startPositionUpdates(for: self.location)
}

func stopUpdates() {
    NSLog("Stopped location updates")
    self.locactionManager.stopPositionUpdates()
}

func init() { //code that sets up self.location
}

I run this code on an iPhone 7, running iOS 10 and it is compiled as Swift 3. Are any of these not supported? Or am I missing something else?

1 Like

Hey :wink:

To make sure we just tested it by creating a simple app using Swift 3 with iOS 10.0 as base SDK and run it on iPhone 7. It worked just fine. Could you paste the part of the code from AppDelegate where you create the instance of this small class and call startUpdates? Maybe accidentally you declared an instance of that class inside one of AppDelegate methods and it gets deallocated before the first location update comes.

Hi,

Thank you for your reply! Below the code from my AppDelegate, thanks for your help!

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    
    let locationService = LocationService(location: nil)

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        locationService.startUpdates()
        return true
    }

}

Here LocationManager is the class mentioned above.

Could you perhaps share the simple example-app? Then I can make sure everything works in our local setup.

I added the an authorisation request to the didFinishLaunchingWithOptions: method, which seems to have fixed the issue, for the first launch of the app:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let beaconManager = ESTBeaconManager() //only for asking permission
    beaconManager.requestAlwaysAuthorization() 
    [...] //start the location service and return True
 }

However, after first launch of the app, the app never manages to connect to the location. Removing the app and then starting a new session through XCode then has working location updates for that launch. But after stopping and starting the session again, no more update come in, and the app has to be removed again to get location updates. Is this a known issue? What could be done to overcome this?

Also, one other issue. As discussed with one of your colleagues at Indoor location on locked device (iOS) the new Beacons should work when the device is locked. However, when locking the device, the stream of location updates seems to stop. As stated, the app as permission to always use the location services and has location updates listed as a required background mode in info.plist. What else should be done to enable location updates in the background, or is this linked to the other problem?

So TL;DR of our problems:

  1. Indoor location only works the first time the app is launched
  2. When indoor location works, no location is reported when the phone is locked.

Hi Gzegorz,

Could you perhaps take a look at my above post? Thanks in advance,

Pim Jager

Hi,

  1. You don’t have to call any of the ESTBeaconManager methods to use IndoorSDK functionality. I’m sending you a link to the simple app I mentioned before. Just insert you appID, appToken and the identifier of your location and check how it behaves. It should log position updates each time it’s in foreground.
  1. Right now background updates are only available with the IndoorLocation app from AppStore.
    https://itunes.apple.com/us/app/estimote-indoor-location/id963704810?mt=8

Hi Gregorz,

Thank you for sharing the test app. The difference was in the EILIndoorLocationManagerMode, by setting this to .Light our app works as well. However our app does not work with .Normal, and neither does the test app you provided (just by removing the .mode = .Light line). They both then do not provide location updates, or if they do they only do so on first launch, as I described above.
Is this a bug in the Estimote SDK, or is Normal mode not properly supported on iPhone 7 / iOS 10?

Thank you in advance for your reply.

Pim

Pim,

Normal mode uses other sensors not only Bluetooth. If some of those sensors could not be initalized it won’t provide location updates - the usual suspect is the magnetometer. Is the method indoorLocationManager:didFailToUpdatePositionWithError: being called with any error?

Hi Marcin,

Thank you for your fast reply!

indoorLocationManager:didFailToUpdatePositionWithError: is not called. I tried this in the test app you provided by removing the line which sets the mode to Light (line 16 (I believe) in ViewController.swift).
Neither of the two indoorLocationManager delegate functions are called.

What I find odd is that on very rare launches, the SDK works correctly and location updates are provided. However, this is only in very rare instances, most launches, providing the updates fails.

Is there something else I can try, or some way I can help you to asses this bug?

Hi,
We tested once again if positioning starts, this time on iOS 10.1 using iPhone 6 and it worked fine for both Light and Normal modes. Sometimes it took around 30 sec for the first position update to come. We will try once again on iPhone 7 on Wednesday and provide you with some possible solutions or more debug ideas.

Regards,
Greg

Dear Greg,

Did you check with the iPhone 7? We have sadly net yet managed to resolve the issue.

Kind regards,
Pim

Hi,
We just released a new version of our Indoor SDK (2.3.0). Just to make sure, did you try updating your app to the newest version of our SDK? Also, are you sure that you don’t have battery saving mode enabled? It may cause much bigger delays in position updates as the CPU is throttled down.
We are currently working on solving couple of issues related to iOS 10.1 but none of them resembles the situation you described.
To help us solve your issue, can you please open the Console app on Mac before starting your app and look for any weird (Bluetooth related) logs from your iPhone.

Greg

Dear Greg,

Thank you for your reply and for checking! I am sadly not in the office this week, but will do a double check on the version of the SDK next week.

When do you expect to release the next version of the SDK? (is there some sort of RSS or other service to receive notifications of this? We sadly can not use pods in our project).

Pim

You can got to GitHub - Estimote/iOS-Indoor-SDK: Estimote Indoor SDK for iOS, log in with your GitHub account, and click the “Watch” button. You’ll then get an email when there’s a new release.

Good Day, I am experiencing some issues as well. I tried using the dropbox link to download your sample app, however it does not exist. If possible can you provide a link for your app :slight_smile:

Hi Nicholas!

Since we released few updates to our SDK that project is no longer available.

Could you post what problems did you encounter so we can help you? :slight_smile: