How to check if NSData has a multimedia content? - objective-c

I have a NSData object, obtained from a URL request.Now I don't know how to read it.
However in my application I don't know if the data contains a video or not, so I would know:
How to know if NSData has some video inside it?
How to interpret the data, reading it byte per byte?

I'm not familiar with the particular API you're using so I can't say what the code should be, but any web/HTTP client library should provide you the Content-Type of the data as well as the data itself. Use the Content-Type (and only the Content-Type; doing otherwise can lead to security bugs) to determine how to interpret the content. For example, if the Content-Type (also known as MIME type) starts with video/, then the content is definitely video; the part after the slash will tell you the specific format to interpret it as.

If you intend to play the video that the data may contain, then just do that. Whichever playback API you use should give you an error if the data isn't anything it recognizes.

Related

Appropriate REST design for data export

What's the most appropriate way in REST to export something as PDF or other document type?
The next example explains my problem:
I have a resource called Banana.
I created all the canonical CRUD rest endpoint for that resource (i.e. GET /bananas; GET /bananas/{id}; POST /bananas/{id}; ...)
Now I need to create an endpoint which downloads a file (PDF, CSV, ..) which contains the representation of all the bananas.
First thing that came to my mind is GET /bananas/export, but in pure rest using verbs in url should not be allowed. Using a more appropriate httpMethod might be cool, something like EXPORT /bananas, but unfortunately this is not (yet?) possible.
Finally I thought about using the Accept header on the same GET /bananas endpoint, which based on the different media type (application/json, application/pdf, ..) returns the corresponding representation of the data (json, pdf, ..), but I'm not sure if I am misusing the Accept header in this way.
Any ideas?
in pure rest using verbs in url should not be allowed.
REST doesn't care what spelling conventions you use in your resource identifiers.
Example: https://www.merriam-webster.com/dictionary/post
Even though "post" is a verb (and worse, an HTTP method token!) that URI works just like every other resource identifier on the web.
The more interesting question, from a REST perspective, is whether the identifier should be the same that is used in some other context, or different.
REST cares a lot about caching (that's important to making the web "web scale"). In HTTP, caching is primarily about re-using prior responses.
The basic (but incomplete) idea being that we may be able to re-use a response that shares the same target URI.
HTTP also has built into it a general purpose mechanism for invalidating stored responses that is also focused on the target URI.
So here's one part of the riddle you need to think about: when someone sends a POST request to /bananas, should caches throw away the prior responses with the PDF representations?
If the answer is "no", then you need a different target URI. That can be anything that makes sense to you. /pdfs/bananas for example. (How many common path segments are used in the identifiers depends on how much convenience you will realize from relative references and dot segments.)
If the answer is "yes", then you may want to lean into using content negotiation.
In some cases, the answer might be "both" -- which is to say, to have multiple resources (each with its own identifier) that return the same representations.
That's a normal thing to do; we even have a mechanism for describing which resource is "preferred" (see RFC 6596).
REST does not care about this, but the HTTP standard does. Using the accept header for the expected MIME type is the standard way of doing this, so you did the right thing. No need to move it to a separate endpoint if the data is the same just the format is different.
Media types are the best way to represent this, but there is a practical aspect of this in that people will browse a rest API using root nouns... I'd put some record-count limits on it, maybe GET /bananas/export/100 to get the first 100, and GET /bananas/export/all if they really want all of them.

Can I trust the .Length property on IFormFile in ASP.NET Core?

We have an API endpoint that allows users to upload images; one of its parameters is an IFormFileCollection.
We'd like to validate the file size to make sure that the endpoint isn't being abused so I'm checking the Length property of each IFormFile, but I don't know whether I can trust this property or not, i.e. does this come from the request? Is it considered 'input', much like Content-Length is?
If you have an IFormFileCollection parameter, and you send data using a "form-data" content-type in the request, that parameter will be bound by a whole lot of plumbing that's hard to dig through online, but if you just debug the action method that accepts the IFormFileCollection (or any collection of IFormFile, really)and inspect the collection, you'll see that the uploaded files will already have been saved on your server's disk.
That's because the entire multi-part form request's body has to be read to determine how many files there are, if any, and form parameters, and validate the request body's format while it's reading it.
So yes, by the time your code ends up there, you can trust IFormFile.Length, because it's pointing to a local file that exists and contains that many bytes.
You're too late there to reject the request though, as it's been already entirely read. You better fix rate and size limits lower in the stack, like on the web server or firewall.
Content-Length is compressed number of bytes of data in the body , it is not reliable since it may include extra data ,for example , you are sending multipart request . Just use the IFormFile.length for features like calculation or validation .

How do I know the duration of a sound in Web Audio API

It's basicly all in the title, how do I know or how can I access the duration of a soundNode in Web Audio API. I was expecting something like source.buffer.size or source.buffer.duration to be available.
The only alternative I can think of in case this is not possible to acomplish is to read the file metadata.
Assuming that you are loading audio, when you decode it with context.decodeAudioData the resulting arrayBuffer has a .duration property. This would be the same arraybuffer you use to create the source node.
You can look at the SoundJS implementation, although there are easier to follow tutorials out there too.
Hope that helps.
Good and bad news; nodes do not have length - but I bet you can achieve what you want another way.
Audio nodes are sound processors or generators. The duration of a sound processed or made by a node can change - to the computer it is all the same, lack of sound is a buffer full of zeroes instead of other values.
So, if you needed to dynamically determine the duration of a sound, you could write a node which timed 'silences' in the input audio it received.
However I suspect from your mentioning of meta data that you are loading existing sounds - in which case you should indeed use their meta data, or determine the length by loading into an audio element and requesting the length from that.

Detect if NSURL is a URL to a file format supported by the UIImage class

I'm looking for a way to detect a if an NSURL is a URL to a file format supported by the UIImage class, and if yes, open it in something like MWPhotoBrowser (https://github.com/mwaterfall/MWPhotoBrowser) instead of a UIWebView. My first thought is to have an if condition with all the supported file extensions. I'm wondering if anyone knows of a better way?
You don't know what's at a URL until you at least begin to fetch it. Some URLs look like they end with a filename -- an image filename, even -- but actually point to HTML pages (say, for viewing said image). Some URLs don't appear to end in a filename but do point straight to an image file.
You can get a pretty good hint as to what kind of data is at a URL by making an HTTP HEAD request: see NSURLRequest and NSHTTPURLResponse and look for the Content-Type header. (Those just describe a request and response; you'll need NSURLSession to perform the request and get a response.)
Even a HEAD request doesn't always report correctly, though: the only way to really be sure if there's an image at a URL is to fetch it -- most image formats are identifiable within the first several bytes of the data, so you can begin a fetch, look at the first partial data you get, and abort the fetch if you don't want the rest.

Best way to write to file a large HTTP response

I'm looking for ways of writing to file the results of a web request. In languages based on the JVM or the CLR there are appropriate Stream-based techniques I'm familiar with, however I'm clueless on how could that be done in Objective-C.
What I need is essentially a way to send an HTTP request (with a custom header set) and write the HTTP response content as I receive it (due to memory constraints I can't afford to get the whole file or even a large portion of it before persisting the contents).
Ideas/suggestions/snippets?
Thanks in advance!
P.S.: I'm developing for Mac OS and I'm already using ASIHTTPRequest, if that can be of help.
Edit: I should specify that I don't want to write all of the contents returned by the server to disk unless I can write them directly at a certain offset of a file (which I'll then be able to manipulate), so anything that dumps straight to a new file or to the beginning of a file won't work for me.
There a few ways of doing it, depends on how you want to handle the responds
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:#"/Users/Test/Desktop/cool.html"];
with setDownloadDestinationPath: set, it'll save into temporary path, and when it finished, it'll move it to your downloadDestinationPath you set.
Or you can implement request:didReceiveData: delegate (see ASIHTTPRequestDelegate.h), and handle it yourself. This is similar to stream.
PS. I only ever use ASIHTTPRequest on iOS, not Mac OS, so I'm not entirely sure if it will work for you.