I have location services working in iOS8.
It is set for kCLLocationAccuracyBest using startMonitoringSignificantLocationChanges to restart when in the background and startUpdatingLocation for accuracy.
When I set pausesLocationUpdatesAutomatically = YES, the location services get paused and resumed as expected. However, the following call to didUpdateLocations: only has one location in it.
I was expecting to receive a bunch of locations that were received by the OS while the delivery was paused. Am I missing something here? Does it have anything to do with deferredLocationUpdatesAvailable?
This answer talks about a post on Apple Dev Forum, but I get nothing when searching for pausesLocationUpdatesAutomatically.
Please note: this issue has nothing to do with calling requestAlwaysAuthorization or setting prompts in info.plist.
Further to the answer by Quentin Hayot...
The documentation for pausesLocationUpdatesAutomatically states:
Allowing the location manager to pause updates can improve battery life on the target device without sacrificing location data.
This is highly misleading.
What it really means is when location manager pauses it will sacrifice location data: the app does not get and never will get location updates until the location manager resumes.
It should explain that paused location updates are completely different from deferred location updates.
To improve battery life, the app should call allowDeferredLocationUpdatesUntilTraveled:timeout: which does deliver all location updates gathered while deferring to locationManager:didUpdateLocations:.
The documentation for locationManager:didUpdateLocations: states:
If updates were deferred or if multiple locations arrived before they could be delivered, the array may contain additional entries.
which is reasonably clear, but it could state that it has nothing to do with, and should not be confused with, pausesLocationUpdatesAutomatically.
When you pause the location updates, the system considers that you don't need the location for now. Resuming it will only give you the current location.
This is a normal behavior.
Related
When trying to send a push alert through Parse.com, I came across the following warning:
Installations without a known timezone will not receive this campaign.
So, how do I make sure Parse knows a user's timezones? Is there any specific code, or does it to that without the need for code/by default, and this is a moot question?
Thanks!
This is recorded on a per-Installation basis by the Parse library, and should be automatically updated whenever it is updated by the client.
You can verify that Parse is saving time zones by logging into your account, selecting 'Core' (at top) and 'Installation' (at left). You'll see a list of all current installations - the relevant column is timeZone.
The notice that you see when attempting to send a push is just a general reminder, not an indication that there is necessarily anything wrong on your end.
UPDATE 3/1/2015:
I found a bug in this, BTW, that some people might run into. So I'm posting it here in case it might help somebody.
In the current version of Parse, there is a bug wherein an iOS device with their Date & Time "Set Automatically" setting disabled will (potentially) return a timeZone that Parse won't understand. In such an event, local-time scheduled push notifications will not be sent to a user with that setting turned off.
I verified this, myself, on two devices. With "Set Automatically" turned on the Parse Installation is set to "America/Los Angeles" (which is accurate for me). With it turned off, it sets it to "US/Pacific". This is still accurate, obviously, but for some reason Parse does not like that value.
I imagine there are a non-trivial number of iOS users with that setting disabled, so I hope Parse fixes this.
Sorry if this one's a bit of a stupid question.
I'm currently building an iOS app which needs to be able to have (or acquire) the user's location when a push notification is received, potentially waking up the app. Previously, I was just monitoring significant location changes, updating a property as locations were received, using the last acquired location when the push notification is received (the location doesn't need to be very accurate, within 0.5-1.0 km will suffice).
However, with the highly annoying changes to location permissions in iOS8, this now requires 'always' authorisation - which repeatedly prompts the user about the access, greatly increasing the chances it will be turned off altogether. So my question is basically twofold. Will 'when in use' authorisation allow the location to be accessed even when the app is in the background, woken up by a push notification? And if it will, is there anything special I need to do to get the location - for example, wait a few seconds for the GPS to acquire a position, or make a call to enable location monitoring?
I have an app which needs almost no user interaction, but requires Geofences. Can I run this entirely within a background service?
There will be an Activity when the service is first run. This Activity will start a service and register a BroadcastReceiver for BOOT_COMPLETED, so the service will start at boot. It's unlikely that this Activity will ever be run again.
The service will set an Alarm to go off periodically, which will cause an IntentService to download a list of locations from the network. This IntentService will then set up Geofences around those locations, and create PendingIntents which will fire when the locations are approached. In turn, those PendingIntents will cause another IntentService to take some action.
All this needs to happen in the background, with no user interaction apart from starting the Activity for the first time after installation. Hence, the Activity will not interact with LocationClient or any location services.
I've actually got this set up with proximityAlerts, but wish to move to the new Geofencing API for battery life reasons. However, I have heard that there can be a few problems with using LocationClient from within a service. Specifically, what I've heard (sorry, no references, just hearsay claims):
location client relies on ui availability for error handling
when called from background thread, LocationClient.connect() assumes that it is called from main ui thread (or other thread with event looper), so connection callback is never called, if we call this method from service running in background thread
When I've investigated, I can't see any reason why this would be the case, or why it would stop my doing what I want. I was hoping it would be almost a drop-in replacement for proximityAlerts...
Can anyone shed some light on things here?
The best thing would be to just try it out, right? Your strategy seems sound.
when called from background thread, LocationClient.connect() assumes that it is called from main ui thread (or other thread with event looper), so connection callback is never called, if we call this method from service running in background thread.
I know this to be not true. I have a Service that is started from an Activity, and the connection callback is called.
I dont know about proximity alerts; but I cant seem to find an API to list my GeoFences. I am worried that my database (sqlite) and the actual fences might get out of sync. That is a design flaw in my opinion.
The reason LocationClient needs UI, is that the device may not have Google Play Services installed. Google has deviced a cunning and complex mechanism that allows your app to prompt the user to download it. The whole thing is horrible and awful in my opinion. Its all "what-if what-if" programming.
(They rushed a lot of stuff out the door for google IO 2013. Not all of it are well documented, and some of it seems a bit "rough around the edges").
I'm seeing strange behavior on FSEvents where I mount my drive in recovery mode and on reboot get zero fsevents in my stream.
I do the following:
Boot regularly
Record current event with FSEventsGetCurrentEventId()
Boot in recovery mode and modify a file in the watched path
Restart the system
When this happens, I get no events at all when I use the fsevents API. The only flag it sends in the kFSEventStreamEventFlagHistoryDone sentinel, even if I had made other changes on the regular OS.
This ars technica review seems to imply that when you mount on some other device you should get the kFSEventStreamEventFlagMustScanSubDirs flag, but I'm not seeing that behavior. Has anybody encountered this before? Is there a better way of detecting and dealing with the case that the drive has been mounted somewhere else while the OS was off?
Update: I tried the same thing booting from linux and modifying the file system. I did not get the same strange behavior of 0 events no matter what, but I also didn't get an event from the directory I changed or a MustScanSubdirs flag.
Update 2: In this thread, the accepted response says that when this happens, time machine detects that the logs are out of date in the above situations. Anybody know how to detect if the logs are out of date? This date could be used instead of a flag.
I think you need to also store the UUID of the FSEvents database in step #2, and check for it in step #4.
This behavior is vaguely mentioned in Apple's documentation (emphasis added):
Note: Because disks can be modified by computers running earlier versions of OS X (or potentially other operating systems), you should treat the events list as advisory rather than a definitive list of all changes to the volume. If a disk is modified by a computer running a previous version of OS X, the historical log is discarded.
For example, backup software should still periodically perform a full sweep of any volume to ensure that no changes fall through the cracks.
Note the bit about the historical log being discarded, then look at the reference (emphasis added):
FSEventStreamGetLatestEventId() -> Initially, this returns the
sinceWhen value supplied when the stream was created; thereafter, it
is updated with the highest-numbered event ID mentioned in the current
batch of events just before invoking the client's callback. Clients
can store this value persistently as long as they also store the UUID
for the device (obtained via FSEventsCopyUUIDForDevice()). Clients can
then later supply this event ID as the sinceWhen parameter to
FSEventStreamCreateRelativeToDevice(), as long as its UUID matches
what you stored. This works because the FSEvents service stores events
in a persistent, per-volume database. In this regard,the stream of
event IDs acts like a global, system-wide clock, but bears no relation
to any particular timebase.
FSEventsCopyUUIDForDevice() -> Gets a UUID that uniquely identifies
the FSEvents database for that volume. If the database gets discarded
then its replacement will have a different UUID so that clients will
be able to detect this situation and avoid trying to use event IDs
that they stored as the sinceWhen parameter to the
FSEventStreamCreate...() functions.
Note that the UUID is per-device, so if you have any filesystems mounted inside your directory tree, you'll probably need to get the UUID of each of them.
Good luck!
I've got a service that acts as a watchdog for several apps/servers. There are no user sessions on this machine. I'd like the watchdog to be capable of beeping on the internal speaker should something go wrong (that'd be my queue to go fix whatever it's complaining about)
when I try the Beep() API on Windows nothing happens - I suspect the problem is that the services session isnt permitted to make noises?
can I make this work? any other ideas for how to make the service alert me?
-CG
Call CreateFile on \device\beep, then send down IOCTL_BEEP_SET (see http://www.koders.com/c/fidFEC3527B9D951559D62722A9C0C603863106CA9B.aspx for details)
It may work if you allow it to interact with the desktop (an option configurable somewhere, I can't remember where).
But personally, I'd have it email me.
Though maybe you could have it use the task scheduling API to schedule a task for yourself, so next time you log on you can see it.
I don't know; you've got a few options. I'd avoid beeping though.
Try sending beep char "\a" to console. Not sure if it will work.
Beeping doesn't seem like a good idea - it might end up driving everyone mad....
I'd also agree about the "interact with desktop" option and you set this in the services parameters see A Windows Service without a template
I'd recommend creating a simple client application that polls that server to query for any problems and returns a set of status messages. Then an appropriate UI would be raised (e.g. balloon on the tray), an email sent, etc. containing any warning or failure messages.
This way you also know that the watchdog itself is running and has network connectivity - if the watchdog dies and/or machine locks up you wouldn't otherwise know.
It also avoids being thrown out of a window when the machine starts beeping continuously just after you go to lunch. [+1 to #mikej] :-)
The poll period should be around half (see Nyquist sampling rate) your minimum required response time.