Can we backup Files and Photos in terminated state - ios

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.

Related

iOS: Issues with background uploading large files

I have an app that records and uploads large files ( up to 5gigs each )
After the recordings are done the user triggers an action to begin the file uploads.
The uploads are registered for background processing so they continue if the phone goes asleep.
I issues I am running into:
Random memory crashes on some files over 4 gigs
Unable to initiate a background upload while the app is already suspended.
So if user records a file between 4-5gigs the app will randomly crash while uploading. Multiple 5 gig files uploading at the same time also increases the chance of crashing.
We currently upload the files in sequence but ran into issue #2 from my list. If the user records multiple 5 gigs files, and puts the phone asleep, only the the first file will upload and the user has to reopen the app for the next file to begin processing.
I have attempted to use BackgroundTasks to see if it can trigger an upload but the background task never fires and I've read the only attempts to fire the background task if it thinks the user is about to use the phone.
I also tried using the urlSessionDidFinishEvents callback on uploadTask. But it never seemed to fire or at least it can't be used to call an API request.
Anyone have advice on initating background file uploads for large files?
I think the problem is that you are likely reaching system resource limits. The system will eject your binary when this occurs; they are called Jetsam events. I suggest you trigger a sysdiagnose event on your device (differs per device - usually pressing volume up, down, and side buttons together).
Then recover the logs from Settings > Privacy > Analytics and Improvements > Analytics Data
The file names begin with sysdiagnose_YEAR.MONTH.DAY_*.
After you copy the files over to your Mac (using the Share button in the iOS UI) you can then look at specifically what is being breached.
Please update your question with specific log information thus retrieved.
Lastly, it is worth implementing applicationDidReceiveMemoryWarning: since your app is probably using a lot of memory during such processing.

What is the maximum amount of data an iOS app can handle?

Right now we are designing an app in Swift that fetches HTML applications from a server in form of zip files and then run it in the iOS app as an web view. Each zip files is of approx 4-5 mb in size. We have 30+ HTML applications in our app as of now. But we may reach to 150-200 apps soon enough. I would like to know the maximum amount of data that an iOS app can handle. If excess amount of data gets deleted, where will it go? Will it be stored in iCloud before the data gets deleted? Please help me. P.S. The HTML applications will be downloaded from the servers in form of zip files , it'll be extracted and then will be stored as a folder. When the user first installs the app in his system , he won't have any html applications installed. He'll have to fetch the apps one by one according to his requirements.
Since you're saving the content to disk, the limitation is the disk size of the user's device. It also depends on where you're saving the data: If you save to the tmp directories, the data may get deleted, but if you're saving to the application's normal directory it will also be backed up to iCloud (assuming the user backs up).
I would advise against filling up the user's phone with hundreds of MB of data automatically, they will get very annoyed at you. So you will want to offer them a UI to actually select which content they want to keep and which should be removed.
No limit as far as I know.
But be aware that all files you download and store in the app have to be marked as "do not backup in iCloud" - otherwise Apple will reject your binary when you submit it to the store.
See
Apple Documentation and
Excluding files from iCloud Backup
My advice,
Don't download all the applications at once, instead provide user a UI from which he can able to select any application (only one at a time, because at any point he'll be able to run single app only, I guess), then download that particular application (also removed if any previous installed app found).
But wait, there's one more option, you can keep 3 apps at a time, and I believe they wouldn't cost you more than 20Mbs (as you said, 4-5Mbs / app). If so user may have feel of switching between (last used) three apps. If he want any other application then he can select any app, here you need to delete (a app from last three) and add newly downloaded app, this means at any point you'll have 3 apps in your directory.
Now the problem of preserving user information (for individual apps), here you can use any local db (or your server or any third party servers) to store (preserve) user information for particular app. At any point he'll delete the app (you should keep backup of it before deletion will be made).
Later, when he changed his mind, and download the app (previously deleted), then you can restore the information (which was preserved before).
Good luck! Don't wash your hands :)

Using MultipeerConnectivity.framework to send and receive photos and text files

I want to give to the user of my app the ability to share a photograph without having an internet connection. It is quite hard to explain but I'll do my best. Basically in my app a user can press on a plus button to take a shot using their iPhone. This image is then uploaded on the Internet (Dropbox) in a common folder that can be accessed by all app users. When other users open the app, the image that has been uploaded is downloaded on their device. Since there might be more than one image, the app refreshes itself once in a while, and downloads the new photographs. I want to do the same thing using the bluetooth (or airdrop). When one device takes a picture, this is saved on the device, and sent to all app users nearby. These users can edit it, send it back to the original device where it can be accessed by everyone. basically the original device acts as a server, and all other devices stream the information from that device. The whole purpose of this is to have, say 15 different iOS devices all in the same room in sync which display the same exact thing. When someone edits, all the other people will see it, as if they where in sync with "the cloud" (which now is Dropbox).
I understood that this might be possible with MultipeerConnectivity.framework as it permits more than one device to be connected at the same time. I also found an example app called beam it: http://arctouch.com/beamit/
What I'm asking here is not really for some code, rather some indications on how I could approach the problem.

Keep track of time since last attempt of ______

I have a game where users can do a certain activity once per hour. How can I make sure it's been an hour since the last time they attempted something without them just changing their devices current time in settings?
Also, if I wanted to prevent the user from just deleting the app and re-installing it so they could constantly keep trying without having to wait to full hour is there any way I can store data on the device even after an app delete or would that have to be a server thing?
If I don't have a server can anyone think of a clever way to do this via Free in-app purchases or something?
The only way to persist data in a way that survives app reinstalls is to save it to the keychain. This works, because keychain data may be shared across multiple applications; the rest of your application's data is removed on uninstall.
If you need a reliable way to tell the current time, the device must be connected to the internet. In this case you would be able to check the current time using one of the time services through the NTP.
That sounds like exactly the sort of task you would need a server for.
When the user wants to perform this limited action, have them ask the server for permission. You can log the user's ID and request time, decide if they can execute the action, then return a small success/failure message. Works if they change their clock, works if they log in from a different device, works if they wipe the device data.

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

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

Resources