Original fileURL from ItemProvider and UIDropInteractionDelegate functions - ios

Our iOS application allows users to select an email attachment document and upload it, through our application, to a remote database on a cloud server. We have been doing this successfully using "open in..", which allows us to identify the current fileURL of the document. Using the fileURL, we can both display the document in our application for immediate use, as well as upload it in the background to the remote data base. All good and very fast from a user perspective.
However, on iPad in split-screen mode, we would now also like to allow drag-and-drop, where the user drags the attachment from their email program and drops it on our application. Item Providers are used for this purpose, along with the UIDropInteractionDelegate methods. Unfortunately, these methods seem to want to either copy or move the document, rather than provide us with the existing fileURL. Moving or copying and then uploading the document into our application are both slow and expensive in CPU processing and thus degrade the user experience. We don't want to do anything with the file on the device. All we want is to get the existing fileURL. We will take it from there!
Question: How can we find the existing fileURL of a "dropped" document, using the Item Provider and the UIDropInteractionDelegate methods?

Related

PHAsset Create with Adjustment Data in One Go

TL, DR:
I want to create a new asset in the photo library and apply adjustment data (edits) to it, without the user being prompted twice.
The Background
I am developing an iOS photo editing extension, and providing similar functionality in the container app.
For better code reuse and modularity, I am adopting a PHContentEditingController-based flow on both the extension (required) and the container app, bundling all the shared components in an embedded framework that both the app and the extension link against (as recommended by Apple).
Unlike the app extension, which is "passed" an image to edit by the Photos app and executes under its supervision, the container app needs to request changes to the asset library, each resulting in the user being prompted for authorization.
On launch, the app offers the user two options for sourcing the image to edit:
Opening an existing photo from the library, or
Taking a new photo using the camera.
(both options rely on UIImagePickerController, of course)
Right now, the images read from the library undergo the same editing flow as they would within the app extension, with the only difference that my own UI code manually calls finishContentEditing(completionHandler:) on the (shared) object that adopts the PHContentEditingController protocol, and, on completion, it further calls the PHAssetLibrary method performChanges(_:completionHandler) (which triggers the authorization prompt).
This means that edits made within the container app can be reverted when re-editing the same image with the extension in the Photos app (and potentially vice-versa, too, once I get around supporting adjustment data).
For new images taken with the camera, however, I am taking a different approach. After applying the filters, I just save the result to the photo library using the legacy function:
UIImageWriteToSavedPhotosAlbum(_:_:_:_:)
(back from the time when argument labels weren't a thing yet :-)
The Problem
The problem with this approach is that edits are always 'baked in' for images taken with the camera and edited within the app (the can't be reverted). This feels arbitrary and perhaps even confusing to the user, so I'm looking for a more unified approach.
I could save the photo to the library right after the user takes it, and from there use the same flow as with existing assets, but this means that I need to modiufy the library twice:
Create a new asset
Save edits to the new asset
...which will result in the user being asked for permission twice: Once before editing the image, and once again on committing the edits.
So, my question is:
Is There a Way to Create a Library Asset "In One Go", Original Image and Adjustment Data?
Although I haven't tried this on my code yet (I have more urgent issues now), I seem to have found what seems to be the exact answer to my question in Apple's documentation for one of the initializers of the PHContentEditingOutput class:
init(placeholderForCreatedAsset: PHObjectPlaceholder)
From the docs:
Discussion
Use this method if you want to add a new asset to the Photos library
with edited content, as opposed to editing the content of an asset
after adding it to the library. For example, you might use this option
if your app applies filters to photos it captures with the device
camera—instead of saving only the filtered image to the Photos
library, your app can save both the filtered and the original image,
allowing the user to revert to the original image or apply different
filters later.
Also:
Note
If your app edits the contents of assets already in the Photos
library—including assets your app has itself recently added—Photos
prompts the user for permission to change the asset’s content. If
instead your app uses the init(placeholderForCreatedAsset:) method to
create an asset with edited content, Photos recognizes your app’s
ownership of the content and therefore does not need to prompt the
user for permission to edit it.
I guess we all need a healthy dose of RTFM once in a while! :-)

Notify users PDF creation is ready and can be downloaded

Users can create a PDF in my app which takes some time to generate, so it has to be done in a background job. No problem, but then there is a delay and the user must be notified that the PDF is ready.
So the first choice is to send an email with a download link or a push notification in the app itself. My preference is the push notification, so I guess ActionCable is the way to go? My app runs on Heroku, so is ActionCable also a good choice then or is another solution preferable?
Then there is another consideration, where to store the generated PDF until the user downloads it? I could upload it to Azure/S3/etc with ActiveStorage, or I could store it temporarily in an app folder and delete it after download. My preference is to do the last, because the PDF is there only for a few minutes and therefore the hassle to store it in the cloud is not really needed?
You have a very broad question here, which is very much dependent on the overall user needs and experience you want them to have.
I'll start with the simplest part, in terms of temporary storage of the PDF. There are several things to bear in mind here.
I would say that from a scalability, and application security standpoint, storing the PDF to the cloud is the way to go. Opening up writable directories on your application server carries a risk. Also, if you ever need to scale to more than one server, this will not work. Deleting items from cloud storage is not hard with the appropriate APIs.
Is it essential for the user to be authenticated in some way to download the PDF? This is more challenging if you push the PDF to a cloud bucket (unless you have the PDF named with a very complex, unguessable name, that name only accessed through the authenticated application). If the data is less sensitive, then your email notification can show the link directly, but you won't know easily if a user has retrieved the PDF and it is now ready to be deleted.
In terms of notification, I'd go with email for several reasons. Simplicity is the main one. Do you have experience with ActionCable? It appears simple on the surface, but there are many things to bear in mind when using it: infrastructure and UI being the major ones. Also, from a user experience perspective, are users likely to hang around in the application waiting for the PDF to be completed? What happens if they logout? How will they know the PDF is available?
If the timescale for generation of the PDF is short and absolutely optimized scalability is not a big deal, you could consider a simpler mechanism that checks for user notifications (a simple query onto a user_notifications table for example) for every user action, and use a flash or some other session flag that the UI can check and use to asynchronously retrieve the notification.
Just ideas. Impossible to give definitive answers.

Where to save my iOS app's save files

I am learning iOS file system to store my game data like saving the amount of money earned and things like this in a xml file.
The question is where should I store them?
I read this: File System Basics
And I don't know that I should save data in Documents directory or Application Support directory.
Because the data I want to save is something that is not associated with user's documents and user will never see it so it should be in Application Support, but on the other hand it's something that is affected by user interactions so it should be in Documents.
I think it is the Application Support/MyGame as per the Apple Developer guide link shared by you. You are confused by the fact that it should not be something affected by user interaction. Actually it means user should not directly interact with these. See this from the link: File System Basics
Using something like Parse may slow down your app as it needs to interact with their server, but you do get a backup.
For something of this size, I'd use a mobile backend solutions provider like Parse or Firebase. Personally I use Parse in my projects and is very easy to implement advanced functionality into your apps like user registration/save data to users.
Hope this helps.

iOS app that creates HTML5 content

I'm trying to do something a bit complicated and I'm not entirely sure how to go about it. Could you please give me some pointers on the tech I should use and how I should go about implementing this. Here's what I need to do:
Create an iOS app that allows the user to upload pictures from his camera roll and modify variables with sliders. (so far so good)
These variables and graphics are used to modify some htlm5 code (i.e. the graphics the user supplies are called by the hmtl code and the variables modify some set variables in the script) (Do I just edit the code as a string?)
The code is put together and uploaded to a server where it is accessible at a unique URL. The user can save multiple times and each time it creates a new URL. (Do I need an FTP here?)
Your question is too general, but as far as I can help, Yes you have to create and edit some html source texts, and append every object that user is adding to the page as some html codes, files, css, etc.
and for uploading, if you want the user to upload the site to his/her own ftp server or web hosting service, yes you need FTP connection to create with the server.
But if you want your user to upload the website to a space you're providing for the user, then you need some server part and maybe some APIs. then you may use FTP or even some APIs to create and update files on your server. It highly depends on the service you want to provide.

Is there is any way to directly access files from video gallery?

I want to know is there are any way to doing this (talking about iOS): Choose video from Video gallery, store its 'URI'. And then access this video using this URI directly?
For example, on Android I can pick video, remember its filename, and with file system load it using this filename.
I don't want to store it is in my application cache folder or something else, that will duplicate data on device.
Is there is a way to do such thing on iOS?
Take a look at all of the "Bookmark" methods of NSURL
They give you the ability to find the underlying file, even if it's moved around when your app is closed.
From the docs:
A bookmark provides a persistent reference to a file-system resource. When you resolve a bookmark, you obtain a URL to the resource’s current location. A bookmark’s association with a file-system resource (typically a file or folder) usually continues to work if the user moves or renames the resource, or if the user relaunches your app or restarts the system.

Resources