I've got the tagged NSURLConnection subclass, and need to fetch Image data from multiple URL-s...The idea is clear to me, but i can't start the connection properly, so that data would append into its place... here i have:
- (IBAction)sophisticatedDownload {
connectionDict = [[NSMutableDictionary dictionaryWithCapacity:news.count] retain];
for (int i =0; i<news.count; i++)
{
//init the tagged connection
if (theConnection) {
self.imageData = [NSMutableData data];
[connectionDict setObject: imageData forKey: theConnection.connID];
} else {
NSLog(#"Connection failed");
}
}
}
- (void)connection :(tagConnection *)connection didReceiveData:(NSData *)data {
[[connectionDict objectForKey:connection.connID] appendData:data];
}
- (void)connectionDidFinishLoading:(tagConnection *)connection {
NSLog(connection.connID);
What should
You can get start you connection like this -
NSString *urlString = [NSString stringWithFormat:#"http://EnterYourURLHere"];
NSURL *URL = [NSURL URLWithString:urlString];
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc]init];
[urlRequest setURL:URL];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-type"];
NSURLConnection *urlConnection = [[NSURLConnection alloc]initWithRequest:urlRequest delegate:self];
if(!urlConnection)
{
[[[UIAlertView alloc]initWithTitle:#"OOoopppssS !!" message:#"There is an error occured. Please check your internet connection or try again." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil] show];
}
But this is not good approach to download multiple images. See NSURLConnection Download multiple images to download multiple images.
Related
I have a simple asp.net web service which returns json format data. I want to send http post request with parameter for getting json data. How can I send request and get data ?
post request:
POST /JsonWS.asmx/FirmaGetir HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: length
firID=string
answer:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">string</string>
I'm trying some codes but they didn't work.
NSString *firmadi =#"";
NSMutableData *response;
-(IBAction)buttonClick:(id)sender
{
NSString *firid = [NSString stringWithFormat:#"800"];
response = [[NSMutableData data] retain];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://192.168.1.23/testService/JsonWS.asmx?op=FirmaGetir"]];
NSString *params = [[NSString alloc] initWithFormat:#"firID=%#",firid];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if(theConnection)
{
response = [[NSMutableData data] retain];
}
else
{
NSLog(#"theConnection is null");
}
}
-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)responsed
{
[response setLength:0];
NSURLResponse * httpResponse;
httpResponse = (NSURLResponse *) responsed;
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data
{
[response appendData:data];
//NSLog(#"webdata: %#", data);
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError*)error
{
NSLog(#"error with the connection");
[connection release];
[response release];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
response = [[NSMutableData data] retain];
NSString *responseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSLog(#"%#",responseString);
}
What are you doing here:
[[NSURLConnection alloc] initWithRequest:request delegate:self];
This line returns a NSURLConnection but you are not storing it. This is doing nothing for you.
You are clearing your data before you read it:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
response = [[NSMutableData data] retain]; // This line is clearing your data get rid of it
NSString *responseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSLog(#"%#",responseString);
}
Edit
-(IBAction)buttonClick:(id)sender {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://192.168.1.23/testService/JsonWS.asmx?op=FirmaGetir"]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:15];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:[#"firID=800" dataUsingEncoding:NSUTF8StringEncoding]];
self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[self.connection start];
}
#pragma NSURLConnection Delegates
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
if (!self.receivedData){
self.receivedData = [NSMutableData data];
}
[self.receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseString = [[NSString alloc] initWithData:self.receivedData encoding:NSUTF8StringEncoding];
NSLog(#"%#",responseString);
}
I suffered this problem this morning and I just figure it out now. I guess the key to your question is How to use POST method with parameter. Actually, it is quite simple.
(1) First, you should make sure your file is ready to send. Here we say it is an NSString called stringReady. We use it as a parameter in our method called postRequest (Here is not the HTTP POST parameter we want to talk about. Don't worry).
// Send JSON to server
- (void) postRequest:(NSString *)stringReady{
// Create a new NSMutableURLRequest
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.xxxxxx.io/addcpd.php"]];
[req setHTTPMethod:#"POST"];
(2) Now, we say it the parameter that the server wants to get is called "data", this is the way how to insert your parameter to the HTTP body.
// Add the [data] parameter
NSString *bodyWithPara = [NSString stringWithFormat:#"data=%#",stringReady];
See, it's how you add a parameter when using POST method. You just simply put the parameter before the file that you want to send. If you aleary konw what your parameter then you may better to check this website:
https://www.hurl.it/
This will help you to test if you are sending files properly and it will show the response at the bottom of the website.
(3) Third, we pack our NSString to NSData and sent it to server.
// Convert the String to NSData
NSData *postData = [bodyWithPara dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// Set the content length and http body
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
[req addValue:postLength forHTTPHeaderField:#"Content-Length"];
[req setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[req setHTTPBody:postData];
// Create an NSURLSession
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:req
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// Do something with response data here - convert to JSON, check if error exists, etc....
if (!data) {
NSLog(#"No data returned from the sever, error occured: %#", error);
return;
}
NSLog(#"got the NSData fine. here it is...\n%#\n", data);
NSLog(#"next step, deserialising");
NSError *deserr;
NSDictionary *responseDict = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&deserr];
NSLog(#"so, here's the responseDict\n\n\n%#\n\n\n", responseDict);
}];
[task resume];}
Hope this can help somebody who gets stuck at here.
I have a web service I am working with a url such as
//myurl/index.jsp?user_name=bob&user_pwd=new
as you can see the username has been set as "bob" and password "new". The site give this json file when entered,
[{"success":"1"}]
How do you implemented it on xcode, where when a user enters "bob" as username and "new" as password it should lead to the next controller. How do can I achieve that ?
I followed this tutorial though it's not quite the same, how do you do this. Thanks.
Use a navigation controller and set you view controller as the rootViewController. Then after the user has entered the credentials push the new view controller onto the navigation stack.
Get the value of success from json response. If it is equal to 1 then push to next controller else do nothing.
In Following code you can pass data by either GET or POST method … use any one (As You Wish)
-(void) sendRequest
{
//////////////////////////// GET METHOD /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
NSString *strURL=[NSString stringWithFormat:#"http://myurl/index.jsp?user_name=bob&user_pwd=new"];
self.request=[NSURLRequest requestWithURL:[NSURL URLWithString:strURL]];
self.nsCon=[[NSURLConnection alloc] initWithRequest:request delegate:self];
//////////////////////////// POST METHOD /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
NSString *postString = [NSString stringWithFormat:#"&user_name=bob&user_pwd=new"];
NSString *url = [NSString stringWithFormat:#"http://myurl/index.jsp/"];
self.request =[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[self.request setHTTPMethod:#"POST"];
[self.request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(self.nsCon)
{
self.receivedData=[[NSMutableData alloc] init];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Error",#"") message:NSLocalizedString(#"Not Connected !!",#"") delegate:nil cancelButtonTitle:NSLocalizedString(#"OK",#"") otherButtonTitles:nil];
[alert show];
[alert release];
}
}
#pragma mark -
#pragma mark - Connection Delegate Methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[self.responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[GeneralClass stopHUD];
NSLog(#"Connection failed.");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Error",#"") message:NSLocalizedString(#"Connection failed!",#"") delegate:nil cancelButtonTitle:NSLocalizedString(#"OK",#"") otherButtonTitles:nil];
[alert show]; alert = nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *responseString = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
NSMutableDictionary *receivedData = [responseString JSONValue];
if([[receivedData objectForKey:#"success"] isEqualToString:#"1"])
{
MainDetailViewController *mdController = [[MainDetailViewController alloc] init];
[self.navigationController pushViewController:mdController animated:YES];
}
else
{
NSLog(#"%#",receivedData);
}
}
Post login data
NSString *soapMsg = [NSString stringWithFormat:#"&data={\"LoginUser\":[{\"UserName\":\"%#\",\"Password\":\"%#\"}]}",firstname.text, password.text];
NSHTTPURLResponse *response;
NSData *myRequestData = [ NSData dataWithBytes: [ soapMsg UTF8String ] length: [ soapMsg length ] ];
NSString *postLength = [NSString stringWithFormat:#"%d", [myRequestData length]];
NSMutableURLRequest *request = [ [ NSMutableURLRequest alloc ] initWithURL: [ NSURL URLWithString:#"http://myurl/index.jsp"]];
[request setHTTPMethod: #"POST" ];
[request setHTTPBody: myRequestData ];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody: myRequestData];
NSURLConnection *myConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
Receive and vaild json data
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseString = [[NSString alloc] initWithData:WebXmlData encoding:NSUTF8StringEncoding];
NSDictionary *results = [responseString JSONValue];
BOOL success = [[results objectForKey:#"success"] boolValue];
if (success) {
ViewController *viewController =[[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
[self.navigationController pushViewController:viewController animated:YES];
}
}
Not quite the answer you are looking for but this is more a recommendation for what should you use.
I use github link for Network related activities.
They have nice documentation and very easy to use (uses blocks)
NSDictionary *paramsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:#"user",#"client_id",#"password",#"new", nil];
[[YourAFHttpClientExtenstion sharedInstance] postPath:LOGIN_PATH parameters:paramsDictionary success:^(AFHTTPRequestOperation *operation, id responseObject) {
//handle success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// handle error.
}];
YourAFHttpClientExtenstion is extending AFHttpClient and adds a convening method of shared instance and implements initWithBaseUr:
I am new in objective C. I have done app in j2me and android using below code. I m trying same to consume web service through objective C but not getting success. It will be great if anyone guide me.
Thanks.
public static String RetriveData(String myStr)
{
String result1 = "-1";
Object ob1 = new Object();
ob1 =MyStr;
SoapObject rpc = new SoapObject("http://abcd.com/", "MyMethod");
rpc.addProperty("Mystr", ob1.toString());
try
{
Object strdata = new HttpTransport("http://11.22.33.44/myService.asmx", "http://abcd.com/" + "MyMethod").call(rpc);
result1 = strdata.toString().trim();
}
catch (Exception ex)
{
System.out.println("In catch block :" +ex);
}
return result1;
}
I am trying same through objective C as below but getting error.
NSURL *url = [NSURL URLWithString:#"http://11.22.33.44/MyService.asmx"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d", [soapMessage length]];
//
//[theRequest addValue: #"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[theRequest addValue: #"http://abcd.com/MyMethod" forHTTPHeaderField:#"SOAPAction"];
//[theRequest addValue: msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest addValue:#"MyStr" forHTTPHeaderField:#"MyStr"];
[theRequest setHTTPMethod:#"POST"];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if( theConnection )
{
webData = [[NSMutableData data] retain];
}
else
{
NSLog(#"theConnection is NULL");
}
[nameInput resignFirstResponder];
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[webData setLength: 0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[webData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"ERROR with theConenction");
[connection release];
[webData release];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"DONE. Received Bytes: %d", [webData length]);
NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:
[webData length] encoding:NSUTF8StringEncoding];
NSLog(theXML);
[theXML release];
if( xmlParser )
{
[xmlParser release];
}
xmlParser = [[NSXMLParser alloc] initWithData: webData];
[xmlParser setDelegate: self];
[xmlParser setShouldResolveExternalEntities: YES];
[xmlParser parse];
[connection release];
[webData release];
}
My personal recommendation is to use ASIHttpRequest. I consume web services (both .NET and PHP) with it and it seems much easier and straightforward to use in most cases.
Just include the ASIHttpRequest classes and the MBProgressHUD (If you want to use it)
Here is what I use to do it:
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = #"Connecting to Server";
// Start request
NSURL *url = [NSURL URLWithString:#"http://mydomain/MyWebService.asmx/MyMethod"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setValidatesSecureCertificate:NO];
// Now setup the Request
[request setPostValue:#"MyValue1" forKey:#"WebServiceArg1"];
[request setPostValue:#"MyValue2" forKey:#"WebServiceArg2"];
[request setDelegate:self];
[request startAsynchronous];
Now use the delegate methods to check and consume the response from the web service:
#pragma mark - ASIHttpRequest Delegate Methods
- (void)requestFinished:(ASIHTTPRequest *)request
{
[MBProgressHUD hideHUDForView:self.view animated:YES];
if (request.responseStatusCode == 200) {
NSString *responseString = [request responseString];
// Do something with this, create an array or dictionary depending on how the return data is structured (this assumes you are using a JSON formatted return string btw
}
else {
// Standard UIAlert Syntax
UIAlertView *myAlert = [[UIAlertView alloc]
initWithTitle:#"Connection Error"
message:#"My Message"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[myAlert show];
}
} else {
NSLog(#"Error finishing request");
}
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
[MBProgressHUD hideHUDForView:self.view animated:YES];
// Standard UIAlert Syntax
UIAlertView *myAlert = [[UIAlertView alloc]
initWithTitle:#"Connection Error"
message:#"Unable to establish connection"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[myAlert show];
NSError *error = [request error];
NSLog(#"%#",error.localizedDescription);
}
There are many ways to do it but this is what I would use.
I'm struggling sending POST data to a server and receiving the correct response. I started by using setHTTPBody but moved to setHTTPBodyStream when I wasn't getting the correct server response for certain POST data and I read setHTTPBody has a memory leak on earlier iOS versions. The problem is setHTTPBodyStream causes the error - "Operation couldn't be completed. Connection reset by peer".
Here's the code:
NSMutableURLRequest * request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"secret but correct url goes here"] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10.0];
[request setHTTPMethod: #"POST"];
[request setHTTPBodyStream: [NSInputStream inputStreamWithData: [[NSString stringWithFormat:#"username=%#&password=%#&score=%i",[(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)ogl_view->username, NULL, CFSTR("?=&+"), kCFStringEncodingUTF8) autorelease],[(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)text_field.text, NULL, CFSTR("?=&+"), kCFStringEncodingUTF8) autorelease],ogl_view->score[0]] dataUsingEncoding:NSUnicodeStringEncoding]]];
NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest: request delegate:self];
if (connection){
received_data = [[NSMutableData data] retain];
ogl_view->section = CURLING_PROCESS_CREDENTIALS;
}else{
ogl_view->section = CURLING_LOGIN_OR_REGISTER;
UIAlertView *connection_alert = [[UIAlertView alloc] initWithTitle:#"Error" message: #"Can't connect to server" delegate:self cancelButtonTitle:#"Close" otherButtonTitles: nil];
[connection_alert show];
[connection_alert release];
}
I can verify the server is fine and it works when I try a web-browser.
Can somebody get me on the right track to sending data with HTTP and the POST method correctly?
Thank you for any help.
Try using this (with your own values):
NSString* post = #"username=myUser&password=myPass&score=20"; //customize this
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
NSURL *url = [NSURL URLWithString:#"http://my.request.com"]; //customize this
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
[request setTimeoutInterval:timeout];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
You'll then need to implement the NSURLConnectionDelegate methods:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)remoteData;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
In the end, remember to release the NSURLConnection.
Edit: Didn't see that you wrote that setHTTPBody leaks... never seen that happening. Anyway, here is some code that should work...
I am new to iphone development.I have posted the URL with the user-name and password. I am able to print the data in "connection didReceiveData " method.But i see "connection didReceiveData" method called twice.I don't know ,where i am going wrong. Here is my code
- (void)viewDidLoad {
[super viewDidLoad];
NSString *post = [NSString stringWithFormat:#"&domain=school.edu&userType=2&referrer=http://apps.school.edu/navigator/index.jsp&username=%#&password=%#",#"xxxxxxx",#"xxxxxx"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d",[postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://secure.school.edu/login/process.do"]]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Current-Type"];
[request setHTTPBody:postData];
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
if(conn)
{
NSLog(#"Connection Successful");
}
else
{
NSLog(#"Connection could not be made");
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data{
NSString *string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"the data %#",string);
}
The whole HTML page is printed twice in the console.So please help me out.Thanks.
You may receive the response data in chunks, which is why NSURLConnection's documentation states:
"The delegate should concatenate the contents of each data object delivered to build up the complete data for a URL load."
Use an instance of NSMutableData for this and only process the complete data once you receive the -connectionDidFinishLoading: message.
As MacOS Developer Library states, connection:didReceiveData can be called multiple times if data is received in chunks. That means you have to save all the chunks in some variable and do data processing in connectionDidFinishLoading method. e.g.
NSMutableData *receivedData = [[NSMutableData alloc] init];
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Append the new data to receivedData.
[receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do something with the data, for example log:
NSLog(#"data: %#", [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding]
}