I have 2 apps on the app store with Tiles on the MS Band- (Band Time Tracker and Band List). Both of these suffer from the same issue: over time the connection to the band is lost, events generated in the Band do not trigger code execution on the app.
What types of mitigating strategies can I use to ensure that events always trigger code execution on the phone?
Right now the only thing I have included is haptic feedback to notify the user that the event was accepted.
Related
I am reading through the documentation for the Apple HealthKit and am stuck on understanding the difference between a query being registered for background deliveries vs. running on the background. This excerpt from the explanation of anchored object queries seems to differentiate between the two:
Anchored object query. In addition to returning the current snapshot of modified data, an anchored object query can act as a long-running query. If enabled, it continues to run in the background, providing updates as matching samples are added to or removed from the store. Unlike the observer query, these updates include a list of items that have been added or removed; however, anchored object queries cannot be registered for background delivery.
Source: https://developer.apple.com/documentation/healthkit/reading_data_from_healthkit
I am confused about the difference between the two types of "backgrounds." Does the statement "continues to run in the background" really mean "when the app is in the foreground, this query will continue to run without needing to be re-called?"
Background Delivery works like background app refresh, or GPS significant location change events. It wakes up your app to allow you to act on some event. In this case whenever a health sample you are listening for, is added to the store, your app is woken up (once within a given interval) in order to be able to process the event.
Think of a running/cycling app, where a user is trying to tracking their progress on a long workout. The app won't remain open the whole time, but you can ask for the number of steps every X interval so that you can keep your UI updated, or in sync with a server.
More info on background delivery: https://developer.apple.com/documentation/healthkit/hkhealthstore/1614175-enablebackgrounddelivery
The other reference to background, means that it continues to run in another thread, while the app is open. So if you query for heart rate, you can be notified every time a reading comes in, as opposed to just receiving 1 result and having to check every X seconds for a new one
The app I worked on got an alert from apple wallet: "Some passes are receiving too many updates, which may affect battery life. Automatic updates for *** passes will be disabled. Choose RE-enable if you want automatic updates to continue." I only have 2 passes in the wallet from that app.
Does anyone know what's the reason trigger this alert? If we send 2 push notifications within 5 seconds, will that trigger this kind of alert?
It means pretty much what it says. Apple is respectful of user's battery life and data consumption and recognises that a pass update is a high energy activity that the user has little control over, and so if a pass issuer makes too many updates, then iOS takes action to alert the device owner so they can choose if they would like to continue to receive these updates (at the expense of reduced battery life).
Apple's previous policy was to silently throttle updates, but this led to problems, since users were unaware that they were being throttled and would wonder why their passes were not updating.
Apple recognises that developers may need to push content more frequently, which is why you can disable rate limiting on your device via the developer menu (that appears when you have your iPhone hooked up to Xcode).
Apple doesn't publish the criteria that it uses to throttle, and normally a quick burst of activity (E.g. a one-off burst of 2 or 3 messages in the space of a few minutes) would be tolerated. But if the issuer is sending dozens of messages every few minutes, then you can almost certainly expect they will see this message.
I'm using Plot Projects service to send geofencing notifications to users of iOS and Android application.
I want to use "dwelling" event to trigger specific notifications when user remains at one specific geofence for some extended time. The documentation states that dwelling event can be used on iOS, but has certain specifics:
Please note that due to restrictions in iOS the notification filter for dwelling notifications is called when the user enters the geofence or beacon region and that the returned notifications are only shown when the user remains in the region for the specified amount of time.
By my understanding, this would mean that the Notification filter gets triggered as soon as user enters the geofence, but the notification, if properly filtered, will be displayed after user dwells there. Filtering logic in my case is done on server-side - iOS app sends notification info to server, and then appropriate logic is applied to decide whether to show notification or not.
So, server-side logic for checking whether to show notification or not would be triggered at the time user trips geofence, but the notification would be shown to the user once he dwells there for some time. In my specific case, in order to properly decide whether to show the notification or not, I'd need the check to be done at the time the user really dwells, and not on entering. My understanding is that this cannot be done on iOS (unlike Android).
Am I right to assume this? If not, what would be the way to achieve a dwell-time filtering check, as opposed to enter-time filtering check?
You're correct about the moment when the Notification Filter will trigger on iOS. This is done because of platform limitations. The filter will be called directly when you enter the geofence. When you want filter out messages, that is indeed the time to do so. There is no way to filter at the time of the end of the dwelling period.
This, as mentioned, differs from the behaviour on Android. There it will be called at the end of the dwelling period.
I am using the Socket iOS SDK with the 7Xi scanner. The scanner is fast enough to register duplicate scans in quick succession if a user holds a barcode in front of the scanner when in stand mode. To handle this, I am simply removing my scan delegate when the first scan arrives, and not setting it again until I am ready for the next scan.
Of course, the scanner itself continues scanning. Is there some way to silence the beep while I am handling the scan, so that my users don't think the scan was correctly received when the app does not. It must be fast enough that I can reliably re-enable it within a second or so.
Background
The scanner has three confirmation modes (device, sdk and app) which determines who is responsible for acknowledging a barcode was scanned. The default is device, which will acknowledge any successful scan (i.e. the barcode type is supported and the device successfully decoded the barcode).
Solutions
Option 1
Currently, you remove the scan delegate, which doesn't prevent the scanner from scanning the next barcode; It only prevents your application from receiving the event notification. You provide ScanApiHelper with a timer routine that calls doReceive to check for new events and if it finds one it calls your delegate.
You could add a flag to your timer so that it will only call doReceive when you are ready to handle the next event.
There are two limitations to this approach. There will be a delay between the device acknowledgement and feedback from the application, if important feedback is provided, when a scan is held in the queue. Second, a queue is only suitable for handling a brief burst of activity, but your application will require downtime to catch back up.
Option 2
Caveat: I'm not sure if this works in presentation mode
Switch the confirmation mode to app and have your application acknowledge the barcode after it is done processing. This has the benefit of essentially locking out the scanner (it won't beep, flash or vibrate for any scan) unless your application has received and handled the barcode.
The downside here is there is a small lag between the barcode being read and the scanner acknowledging it, when using app confirmation mode. Adding an additional delay while processing the data may not be the best user experience.
We are working in a groupon-like app where alerts are displayed to the user when he/she enters in the range of an offer.
The client insists on having alerts even when the app is in the background.
Due to the architecture of the system, the app gets the location of the client at intervals and checks with the server if there is any new alert. If so, the app does some processing in the local database and displays a notification.
APN cannot be used since changes in the server are out of reach for this project.
My question is whether Apple would accept it in AppleStore as I have read different opinions about it and Apple discourages its use as in this extract from iOS Developer Library
http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html
At wake-up time, your app is put into the background and given a small amount of time to process the location data. Because your app is in the background, it should do minimal work and avoid any tasks (such as querying the network) that might prevent it from returning before the allocated time expires. If it does not, your app may be terminated
Thanks
How often does your app get location from the user? According to Apple's Background Execution and Multitasking, if you are getting the location updates on a regular schedule (I think it's less than 10 minutes), your app can still process in the background if you add location to UIBackgroundModes in your info.plist. With those CLLocation coordinates, you can then process your web service requests.
I personally have not done something like this, so I can't tell you for sure if Apple will reject your app or not. However, if everything is within the guideline and requirements set by Apple, I don't see why they would reject your app.
EDIT:
From the Apple doc:
An app that provides continuous location updates to the user (even
when in the background) can enable background location services by
including the UIBackgroundModes key (with the location value) in its
Info.plist file. The inclusion of this value in the UIBackgroundModes
key does not preclude the system from suspending the app, but it does
tell the system that it should wake up the app whenever there is new
location data to deliver. Thus, this key effectively lets the app run
in the background to process location updates whenever they occur.
I guess even if the app is suspended, it will wake up whenever there is a new location data to deliver.
I think you should reconsider your approach for this application. It sounds like you have decided to build a set of features which are not necessarily well informed by, or a good fit for, the characteristics of the devices the app will run on.
You write that "the app gets the location every n minutes" but that's not how iOS location services work. Querying location services for the current location occasionally is a good approach when your app is running in the foreground but that's not an option once it is suspended or terminated. Instead you need to subscribe to location events, at some level of accuracy, and your app will be notified when the device's location changes. There are no guarantees about the schedule on which you receive these events and it varies depending on the accuracy you request and the speed at which the device is moving.
Additionally, obtaining a location is an expensive operation and can quickly drain the device's battery. Burning through a user's available battery power in an hour or two is a very good way to get your app uninstalled quickly. Where possible you should be using the significant location change service to get low accuracy location updates with minimal power consumption. If you need more precision then consider using boundary crossing events for a defined region or at least reduce the accuracy your have requested as much as possible.
With all that out of the way you still need to work within the limited time your app has to run once started by a location update. That's probably not long enough to make a round trip to the server. If a network connection is already active and the device happens to have low latency you will probably get a response some of the time but I would expect to see the app terminated by the OS frequently. When that happens I don't know that you will continue to receive location updates which might otherwise re-launch the app.
Instead of downloading a list of alerts and displaying them locally a better solution might be to attempt to send your current location to the server via UDP when you see a significant location change. That way you can fire off a network request without waiting for a response. Only some of those requests will still succeed but at least your app won't be terminated. You can then process the locations you receive on the server and send push notifications when appropriate.
I realize that you don't seem to be able to make server side changes. In that case the best you might be able to do is pre-fetch alerts for the nearby region when the app runs (and if you ever manage to complete a round-trip while in the background). That way you could compare location updates to that list and not need to fire off a network request on every location update. Unfortunately it sounds like you might be backed into a corner here with no reliable solution available under your current constraints.