Any alternative to NSURL? - ios

A client is pondering development of an iPhone and iPad app and has asked an odd question: Is there any way to send data from an iOS device to a server other than using NSURL?

I think you could try using a POST request
responseData = [[NSMutableData data] retain];
NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:[NSURL URLWithString:#"http://www.domain.com/your/servlet"]];
NSString *params = [[NSString alloc] initWithFormat:#"foo=bar&key=value"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
That way the data would go inside the body of the request and not on the URL itself

The NSURL API isn't a way of getting data from a server. It's just a class for storing a URL. I suppose if you really want to avoid NSURL as much as possible, you could store URLs in an NSString, and then use appropriate APIs to convert it into an NSURL right before you use it.
To get data from a server, you would use either the NSURLSession API (modern) or NSURLConnection API (kind of crufty). Either is a fairly straightforward way to fetch data from an HTTP or HTTPS URL.
If you don't want to use either of those URL fetching APIs for some reason, you can write your own code using sockets or grab libcurl (MIT license) and link it into your app. Be aware that if you write your own socket code or use libcurl, assuming you're writing code for iOS, you'll need to occasionally use high-level APIs such as NSURL or CFHost to wake up the cellular radio.

Related

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.

ASIHTTPRequest addRequestHeader issue

I am using ASIHttpRequest and make use GET method to send header to server. I call method addRequestHeader like this
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request addRequestHeader:#"myHeader" value:#"abc"];
It's not working. But if I use NSMutableURLRequest to add header and request to server, it works.
I don't know anything wrong when calling addRequestHeader methods for ASIHTTPRequest library.
Have anyone seen this issue?
Wow ok so, yeah if this is a new app, please do NOT use ASIHttpRequest. It has long been supplanted by the delightful AFNetworking.
If this is an existing application, you really should work on a migration plan off ASI.
However, in an attempt to actually answer your question - that is the appropriate setup per the documentation, and is how I used to use it. My guess is something is broken under the covers and judging from a basic google request, there are issues with iOS 7 including memory leaks and requests just failing.
You can do it via NSURLRequest
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.abc.com"]];
NSMutableURLRequest *mutableRequest = [request mutableCopy];
[mutableRequest addValue:#"AAA" forHTTPHeaderField:#"Hello-there"];
request = [mutableRequest copy];
NSLog(#"%#", request.allHTTPHeaderFields);
Hope this helps .. :)

iOS/Restkit application design

I'm currently developing an application for iOS that is backed by rails. For the communication between iOS and rails i use RESTkit framework since it takes away a lot of work!
I have some doubts on how to manage the code when it starts to grow! How do you design your applications when you use RESTKit? What kind of data layer do you provide to your controllers to perform different actions?
Thanks
I am not aware of what your goal is with the application that your building in.But to start with i suggest you to create your own custom class(for example: Click this link,which indeed accepts the request(might be POST/GET/PUT) that your making and throws you the details in json format.
On the server side,create the REST api(i prefer php) bridge such that you can able to access the server database.
To start with make login authentication test using POST method(i prefer this because its more secured).
After the login page,i assume you want to show the list of data related to rail,then use UITableView/UICollectionView/Custom GridView.It depends on your requirement.And use the asynchronous approach to send the request but below i haven't used that way ;-)
Example: For login authentication
NSString *post =[[NSString alloc] initWithFormat:#"userName=user&password=pwd"];
NSURL *url=[NSURL URLWithString:#"Your URL/authenticate"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];**
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPBody:postData];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if( theConnection )
{
receivedData = [NSMutableData data];
}
else
{
NSLog(#"theConnection is NULL");
}
NOTE: Always try to return the response in json format.
Q: WHY REST-API WITH JSON? WHY NOT SOAP?
==> Many enterprises are creating mobile applications for their internal staff, for their customers, or both. These applications need access to data, business rules, and business processes. For architectural and security reasons these applications are typically built to access remotes services that provide the data and functionality that are required by the users. That's why All of Yahoo's web services use REST.
-FASTER: REST is almost always going to be faster.
-LOW BANDWIDTH: REST is much more lightweight. For mobile devices even with low bandwidth & network, Restful service works well for mobile devices.
-LOW MEMORY CONSUMPTION: The important/must thing in the mobile devices is how we handle the memory when running our application. REST always uses less memory without any unwanted xml strings.
Concerning REST or SOAP, the last one is indeed really heavy for mobile platform and not so easy to implement. SOAP requires XML too and cannot be used with JSON. Whereas with REST you can use JSON or XML and easily implement it on mobiles with RESTKit (http://restkit.org/), for security we can use an SSL connection with HTTPS and a signed certificate.
Source: http://en.wikipedia.org/wiki/Representational_state_transfer
I believe that the information what i have given above is still not enough,you need to do a google a bit.(http://www.restapitutorial.com)
I usually prefer to create a singleton data controller which provides an API in terms of the model objects and the human understandable operation being performed (getPost, addCommentToPost, createPost, ...). This gives one place that controllers go to get data and means I don't need to pass the data controller around. It also means that all of the mappings are in one place and are isolated from the rest of the code (so when the server changes I don't need to change any code in the controllers, just the code which maps into the model objects).

What is the easiest way to make an HTTP GET request with IOS 5?

I am trying to send a suggestion from my app to a php file on my web server, I have tested the php script in my browser which sends an email to the user and stores the suggestion in my database, which all works fine.. And when running the following script I get a successful connection via IOS however i do not receive the results in my database..
NSString *post = [NSString stringWithFormat:#"http://blahblah.com/suggest.php?s=%#&n=%#&e=%#", suggestion, name, email];
// Create the request.
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:post]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
NSLog(#"Connection establisted successfully");
} else {
NSLog(#"Connection failed.");
}
I have checked all the strings and encoded all spaces with %20 etc.. Can anyone see any glaringly obvious reason why my script won't work?
What is the easiest way to make a HTTP request from my app without opening safari?
You problem is that you're creating the connection, but are not sending the actual "connect" request. Instead of
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
try using this piece of code:
NSURLResponse* response = nil;
NSData* data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil]
This is quick and dirty solution, but keep in mind that while this connection is in progress, your UI thread will appear to be frozen. The way around it is to use asynchronous connection method, which is a bit more complicated than the above. Search web for NSURLConnection send asynchronous request - the answer is there.

How to write data to the web server from iPhone application?

I am looking forward for posting some data and information on the web server through my iPhone application. I am not getting the way to post data to the web server from iPhone sdk.
It depends in what way you want to send data to the web server. If you want to just use the HTTP POST method, there are (at least) two options. You can use a synchronous or an asynchronous NSURLRequest. If you only want to post data and do not need to wait for a response from the server, I strongly recommend the asynchronous one, because it does not block the user interface. I.e. it runs "in the background" and the user can go on using (that is interacting with) your app. Asynchronous requests use delegation to tell the app that a request was sent, cancelled, completed, etc. You can also get the response via delegate methods if needed.
Here is an example for an asynchronous HTTP POST request:
// define your form fields here:
NSString *content = #"field1=42&field2=Hello";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.example.com/form.php"]];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setHTTPBody:[content dataUsingEncoding:NSISOLatin1StringEncoding]];
// generates an autoreleased NSURLConnection
[NSURLConnection connectionWithRequest:request delegate:self];
Please refer to the NSURLConnection Class Reference for details on the delegate methods.
You can also send a synchronous request after generating the request:
[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
If you pass a NSURLResponse ** as returning response, you will find the server's response in the object that pointer points to. Keep in mind that the UI will block while the synchronous request is processed.

Resources