Is it possible to initiate an upload when app is suspended? - ios

Here is the user experience I am hoping to achieve: In my app user can take some photos and upload them to Amazon S3. It is likely that user won't have internet available at that time (nature of app and target market). So I want to store those photos in device if internet is not available and automatically start uploading them whenever internet is available.
And this is where I need help: How can I achieve this? If not completely, how much closer can I get to this user experience? Like stores the photos and start uploading when users opens the app next time or show a notification when internet is available, then user can tap on it to open app and start uploading etc.
Additional information: Each upload will take ~1 minute to complete. After an upload is complete I also need to make an http request (if that matters).

Yes, this is possible. Look into URLSessionUploadTask:
Upload tasks are similar to data tasks, but they also send data (often in the form of a file), and support background uploads while
the app is not running.

Related

(Swift) Get usage data from other apps through the battery page in settings

I am trying to make an app where it tracks the usage of other apps. I already know that this is impossible to do by directly getting usage data from apps that do not belong to you. I am wondering if there is any way to access the battery page in the settings app by using the code in swift.
All I want is to be able to read the data for hours used and use that data in my app. I know this is probably a stretch, but is there any possible way of doing this?
There is no API to read this data directly.
There is an app on the App Store which has a hacky workaround. It requires users to take a screenshot of the battery usage settings page. The app grabs this photo from the user's photo library and uploads it to their servers where it is processed (using image analysis and OCR). They use this information to estimate how much each app is used.

AWS s3 upload + api taking too long

Currently, I'm using amazon s3 to store all the objects like images and videos. I'm using IOS AWS SDK to upload the objects.
The flow of my application are
User snaps a photo or record a video
User add additional information on a form, some sort like
Instagram's caption (using Alamofire)
user clicks continue, and then AWS will begin to upload the images
and videos to S3 using IOS AWS SDK
After object has been successfully uploaded to S3, S3 will response
with a link
Finally using Alamofire to send the information including the link from
S3 as parameters to POST API
The problem that I'm facing is that it takes quite some, to do AWS upload + calling an API. This indeed is a bad user experience. Most of the images are roughly less than 5 MB
My solution
Resizing the image, but what about Video?
After user click continue, instead of doing the AWS upload + calling
API, why not do it as a background on a different screen, so that
users don't need to wait for the loading indicator
What approach is great to solve this problem?. Thanks
Your problem can be rephrased to a questions of "How do I minimise upload latency?"
The most important thing is to use AWS for all app infrastructure.
If you are using S3 as a file storage and uploading from external server, you'll face a huge impact on upload speed due network latency.
When user uploads, your back-end process will write to disk first -
use EBS SSD.
Choose EC2 with increased network latency.
Place all your AWS resources in the same region and same availability
zone.
Another solution you might want to consider is to use S3 post-operation, instead of in-operation.
That simply means your server takes the upload and gives back URL to user, where independent background process syncs with S3 outside users requests.
In this situation you would have User -> Server -> User.
Right now you have User -> Server -> S3 -> User.
You may want to use content delivery network service like AWS cloudfront when speed and user experience is of utmost importance.
Amazon S3 is ideal when low cost of bandwidth and storage is more critical than speed of access, whereas Cloudfront is all about speed of access.
Please see this link as to how to setup cloudfront with your S3 bucket.
When your users are distributed worldwide, you should enable and use S3 Transfer Acceleration. This will decrease the upload time for user who are not close to your buckets's region.
Besides that, uploading 5 MB will take some time depending on your mobile connectivity. So you should resize the image on the client and you can think about starting the upload earlier, e.g. when the users enters details the upload already runs in the background.
I noticed that including "region" in the config speeds up uploading in 7 seconds.
There are maybe other ways to improve, I'm currently researching about including direct endpoint URL. Or maybe that's it: https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html
For me, it was not providing the content type option in the upload function. Saved like 60+ seconds

How does iOS decide whether or not opportunistic background fetch did download anything?

In the Apple documentation about 'Fetching Small Amounts of Content Opportunistically' (https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html#//apple_ref/doc/uid/TP40007072-CH4-SW56) the following is written:
Apps that download small amounts of content quickly, and accurately
reflect when they had content available to download, are more likely
to receive execution time in the future than apps that take a long
time to download their content or that claim content was available but
then do not download anything.
When downloading any content, it is recommended that you use the
NSURLSession class to initiate and manage your downloads.
How does iOS decide whether there was something downloaded or not, if I am not using NSURLSession? The communication between my app and our backend happens over XMPP. I'm afraid that maybe iOS would think that nothing wasn't downloaded and limit execution time in the future, even if we did retrieve content over the XMPP socket.

Can I make iOS 7 send pictures in the background when network connection is established?

I am building an app for iOS 7 that allows the user to select pictures and upload these to a server. In a perfect world the user would choose the pictures, press upload and be able to close the app.
I looked in to NSURLSession to establish this but it seems to only take a file. Is there any way i can send my NSData like in a NSURLRequest? Also, when not connected to the internet, is there any way i can make the app poll for an internet connection in the background and make it send the pictures when connection is established? I don't think was possible using earlier versions of iOS but iOS 7 seems to have some new options regarding background tasks.
Thanks in advance for any help!
A couple of thoughts:
You are correct that background uploads must use a file. So just save the NSData to a file (e.g. with writeToFile method), and then use that file path.
Regarding checking for Internet connection, the background NSURLSession takes care of that for you, so, no, you don't have to do that.
Regarding background uploads in earlier iOS versions, you could initiate the upload, but explicitly request a little more time to complete this finite-length task while the app runs in the background with UIBackgroundTaskIdentifier. See Executing a Finite-Length Task in the Background discussion in the App States and Multitasking section of the iOS App Programming Guide.
This isn't quite as robust as the new background NSURLSession functionality (which is more clever about applying discretionary logic so your app doesn't significantly adversely affect foreground apps, controlling whether it's permissible to do the upload over cell connection, allowing longer-length requests, working even if your app was terminated (for example, due to memory pressure), etc.). But UIBackgroundTaskIdentifier is a possible solution for iOS versions prior to 7 where you want to give an upload request a chance to complete even though the user has left your app.
Re: your comment about the "GOOD Dynamics SDK", I looked at it quickly. It does allow SDK-based app-to-app document sharing. I don't know if that means it writes a single encrypted on-disk file in the process, or if it uses an encrypted folder to store everything. If you had iOS access to that file, and a way to decrypt it on the server, then you'd have a chance of using the file-based background upload magic.

Background file upload in Blackberry WebWorks

I'm writing a Blackberry Z10 app for use in onsite events where we take photos or short videos of attendees and the photos are available immediately on a website. We take the photo, enter a message to be displayed with it and the photo gets uploaded right then. We initially used blackberry.io.filetransfer.upload but the videos could be up to 30MB so would have a long wait time, so we switched to an XHR transfer where we could have a progress bar so at least the app user would have something to look at.
We've found that sometimes they're in areas with low connectivity, so would like to just copy the file to a folder that is watched by a background process and anything deposited there gets uploaded to the server. How can we get an app functioning basically as a service, doing file transfers even when minimized?

Resources