application is getting flashed while calling web services in iOS - objective-c

i am using Soap web services to download the data from server. Device is getting flashed like flash light while downloading data. i am using synchrous request to get the data.
I could nt find out the reason why its getting flashed.
Please help me out, Thanks in advance.
Here is the code:
NSString *msgString = [[NSString alloc] initWithFormat:#"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xmlns:xsd=\"http://http://www.w3.org/2001/XMLSchema\" "
"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
"<soap:Body>"
"<GetCategories xmlns=\"http://tempuri.org/\"/>"
"</soap:Body>"
"</soap:Envelope>"];
NSURL *url = [NSURL URLWithString:[DefaultSettings getLink]];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
//---set the various headers---
NSString *msgLength = [NSString stringWithFormat:#"%d", [msgString length]];
[req addValue:#"text/xml" forHTTPHeaderField:#"Content-Type"];
[req addValue:#"http://tempuri.org/GetCategories" forHTTPHeaderField:#"SOAPAction"];
[req addValue:msgLength forHTTPHeaderField:#"Content-Length"];
//---set the HTTP method and body---
[req setHTTPMethod:#"POST"];
[req setHTTPBody:[msgString dataUsingEncoding:NSUTF8StringEncoding]];
NSError *error;
NSURLResponse *response;
NSData *webData = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
xmlParser = [[NSXMLParser alloc] initWithData:webData];
[xmlParser setDelegate:self];
[xmlParser setShouldProcessNamespaces:NO];
[xmlParser setShouldReportNamespacePrefixes:NO];
[xmlParser setShouldResolveExternalEntities:YES];
[xmlParser parse];
after this, i am parsing the data. In the same method, i am calling 8 soap services one by one.

It's because you are using
[NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];.
This method fires a synchronous connection and block the thread until you get a response from the server.
You can use wether
- (id)initWithRequest:(NSURLRequest *)request delegate:(id < NSURLConnectionDelegate >)delegate startImmediately:(BOOL)startImmediately
to start an asynchronous connection or start your previous method from another thread using NSThread
If your app is doing more than one request, you should create a RequestManager that will perform all the requests. This Manager will implements the NSURLConnectionDelegate. Then create your own protocol and implement it in your ViewController subclasses.
for instance, in your protocol you can add a method called
- (void)request:(int)requestID didFinishWithResult:(NSData *)data
the requestID is used to identify your request.
Call this method when any request finishes.

Related

NSURLConnection and pointer types bug

Here the problem, i'am using a http request, but when i use NSURLConnection to get my xml file and set a NSString *xml variable with that xml file i get a block pointer error if i return it. But if i take NSString *xml and send it to a method it tells me nothing and the xml variable is well set. Also if i return at the end of my method the variable, i get a nil at the parent calling method. How can i fix this because the return of the variable is needed. Thanks for any help, and here is my code :
The error :
incompatible block pointer types sending 'NSString *(^)NSURLResponse *, NSData *, NSError *)'to parameter of type 'void(^)(NSURLResponse *,NSData *, NSError *)'
- (NSString *)restTestRequester: (NSString *)uriRequested serviceUri:(NSString *)sUri parameters:(NSString *)uriParameters technique:(NSString *)requestTechnique {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *l_api_key = [prefs stringForKey:#"globalPublicK"];
NSString *l_secret_key = [prefs stringForKey:#"globalSecretK"];
l_uri = [NSString stringWithFormat:#"%#/%#", uriRequested, sUri];
NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:l_uri]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60.0];
[theRequest setHTTPMethod:requestTechnique];
[theRequest setValue:#"application/xml" forHTTPHeaderField:#"Accept"];
[theRequest setValue:#"application/x-www-form-unrlencoded" forHTTPHeaderField: #"Content-Type"];
[theRequest setValue:l_api_key forHTTPHeaderField: #"EMApikey"];
[theRequest setValue:[self hmacsha1:l_uri secret:l_secret_key] forHTTPHeaderField: #"EMRequestHash"];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if( theConnection )
{
[NSURLConnection sendAsynchronousRequest:theRequest
queue:[NSOperationQueue mainQueue]
incompatible block pointer types error--> completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
here ---->xml = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]
autorelease];
works--->[self myMethod:xml];
doesn't work---> return(xml);
}
];
}
else
{
NSLog(#"theConnection is NULL");
}
[theConnection release];
equals nil variable returned-->return xml;
}
I think that the problem is in async call, U still don't have anything in xml when U trie to return it, your method returns before sendAsynchronousRequest finishes.
USE:
NSData* data=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString* xml = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
It will wait until U get the result back.
You have several major problems. For starters, your block executes after your connection finishes. The code after the block executes after the connection STARTS. This means you releasing the connection before it finishes.
Additionally, you are creating NSURLConnection *theConnection, but never using it. When you call -sendAsynchronousRequest:queue:completionHandler: it creates a completely new handler.
The specific error you are getting is because you cannot return a value from the block. The fact that you are trying indicates that you do not have a full grasp of exactly what is happening. There are many good references around the Internet about blocks and asynchronous programming. I suggest you find one.
NSURL *targetURL = [NSURL URLWithString:l_uri];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:targetUrl
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60.0];
[theRequest setHTTPMethod:requestTechnique];
[theRequest setValue:#"application/xml" forHTTPHeaderField:#"Accept"];
[theRequest setValue:#"application/x-www-form-unrlencoded" forHTTPHeaderField: #"Content-Type"];
[theRequest setValue:l_api_key forHTTPHeaderField: #"EMApikey"];
[theRequest setValue:[self hmacsha1:l_uri secret:l_secret_key] forHTTPHeaderField: #"EMRequestHash"];
[NSURLConnection sendAsynchronousRequest:theRequest
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
// Here the connection is complete and the data is usable.
NSString *xml = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[self myMethod:xml];
[xml release];
}];
// Here the Connection has only been queued and no data is available.

Objective-C Asynchronous NSURLConnection to Ruby Server

I am having trouble sending asynchronous NSURLRequests to a Ruby server. When I use the following, a connection is never made:
self.data = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://domain.com/app/create_account.json"]];
[request setHTTPMethod:#"POST"];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request addValue:#"form-data" forHTTPHeaderField:#"Content-Disposition"];
[request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
However, when I exchange the last line with:
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
Everything works great. But I do need to make this connection asynchronously...
EDIT-Working Example
NSURL *url = [NSURL URLWithString:#"http://domain.com/app/create_account.json"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:data forKey:#"data"];
[request setDelegate:self];
[request startAsynchronous];
It seems RESTful services need their own third party framework in this case.
you can try following using restkit api
- (void)sendAsJSON:(NSDictionary*)dictionary {
RKClient *client = [RKClient clientWithBaseURL:#"http://restkit.org"];
// create a JSON string from your NSDictionary
id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType:RKMIMETypeJSON];
NSError *error = nil;
NSString *json = [parser stringFromObject:dictionary error:&error];
// send your data
if (!error)
[[RKClient sharedClient] post:#"/some/path" params:[RKRequestSerialization serializationWithData:[json dataUsingEncoding:NSUTF8StringEncoding] MIMEType:RKMIMETypeJSON] delegate:self];
}
referance:
https://github.com/RestKit/RestKit/wiki/Tutorial-%3A-Introduction-to-RestKit
https://github.com/RestKit/RestKit/wiki/Posting-NSDictionary-as-JSON
Thanks
Nikhil

Calling Webservice in iPhone application?

I am using soap webservice.
In that i am calling one webmethod. Here if i call from one part of my code is working fine and calling service successfully and retriving data successfully.
But if i calling same method from another part of code of same class is not responding and not getting any data from service. Why is going like that can any one help me please.
Thanks in advance
In detail.m
-(void) downloadAndParse:(NSMutableURLRequest *)sentReq {
conn = [[NSURLConnection alloc] initWithRequest:sentReq delegate:self];
if (conn) {
webData = [[NSMutableData data] retain];
}
}
-(void)fullBarcodeSearch:(NSString *)code {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
URLRequest *r = [[URLRequest alloc] init];
NSMutableURLRequest *req = [r fullBarcodeSearch:code];
[r release];
[self downloadAndParse:req];
}
In URLRequest.m
-(NSMutableURLRequest *) addHeaderToSoapXML:(NSString *) soapMsg {
NSURL *url = [NSURL URLWithString:str];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d",[soapMsg length]];
[req addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"content-type"];
[req addValue:msgLength forHTTPHeaderField:#"Content-Length"];
[req setHTTPMethod:#"POST"];
[req setHTTPBody:[soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
return req;
}
if service not called then i am getting error like this
*oid _WebThreadLockFromAnyThread(bool), 0x6958130: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread.*
Please any one help me
Thanks in advance
You need an NSURLConnection to execute the NSURLRequest. Lookup the Apple Docs on the class.
Something like:
[urlConnection sendSynchronousRequest:urlRequest returningResponse: &urlResponse error:&error]

Asynchronous POST to server

The goal is to do a simple username/password authentication by querying a database. Until the connection is working decently my php destination file simply has following code:
echo "Posted: " . $_POST['email'];
The code to do this synchronously is this:
NSString *post = [[NSString alloc] initWithFormat:#"email=%#&password=%#", self.email.text, ..]; // .. simplified keychainItem
NSData *postEncoded = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
NSString *postLength = [NSString stringWithFormat:#"%d", [postEncoded length]];
NSURL *url = [NSURL URLWithString:#"http://eng.studev.groept.be/web2.0/a11_web02/improver/app/testPost"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postEncoded];
NSError *error = nil;
NSURLResponse *response = nil;
NSData *encodedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *data=[[NSString alloc]initWithData:encodedData encoding:NSUTF8StringEncoding];
NSLog(#"Data? %#",data);
The correct value is shown as an echo. But when trying to do this asynchronously, I get following php error: "Undefined index: email".
I try to start the asynchronous request with this line:
[[NSURLConnection connectionWithRequest:request delegate:self] start];
Then, I have the delegate method connection:didReceiveResponse, but there I cannot seem to get the data out... Or do I need another delegate method? Also, how 'safe' is it to check the result of your query by using just an echo (do I need/want a stream maybe?) ??
Tia
EDIT
Problem related to the server, not to objective-C code. Asked a new question to reach the correct audience: $_POST remaining empty
#ott is on the right track, I'll try to clarify.
You don't need start as he says. It's benign as the connection will start automatically.
initWithRequest:delegate and connectionWithRequest:delegate: are equivalent except for the retain state of the new connection object.
The real problem is b/c you are using connectionWithRequest:delegate the returned connection is autoreleased at the end of the run loop and you are not retaining it in a property. Therefore, the connection never starts.
The solution is to add a property #property (nonatomic, retain) NSURLConnection *connection to your class and set this property to the connection returned from connection:withRequest:
You then release the connection in the completion methods connection:didFinishLoading and connection:didFailWithError:.
The start is wrong here. Simply use
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
with NSURLConnection *connection; defined. See the class reference for connectionWithRequest. start is to be used with initWithRequest:delegate:.

Implement Timeout in HTTP Post

What is the best way to implement a connection timeout (let's say, 20 seconds) within an HTTP post connection?
My current code is as follows:
-(NSData*) postData: (NSString*) strData
{
//postString is the STRING TO BE POSTED
NSString *postString;
//this is the string to send
postString = #"data=";
postString = [postString stringByAppendingString:strData];
NSURL *url = [NSURL URLWithString:#"MYSERVERHERE"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d", [postString length]];
//setting prarameters of the POST connection
[request setHTTPMethod:#"POST"];
[request addValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request addValue:msgLength forHTTPHeaderField:#"Content-Length"];
[request addValue:#"en-US" forHTTPHeaderField:#"Content-Language"];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
[request setTimeoutInterval:10.0];
NSLog(#"%#",postString);
NSURLResponse *response;
NSError *error;
NSLog(#"Starting the send!");
//this sends the information away. everybody wave!
NSData *urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Just finished receiving!");
if (&error) //OR TIMEOUT
{
NSLog(#"ERROR!");
NSString *errorString = [NSString stringWithFormat:#"ERROR"];
urlData = [errorString dataUsingEncoding:NSUTF8StringEncoding];
}
return urlData;
}
Obviously the timeout interval is set to 10.0, but nothing seems to happen when those ten seconds hit.
See:
NSMutableURLRequest timeout interval not taken into consideration for POST requests
Apparently timeouts under 240 seconds are ignored. The highest voted answer in that question links to a solution. However, I would simply recommend using the ASIHTTPRequest library instead.
http://allseeing-i.com/ASIHTTPRequest/