URLSession: Any way to read a file as it is being downloaded? - ios

The use-case is that I want the user to be able to preview a song hosted at a remote URL. Fine, you say, just use AVPlayer. Yes, but I want to be able to cache the file locally if it is completely downloaded in the course of being previewed. As far as I can tell, there's no way to access the local data that AVPlayer downloads for its streaming playback. Likewise, there's no way to get access to the data being downloaded by URLSession until it is completely downloaded. So, I'd like to find a result using one of these approaches:
Access the data in AVPlayer once it has completed downloading it and save to a file.
Download the data progressively to the cached URL and have AVPlayer play it as enough data becomes available.
Are either of these scenarios possible? Is there some other scenario which will achieve what I am looking to do?

So the solution to this came from the AlamoFire source code. If you use a URLSessionDataTask in the traditional, non-combine way and have a controller conforming to URLSessionDataDelegate, then you can implement the urlSession(_:dataTask:didReceive:) protocol method to receive the data as it arrives, rather than waiting to receive it at completion. This allows you to directly write the data to a file of your choosing that is completely under your app's control.

Related

Get an image from URL and upload it to Firebase Storage

Is it possible to write a function to get an image from a url such as https://website.com/images/myImage.jpg and then automatically upload it to a Firebase Storage bucket?
I am trying to do it with multiple images in one go but am struggling to get one to work at the moment. My best attempt so far has seen me having to download the images, save them in the Media Library and then send them all up to Firebase, which surely cannot be the most efficient way?
In a nutshell, I have 10 images with URL's like the above and, when the function is fired I need them all to upload to my storage bucket, without the need to save them to the users device library.
Does anyone have any ideas on the most efficient way to do this please?

custom URLProtocol cannot work with AVPlayer

goal: network flow collection in my app.
For collecting all network flow, i custom URLProtocol. it all work fine with normal GET, or POST request of Json. But it makes audio playing part not working. My Audio playing part is based on AVPlayer and AVPlayerItem.
If i unregister custom protocol, audio playing works again. Does it has some connections between two of them ?
According to https://forums.developer.apple.com/thread/75328 AVPlayer does go through the URL loading system, but those requests are made in a helper process (mediaserverd) and thus don’t ‘see’ custom NSURLProtocol subclass.
Here post my implementation of custom protocol.https://github.com/JimmyOu/JODevelop/blob/master/JODevelop/Tool/performance_Monitor/Network/NEHTTPMonitor.m
Thanks all.
there is no way to deal with it .you cant custom protocol to deal with AVPlayer staff.My compromise is filtering .mp4 or .mp3 url sacrificing some lost network flow.but it wont make mistake

Downloading images directly from Parse.com, as opposed to using their API

I noticed that for a PFFile type Object stored on my Parse.com developer account, the link is open and accessible for anyone to view/download.
Example a PFFile Object that is named, name.jpg, representing an image could be a URL like :
http://files.parsetfss.com/<some garbled class UUID>/<some garbled image uuid>-name.jpg
Where <some garbled class UUID> appears to be the same for all name.jpg, stored on a class
and <some garbled image uuid>-name.jpg appears to be unique uuid's appended with the actual object name which is 'name.jpg'
Using the above URL, anyone/any client can download the object
So I have some questions regarding this:
Is this normal? Is this by design?
Will the URL for an object change, if nothing else changes?
Am I being unwise in using this information to download images directly, thereby saving the cost of one API call from Parse (although I think I'll make one API call anyways to get the URL) ?
Will downloading directly from this URL, perform better/acceptable compared to downloading via Parse.com API
Yes it's normal. Protection is via the object, don't give access to anyone who shouldn't have it.
No the URL shouldn't change, though strictly you should query from the file object each time you want it to be sure.
You should care more about network calls that API calls in general. You could use cloud code to aggregate responses, or batch requests, but that doesn't reduce API calls.
The download is unchanged as you're always downloading the same file from the same link no matter which API you use to do it.

Generate file-directory-safe string using URL?

My app is sent messages which sometimes include http links to images. When this happens, I want to cache the image locally, so I can display the image in future without needing to download it, if it exists locally.
But lets say the image url is http://imgur.com/abcdef.jpg. A file path of something like this, I'd imagine could have all sorts of issues:
/var/Applications/[application]/documents/http://imgur.com/abcdef.jpg
What I need is a way to take the given image URL and generate a file directory-friendly string, so that I can save the image using that URL every time, or check for its existence.
While there are many ways how to implement it (simpliest way would be to create MD5 of the web address, store image as [md5name.png] and then just try to check if md5 file reference exists), I suggest you use one of two libraries made for that:
https://github.com/Haneke/Haneke
https://github.com/rs/SDWebImage
They both work on url-based principles, provide you with all known implementations of caching and they handle cases like this by default. Both of them also download images in background which is recommended way to do it and have convenience methods to load images in UIImageView.
Hope it helps!

Using a custom URL scheme with UIWebView

I have a black box container. I love black boxes, they obfuscate things so well.
This black box is an encrypted zip (sort of) and has inside some html files (this is the short, not so painful to explain, version).
Those files need to be displayed in an UIWebView. Now, the easy way to do it, decrypt, unzip to filesystem, load file from filesystem. That's good, except, the black box contains secret stuff, and can't just lay around on the filesystem, not even a sec, so, I made a C library that actually streams the contents of the box (directly out of the box).
Now, I have this streaming capability and have to somehow make it work with UIWebView. First thing that comes in my mind would be to use a mini local HTTP server where the UIWebView can sent its requests. I would then manage the requests myself and return the contents the UIWebView requires using the streaming lib I've done. That would work I suppose well, but I think a mini HTTP server would somehow, maybe, be a little bit of a overkill.
So, I was wondering, is there another way to interfere between UIWebView and the filesystem? Maybe using a custom schema? Like myschema://? And every time the UIWebView makes a request to myschema://myfile.html I would somehow interfere and return the data it needs?
Is such a idea viable? Where should I look to start from? Maybe NSURLRequest?
EDIT: I found this: iPhone SDK: Loading resources from custom URL scheme. It sounds good, however, how will the browser know the size of the request, the type (xml/binary/xhtml) and all the info HTTP puts in its header?
Create a custom NSURLProtocol subclass and register it so it will handle the HTTP requests. This will allow you to handle the requests that come from the UIWebView however you see fit, including supplying the data from your library. You can examine an implementation of one that performs disk caching of requests to allow offline browsing by looking at RNCachingURLProtocol. I personally use a custom NSURLProtocol subclass that I wrote to handle injecting some javascript code into pages that are loaded in the UIWebView, and it works very well.

Resources