How to use NSURLSession to post some properties and a image - ios

I have a node.js as backend server. And it has a post method accept a title param and a latitude and longitude param and a image. So, I am not only post a image but with other params together. In the node.js,
title -> uitextview's text
latitude & longitude - > cllocation
and a image.
the node.js corresponding method is a form.
How to use NSURLSessionUploadTask to post them to the server.

A file upload with additional parameters will be usually accomplished using a HTTP message whose content type equals multipart/form-data. For reference, see Form-based File Upload in HTML, RFC 1867.
A multipart/form-data body is composed of one or more "parts" which have each a disposition header and an optional content type header. One part contains the data of the file along with a corresponding content type header, and the other part (or several parts) contain the parameters. The part containing parameters, may have a content type of application/x-www-form-urlencoded where the body consists of the encoded parameters, or perhaps JSON or whatever is supported by the server. Each single parameter may also be represented as a separate part.
The difficulty here is the proper composition of the HTTP message whose body is a set of parts. Cocoa or iOS does not have direct support for composing a multipart form data message. That is, you may try to compose this message out of the parts yourself, by hand.
However this technique is elaborated and error prone, and if you strive to be correct regarding all and relevant HTTP and MIME specifications you need to read through virtually 100 RFCs and understand them thoroughly and then painstakingly apply that specification in the underlying implementation. (Please, do yourself a favor and don't try this!)
While at the end of the day, it may turn out that it is relatively easy to compose a message out of parts yourself (there are few examples here on SO which demonstrates this), there's also the tricky part when you want utilize NSStreams as "virtual" body of a part, say a file stream which you want to use, since creating a NSData object seems too costly regarding the amount of allocated memory.
So, when you can afford to compose the complete body (consisting of multiple parts) of the HTTP message into one NSData object, the effort to accomplish this may be moderately low. Otherwise, if you cannot hold the image data and the whole body into memory, I would strongly recommend to use a third party library which is capable to use NSStream as "data sources" for body parts.
How to compose a multipart/form-data message is described in more detail in my answer here. There are also countless related questions on SO.
For a third party library which supports to construct body parts using a NSStream as data source, take a look at AFNetworking, possibly also MKNetworkKit (without supporting NSURLSession yet)

Related

Using Siesta with a non-restful API

I know this is probably a long-shot, but is it possible to use Siesta with a completely non-RESTful API? The API I have to work with (and is not in my control so sadly cannot change) requires every request to be a POST request regardless of whether it is purely retrieving data or not.
I've had a read through the question/answer here which gives me a glimmer of hope, however the big difference between that question and mine is the endpoints of each request. For the API I'm using, they're all the same :(
Every single request must POST to /api/api_post.php, and everything else is specified as a parameter supplied in the request.
Obviously I can roll my own request wrapper to handle this, but I'd love to be able to use some of the functionality provided by Siesta and not have to worry about all the annoyances of dealing with networking. Is there any way of doing this at all, or am I out of luck?
You can make your app work with an imaginary REST API, then transform that to non-restful requests underneath Siesta’s nose. (For example, GET /foo/3 might be transformed to POST /api/api_post.php with item=foo&id=3.) It’s a bit of a hassle, but it does get you the benefits of Siesta even for non-REST APIs.
There are two ways to implement this:
Use mutateRequests(…) to rewrite requests. This lets you arbitrarily alter the URLRequest before it’s sent.
Write your own NetworkingProvider. This is a bit more of a hassle, but gives more wholesale control of the rewriting. This approach might be more suitable if, for example, you need to rewrite responses as well, or if you have to turn one virtual request into multiple real ones.
More in the discussion here.

Understanding website and api urls?

I have noticed that many sites have URLs that are generated and interperable. For example there is the google search one bellow:
https://www.google.com/search?q=example+search&oq=example+search&aqs=chrome..69i57j0j69i60j0l3.2087j0j1&sourceid=chrome&ie=UTF-8
This type of pattern seems consistent accross many different web services. What is the best practice for choosing urls and how could I learn more?
If I understand your question you are referring to the key value pairs separated by ampersands, right?
This is called a GET request, which is giving information to the server through the URL. The format is website.com/path/to/page?variable1=value1&variable2=value2 etc.
The question mark indicates the beginning of the key value pair section.
POST requests serve a similar purpose, but are not sent in the URL, so they can contain more data.
Try looking here: https://www.w3schools.com/tags/ref_httpmethods.asp
This format is standard, but not essential. One could make their server interpret URLs in any way they want; however, HTML forms will automatically generate this format. This page has more info, some of which is relevant to your question: https://www.w3schools.com/html/html_forms.asp.

Website fetch, using NSURLSession and changing INPUT Field value on this site

I wanna fetch the content of a website. But to get the correct content, it is necessary to change a Input Html sroll field on the side?
Many idea how to manage with xcode?
Thanks a lot!!
Lars
If you want to retrieve the HTML that you get after filling in a HTML form, you have to identify precisely what the series of requests looks like to fetch the data. And be careful because it's often not as simple as just looking at the request that the HTML in question generates: unfortunately, it is sometimes a complex series of requests (e.g. retrieving the original HTML is often seamlessly retrieving some critical hidden form fields and/or cookies).
Bottom line, to reverse engineer the required HTTP requests, you often have to pour through HTML code and/or watch the requests with something like Charles. It often takes quite a bit of time to do this with complicated sites.
Before you invest a lot of time here, though, you should first see if the web site provider's Terms of Service permit such usage. They often strictly prohibit this sort of practice. It's much better to contact the web site provider and see if they provide a web service to retrieve the data. That's far easier and will result in a far more robust interface for your app.
But if you're forced programmatically parsing HTML, I'd refer you to How to Parse HTML on iOS on Ray Wenderlich's site.

Alamofire: Support for uploading multipart forms with text and file parts?

Alamofire now has support for uploading files via a multipart form upload.
Looking through the MultipartFormData class API, however, I do not see an obvious way of sending heterogeneous data - textural plain/json data along with the assumed binary file data. In my reading - in the current form, it seems more geared as a multi-file (binary stream) upload without support for text or json parts.
Am I missing something? How does one upload textual/json data parts along with the assumed file data parts? Is there any sample code that does this?
To be complete, I have been writing extensions to fill in some of this, but I keep feeling that there has to be an easier way (my changes require some modification to the Alamofire).
That said, and for what it's worth, here is my attempt at a clean form:
multipartFormData: { form in
form.appendBodyPart(Multipart.plain("person", text:"\(last.id)")!)
form.appendBodyPart(Multipart.json("thing", parameters:parameters)!)
form.appendBodyPart(fileURL: puppyFile, name: "file") },
Obviously a supported solution is better than a re-invented wheel, hence the question.
PS. I am posting this year as per Alamofire documentation, SO is the preferred medium for help and discussion.
This was not supported at the time of my post, but has been implemented since then, on the multipart_form branch, for the 1.3 release which is now currently available. This related issue is:
https://github.com/Alamofire/Alamofire/pull/596

How to get data from a web service?

I'm trying to write an iOS application that'll get data from a web server and display it as I want. I want to use JSON for this purpose. But as I'm absolutely new to web apps I've got no idea how I'm going to get the url to a certain feed. Now here're the two big questions:
How do I find the url to a feed provided by a web service? Is there a standard way or is it publicly or exclusively handed to the web service subscribers?
Is the format they provide data in up to their preference (like XML or JSON)? I mean, do I choose my data parsing method according to the format the web service gives data in? So that if the feed is in XML format using NSJSONSerialization class makes no sense.
The URL to use is dependent on the web service and is usually well described in the documentation.
The type of data they return and the the structure is also usually well described in the documentation.
The common bits you'll need to know are how to get to the web-service (NSURLRequest/NSURLConnection or any of the many asynchronous wrappers that are open source and available with a bit of searching), And how to deal with the the returned data - whether it's in JSON (NSJSONSerialization, JSONKit) format or XML (NSXMLParser, libxml, or any of the many open source implementations that are available and described with a bit of searching)

Resources