How does the 'Flock' iOS app detect when photos have been taken? - ios

Flock is a reasonably new iOS app from the guys at Bump, which has an interesting feature. It somehow knows when photos have been taken by another app, notifies the user (in a notification center way), and asks the user to share them into an album. There are other interesting features of course, but I'm particularly interested in this feature for another app that I'm working on.
I can't see how the API facilitates this directly. I looked carefully through the notifications API documentation, and apps can certainly register to show a notification to the user at a future date/time, and thus be opened by the user at that time... but I couldn't find any system notification for when a photo has been taken. The notifications API also allows server-generated notifications, but once-again, I don't know how Flock's server-side could know when the user has taken a photo in a different application.
I installed the app a couple of days back, and I only seem to get the notification when I have taken photos. It doesn't appear to be just a daily reminder.
Any ideas how Flock (and potentially other apps) manage to do this?

After a couple of days of observing the app's behaviour (and a lot of Googling and bumping into arcane discussions about file locking), I have a strong suspicion of how it works: Flock has simply registered for Significant-Change Location Service, which wakes the app and provides a small processing window when the user changes location. The documentation says:
At wake-up time, your app is put into the background and given a small amount of time to process the location data
I suspect that Flock is checking the image library at that point, and triggering a local notification if photos have been added. This squares with my experience that Flock gives me a local notification ~10 minutes after I leave home... which, in case any of the Bump/Flock devs are reading this, is just about the worst time for me to sort through my photos and share them in an album (perhaps I should use public transport more often).
There are some other interesting SO answers here, here and here... but for the most part they discuss local notifications (which can only be scheduled for a particular time, and will always alert the user at that time, so aren't really background tasks) or the 600 second background processing window afforded to apps that have been shut down by the user (which is certainly a background task, but is clearly not fit for the purpose of running a background task once a day or somesuch).
The Bump devs have also provide some clues to the underlying architecture of the app here.

I haven't used this Framework personally, but I did stumble across this documentation when doing research for a client.
Apple Photos Framework Reference
Under the Features & Concepts there is an entry for "Change Observing" which states:
Use the shared PHPhotoLibrary object to register a change handler for the photo entities you fetch. Photos tells your app whenever another app or device changes the content or metadata of an asset or the list of assets in a collection. PHChange objects provide information about object state before and after each change with semantics that make it easy to update a collection view or similar interface.
It appears that you can use the PHPhotoLibrary singleton to registerChangeObserver: on a class of yours (that adopts the PHPhotoLibraryChangeObserver protocol) to receive PHChange objects from the photoLibraryDidChange: method

Related

Can we backup Files and Photos in terminated state

Since there are many places on the Internet talking about Background Fetch in terminated state, some are saying that iOS does not allow anything in that period except working with notifications, location services etc.
Can anyone please give us a final conclusion about this topic, whether the iOS app can work when terminated and what are the limits?
What I'm specifically interested in is file backup. I want to make specific folders in Files periodically (for example each 6h) check if files in it are changed, and if they did, make an API call which will update those changed files on the server. The user should be able to choose which folders he wants. Or for example Photos app, if user gives permission, could we backup the photos from time to time as it works on Google Photos?
These two resources are confusing me a bit, like they are contradictory:
https://www.hackingwithswift.com/example-code/system/how-to-run-code-when-your-app-is-terminated
https://developer.apple.com/documentation/backgroundtasks/bgprocessingtaskrequest
On the first one it says we can run some code when the app is not running for 30 secs, but another says we can execute even longer tasks.

Apple disallowing background location tracking which is critical to business use case

We have an app that tracks riders in the field and as per their current location and some other parameters assign them deliveries. For this, even when the user is not currently using the app, background mode or device locked, we need to keep track of their location after every x seconds.
Now, we have explained the complete business use case to Apple but they keep coming back with the same response:
Thank you for information. We still need a demo video that shows a
“Background Location” feature (Such as: turn-by-turn navigation,
bread-crumbing) when the app runs in the background.
We still do not see a “Background Location” feature (Such as:
turn-by-turn navigation, bread-crumbing) within your app in the demo
video your provided. If the app does not have this feature, please
kindly use the foreground location instead. please remove the
“location” setting from the UIBackgroundModes key if your app does not
require persistent real-time location updates. You may wish to use the
significant-change location service or the region monitoring location
service if persistent real-time location updates are not required for
your app features.
I wonder how does Uber and other ride sharing/location based apps go around this app for their drivers
You haven't really asked a question above (likely why someone downvoted). You've mostly just posted a complaint about Apple's review process. You've not explained why it's critical to get it every few seconds. And you haven't mentioned why Apple's suggestions don't work/aren't good enough.
Here are some general points around the area you have mentioned that should be useful
Background location:
If you want to allow your app users to close your app, you can use "significant-change location service" to allow your app to detect when the device has moved a lot, in a much more battery efficient way. You get ~10 seconds to ping a server and restart the request for the next time. Apple mentioned this in their response to you, please check it out: https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html
"I wonder how does Uber and other ride sharing/location":
They don't do what you are trying to do first of all, they encourage their drivers to keep the app open at all times for optimal performance. Again Apple mentioned this in their response. Your app is not providing any use to the app user while in the background and tracking location. So either keep the app open and track location (How to prevent screen lock on my application with swift on iOS) or, rely on significant change location events in the background
Again as Apple said in their response, if 1 or 2 above doesn't address your needs (likely they do), you need to implement a feature such as turn by turn directions in the background, in order to justify why you need this data. Users also need the ability to turn this off, so that it can't be abused by the developers.
Apple doesn't allow apps to just track whatever they want due to privacy issues. There is no way to get around this, you'll have to do one of the above.

Is using Core Location for performing functionality in the background appropriate?

Lately, I've notice that there are a few applications request to access the user's location for performing some functionalities in the background.
For example: Application for scanning and uploading the user's photos for backup purposes, so when entering the background state, it keeps scanning and uploading.
What am I asking:
If there are Background Execution mechanisms for executing Background Tasks (Select Target -> Capabilities -> Background Modes), so why using the Core Location for doing such a thing?
If using Core Location is different, what is the benefit of using it?
Also, I've read (and this is what I assume) that using the core location for not what is meant should causes to let the application to be rejected, the weird thing that -as I mentioned- there are a few applications doing this! I feel a little confused about it.
Also, I've read (and this is what I assume) that using the core location for not what is meant should causes to let the application to be rejected, the weird thing that -as I mentioned- there are a few applications doing this! I feel a little confused about it.
You are right to be in doubt. Do not imitate this behavior. These people are misusing CoreLocation as a way of getting their code to run in the background even though they are not really using any CoreLocation features.
You are not allowed to do things arbitrarily in the background — and with good reason. Don't violate the rules. If you want to keep uploading even when in the background, use a URLSession with a background URLSessionConfiguration. Do things the right way.
Edit: To remove any doubt: I do not recommend the following approach, in fact, like #matt I highly discourage anyone from using this or a similar approach. Please see my comment below for a better way to update the app in the background.
To answer the OP question:
You can ask CLLocationManager to get significantLocationChanges. This will not only notify you and give you CPU time in the background, but will actually launch your app (even after phone restart!) to let you know of the location changes.
This is a pretty good way of promising yourself some extra processing time in the background (although like you said - it's a very bad "app behavior" and may even cause your app to get rejected from the AppStore)
AFAIK the first app to do this was Dropbox - they had a whole screen in settings explaining why they ask you for location just to backup your images... since iOS doesn't have any event (for 3rd party devs) for informing an app on changes in the device photos, Dropbox solution was to get "woken" on those location changes and check themselves for changes, if they found any - they would upload the new images to Dropbox in the background.
significantLocationChanges only uses low-power methods such as cellular towers and nearby Wifi and therefore is pretty easy on the battery. The processing itself however can be intensive, depending on the app that takes advantage of this method.

Best practice for when to call requestAccess on EKEventStore

Should and event store's requestAccess(to:completion:) be called
as early as possible (e.g. in application(_:didFinishLaunchingWithOptions:)
only before EKEventSource should be used for the first time?
Does Apple recommend one or the other option (for iOS 10)?
Why nag the user any sooner than necessary?
A user will be more comfortable if the request for permission comes when they actually try to do something they know requires access to the event store.
If you request permission too soon, the user is going to wonder why the app is asking when they haven't even done anything with the app yet.
And what if your app needs access to multiple sources such as camera, photo library, contacts, and events? It would be terrible to just nag the user over and over for all of them up front. Only ask when the source is actually needed and the user probably fully understands that the action they just took (like take photo) requires the specific permission.

iBeacon notification database

I have a question which I have not been able to figure out so I decided to see if I can get some help on here.
I am working on an iBeacons project and I have been able to understand the basic function of iBeacons, setting up UUID'S and major and minor id's to specify exact notifications, but my question is how do I dynamically update information I send out to the users without having to go into the code each time to do this. Do I need to create a database to store all my information I want to push out to users? if so how will this database constantly refresh messages pushed out to users? An example would be lets say if you walk into a store and you get a notification in the shoe section saying there is a 10 percent off, you look at the notification but not too impressed and start to walk out, then you get another notification saying for today only you can get a 25 percent off... The app has to dynamically refresh for this to be possible.
Please help me clarify this
Thank you very much for the help
What you probably want is to store this deal information in a web service so you can update it without changing the app. Your app would need to download the updated deal information from the web service either when it starts up or when it sees an iBeacon.
My company, Radius Networks, offers a tool called Proximity Kit that makes this easy. You can assign arbitrary key/value pairs to iBeacons using a web interface. Then your app downloads them automatically an has access to them whenever you see iBeacons.
In your scenario, they key/values could be something like:
primary_offer_text=10% off all shoes
secondary_offer_text=20% off all shoes

Resources