iOS app http post/get request - ios

I need some tutorial, how to use HTTP POST (or GET) request from my iOS app. I want to send one string to my server and than write it to database. I've found this piece of code:
NSString *post = #"key1=val1";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:#"http://www.nowhere.com/sendFormHere.php"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
I add it to UIAction button, but it don't send anything to my server. On my server, I have a PHP script that takes that "key1" from post and than it write it to db.
<?
$postr = $_POST["key1"];
$con0 = mysql_connect("server","db","pass");
mysql_select_db("table", $con0);
mysql_set_charset('utf8',$con0);
mysql_query("INSERT INTO tok (token) VALUES ('$postr')");
mysql_close();
?>
Can anybody tell me what I am doing wrong?

Look at AFnetworking and work through their api. Sending a post request using the api is very fast, and is what most apps use for web connectivity.
Also please dont be discouraged by sarcastic comments. You should tag iOS projects as iOS and not xcode (unless you actually need help with the actual program xcode). But I don't think it's productive to harrass everyone that comes in and makes this mistake. A more tactful way would be a personal message as opposed to a public retort
https://github.com/AFNetworking/AFNetworking

AFNetworking is a very powerful library that can help you to reduce the effort on create your HTTP requests, you can find several examples on how to use this library on its github page.
You may find this answer useful for your needs: AFNetworking Post Request

Related

SOAP Client Generator for Objective-C from WSDL?

I'm stuck on a SOAP integration project. I need to call some SOAP Web Services from an iPad app.
I have the WSDL, and I need to generate the Objective-C classes to invoke the service calls.
The Mac developer library has an "Example: Calling a SOAP Operation with HTTP Authentication", but the sample code it links to is broken (SOAP_AuthExample.dmg, 404).
The Web Services Core Programming Guide even says (emphasis added):
"Currently, OS X provides no high-level support for extracting SOAP functions from WSDL files. You can use NSXMLParser to read a WSDL file into memory from a URL, however. It is then relatively simple to search the file for a particular method name or to find a URL associated with a service. With a bit more effort, you can extract method names, data types, and parameter names to build a SOAP call. You can then use the Web Services Core framework to make SOAP calls and parse the responses."
I've also found the following three generators; however, the first is throwing an error about some missing files, the second's code generates and endless stream of ARC errors when I try to build (and a refactor is not working), and the third is paywalled.
http://easywsdl.com/
https://code.google.com/p/wsdl2objc/
http://sudzc.com/
Can anyone steer me in the right direction?
I was in your same situation a couple of months ago, and I'm currently working in an iPad app that requires to connect to a SOAP service. I already have the classes, but they are specific for my project and I'm not authorised to share it. However, I'm making a more generic Objective-C class (in any case the final solution for all the SOAP servers) to share it with the world on Github.
First of all you have to set the SOAP message. It has a common structure like this:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
// here comes the header information: credentials, connection information. If needed, of course
</soap:Header>
<soap:Body>
// here comes the request parameters. In my case, these parameters are related to a resource called SOAPAction (That identifies the method to be called. e.g getListOfClients). I don't know if it is the same in all servers
</soap:Body>
</soap:Envelope>
I say to you, the company for which I'm making the app, has provided me with the methods and authentication information. I don't know if this is your case, but you have here a general glance of what to do.
I use AFNetworking to send the request, in this way:
NSString *messageLength = [NSString stringWithFormat:#"%lu", (unsigned long)[msg length]];
NSURL *requestURL = [NSURL URLWithString:self.requestURL];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:requestURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30];
[theRequest addValue:[requestURL host] forHTTPHeaderField:#"Host"];
[theRequest addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[theRequest addValue:soapAction forHTTPHeaderField:#"SOAPAction"];
[theRequest addValue:messageLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody:[msg dataUsingEncoding:NSUTF8StringEncoding]];
// sending the request
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:theRequest];
operation.responseSerializer = [AFHTTPResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *xml = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"Take the data master Yoda: %#", xml);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Bad SOAP server!. Error: %#", error.description)
}];
[[NSOperationQueue mainQueue] addOperation:operation];
self.requestURL is the server URL, obviously. If the request was successful, then you have the server's xml response ready to parse. If not, a request error description otherwise.
This page helped me a lot to find out a solution for some issues that I encountered, and it is related to the website http://sudzc.com/ that you quotes above:
http://blog.exadel.com/working-with-ios-and-soap/
I hope this helps in any way.

Authentication Issue with REST call for iOS

I am currently trying to make a REST call from an iOS device. My code is below
NSString *restCallString = [NSString stringWithFormat:#"MyURL"];
NSURL *url = [NSURL URLWithString:restCallString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
[request setHTTPMethod:#"GET"];
[request addValue:Value1 forHTTPHeaderField:#"Header1"];
[request addValue:Value2 forHTTPHeaderField:#"Header2"];
[request setURL:[NSURL URLWithString:restCallString]];
#try{
_currentConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
#catch(NSError *e){
NSLog(#"%#", e.description);
}
Whenever this is called, I get the following error: Authentication credentials were not provided. However, what confuses me is that if I send an identical GET request via a HTTP web console, it works perfectly. In other words, using the same URL and the same 2 header-value pairs, I get a valid response on a web console, and see no authentication errors. What could be causing this?
You are setting the HTTP headers. This won't work, because the HTTP header is not contained in $_GET or $_POST because they're are not content, but description of the content expected.
Try this instead:
NSURL *url = [NSURL URLWithString:[restCallString stringByAppendingFormat:#"?Header1=%#&Header2=%#", Value1, Value2]];
Of cause you have to be aware that the URL is RFC 1738 compliant.
if I send an identical GET request via a HTTP web console, it works perfectly
I suspect your web console is leveraging SessionAuthentication — i.e. If you're already logged in to your site in your browser the API will authenticate you based on your session cookie.
Django Rest Framework provides various authentication methods and there are third-party options too. The simplest to get going is probably the provided Token Auth method.
Make sure this is enabled. Create a token in the admin (or via the provided view) and make sure you've set the Authorization header. It needs to look like this:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
So your Objective-C will go something like:
[request addValue:[NSString stringWithFormat:#"Token %#", yourToken]
forHTTPHeaderField:#"Authorization"];
Hopefully that gets you started.

GetListCollection SOAP request always returns root collection in SharePoint 2010

I'm working on a mobile share point application. I'm facing issue while trying to retrieve list collection of a sub-site. Went through so many blogs and tried different approaches but of no use.
My Home site has two sub sites (SampleSubsite & SampleSubsite2) in which I've document libraries created.
The GetSite web service defined in /_vti_bin/SiteData.asmx returns the following response.
Url = "http://sp2010.lab.xyz.local:20852";
Url = "http://sp2010.lab.xyz.local:20852/SampleSubsite";
Url = "http://sp2010.lab.xyz.local:20852/SampleSubSite2";
Now, when I try to fetch the List Collection of a sub site (in this case for example SampleSubsite), I'm constructing the URL as follows.
http://sp2010.lab.xyz.local:20852/SampleSubsite/_vti_bin/Lists.asmx
I've tried multiple options but of no use. (Test is the root site name). In all the below 3 cases, I get the root collection itself.
http://sp2010.lab.xyz.local:20852/Sites/SampleSubsite/_vti_bin/Lists.asmx
http://sp2010.lab.xyz.local:20852/Sites/Test/SampleSubsite/_vti_bin/Lists.asmx
http://sp2010.lab.xyz.local:20852/Test/SampleSubSite/_vti_bin/Lists.asmx
Could anyone through some light on it.
Code snippet Below:
#define kFetchListCollectionXML #"<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
#"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\
#"<soap:Body>"\
#"<GetListCollection xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\" />"\
#"</soap:Body>"\
#"</soap:Envelope>"\
- (void)getListCollectionOfSite:(NSString *)sitePath {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/_vti_bin/Lists.asmx",sitePath]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"http://schemas.microsoft.com/sharepoint/soap/GetListCollection" forHTTPHeaderField:#"SOAPAction"];
[request setValue:[NSString stringWithFormat:#"%ld",(unsigned long)kFetchListCollectionXML.length] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:[kFetchListCollectionXML dataUsingEncoding:NSUTF8StringEncoding]];
[self performConnectionWithRequest:request];
}
The issue worked fine after creating the Alternate Access Mapping and creating the request for the the subsites as follows:
For subsite "SampleSubsite" with URL "http://sp2010.lab.xyz.local:20852/SampleSubsite", the request URL should be constructed as follows.
http://sp2010.lab.xyz.local:20852/SampleSubsite/_vti_bin/Lists.asmx
I was struggling with this using the New-WebServiceProxy cmdlet. The problem went away when I added ?WSDL to the end of the query string, as suggested here http://blogs.msdn.com/b/powershell/archive/2010/06/24/using-new-webserviceproxy-to-get-modify-and-add-items-to-a-list-in-sharepoint-2007.aspx

Disqus Password Credentials OAuth

I'm trying to authenticate a user in my iOS app but all I get is a 400 error.
According to the documentation, "this type of flow is restricted to approved applications only, so you must request access first".
So how do I approve my application to be able to accomplish this flow?
Part of my request:
NSURL *url = [NSURL URLWithString:#"https://disqus.com/api/oauth/2.0/access_token/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:WS_TIMEOUT];
NSString *strAuth = [NSString stringWithFormat:#"%#:%#", username, password];
NSString *strAuthBase64 = [[strAuth dataUsingEncoding:NSUTF8StringEncoding] base64EncodedString];
NSString *postString = [NSString stringWithFormat#"grant_type=password&client_secret=%#&client_id=%#&scope=read,write", DISQUS_SECRET, DISQUS_KEY];
[request addValue:[NSString stringWithFormat:#"Basic %#", strAuthBase64] forHTTPHeaderField:#"Authorization"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
Thanks in advance.
This is something we'd have to enable for your application from our end. However, I'd instead recommend hosting a page to handle the authentication with the standard server-side flow. You can then pull the access token and other variables from the page into your application after the user has authorized.
The reason is so you don't have to deal with form validation, error messaging, and can take advantage of our updates to the form without touching your code.
Some server-side OAuth examples in PHP and Python can be found on this page: https://github.com/disqus/DISQUS-API-Recipes/tree/master/oauth
Try this library which solves Disqus authorization issue in a slick manner. Really nice solution https://github.com/moqod/disqus-ios

iOS - REST Client works fine while NSURLRequest returns NULL

I'm trying to download a file from a cloud via a GET HTTP request, and in my REST Client (Postman for Chrome) I get the results as expected, but when I pass the request in iOS, I get a NULL response. What could be the problem?
In my REST Client, I pass the URL as http://myserver.com/api/download.json?filepath=/&fileid=document:1pLNAbof_dbXGn43GtMNafABMAr_peTToh6wEkXlab7U&filename=My Info.doc with a header field for a authorization key, and it works perfectly fine.
While in iOS, if I do such a thing:
[request setURL:[NSURL URLWithString:URLString]]; // I tried even to hardcode the
// URLString to be one of the
// working URLs from the Postman
// Client, doesn't work as well.
[request setHTTPMethod:#"GET"];
NSData* response = [NSURLConnection sendSynchronousRequest:request
returningResponse:&urlResponseList
error:&requestErrorList];
response is null, and I get a status code 500.
Anyone know how to make this work? Thanks.
it looks like your URL has a space in it, you'll need to escape that before sending the string to NSURL.
it would also be helpful to know what the full error from your server is if this doesn't work. what does requestErrorList contain?
but if the only problem is the non-escaped characters something like this should work.
NSString *encodedString = [URLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[request setURL:[NSURL URLWithString:encodedString];
An HTTP status code 500 occurs when the webservice is not able to handle your request. An internal error occured.
Try to add some more details to your request.
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];

Resources