ASIHTTPRequest with UIWebView - iphone

I need to connect to a protected site and try to use ASIHTTPRequest
Here is my code:
url = [NSURL URLWithString:#"http://myurl/page.aspx"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setUsername:username];
[request setPassword:password];
[request setDomain:domain];
[request startSynchronous];
NSError *error = [request error];
if (!error) {
[webView loadHTMLString:[request responseString] baseURL:[request url]];
}
When I use NSLog to see [request responseString], I get the correct HTML, but the result is a blank white webview.
From the outgoing request warnings that little snitch displays, I see the initial request and one going to an external resource.
My guess so far is that the inital request correctly uses the authentication from ASIHTTPRequest and fetches the page, but the uiwebview will try to load the included .js files and since uiwebview is not authenticating, it will not render the page at all ...
Anybody knows how to fix my problem?

Have you tried ASIWebPageRequest? My guess is you have resources in that page that are not downloaded, like http://myurl/image.jpg

ASIHttpRequest runs asynchronously. You need to put your webview loading code into the ASIHTTPRequest callbacks. (requestFinished).
Add a method to your class as follows:
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSError *error = [request error];
if (!error) {
[webView loadHTMLString:[request responseString] baseURL:[request url]];
}
}
There is also a requestFailed method that you can use to trap additional errors, you should implement this as well. One or the other of these methods will be called once ASIHttpRequest completes.
Note you will probably also need to set the delegate on the request before making the asynch call. (so same place you set the auth stuff).
request.delegate = self;

Related

ASIHTTPRequest synchronous request crashing app

I am currently working on an application I need to receive the data in order its very important so instead of going with asynchronous I am using synchronous. However this introduces a very unfortunate side effect, the synchronous request locks up the UI thread.
What I am doing to combat this issue is introduce Multithreading into my app with the use of the life saving "Grand Central Dispatch" services, which seems to be very easy to get my head around so far.
So with all this in mind I am having an issue with what I am doing, Previously I was using asynchronous and everything worked sweet, changing that to synchronous gives me this error
Error Domain=ASIHTTPRequestErrorDomain Code=1 "A connection failure occurred" UserInfo=0x68052a0 {NSUnderlyingError=0x683d250 "The operation couldn’t be completed. Connection refused", NSLocalizedDescription=A connection failure occurred}
Heres my code so far.
- (IBAction)setRequestString:(NSString *)string
{
//Set database address
NSMutableString *databaseURL = [[NSMutableString alloc] initWithString:#"http://192.168.1.1:8778/Data/"]; // iphone development
//PHP file name is being set from the parent view
[databaseURL appendString:string];
//call ASIHTTP delegates (Used to connect to database)
NSURL *url = [NSURL URLWithString:databaseURL];
//Used to Check which ASI cache to use (also used in requestFinished
xmlFileName = [[NSString alloc] initWithFormat:string];
//Set up multithread with GCD
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
//Create If statments here to set up the different caches to be passed down to the next view
if ([string isEqualToString:#"high.xml"]){
//Cache stuff goes in here
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
[request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
[request setCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
[request setSecondsToCache:60*60*24*30]; // Cache for 30 days - this will change to cache until DBVersion changes
[request setDelegate:self]; // this calls the delegate function requestFinished
dispatch_sync(queue, ^ {
[request startSynchronous];
});
}else if ([string isEqualToString:#"low.xml"]){
//Cache stuff goes in here
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
[request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
[request setCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];
[request setSecondsToCache:60*60*24*30]; // Cache for 30 days - this will change to cache until DBVersion changes
[request setDelegate:self]; // this calls the delegate function requestFinished
dispatch_sync(queue, ^ {
[request startSynchronous];
});
}
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
//.... etc
hopefully that gives you a better idea of what im trying to do, I think maybe I am missing something with the way I am declaring my syncronious start.. as in the asihttprequest help file they say to declare it like this
- (IBAction)grabURL:(id)sender
{
NSURL *url = [NSURL URLWithString:#"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
NSError *error = [request error];
if (!error) {
NSString *response = [request responseString];
}
}
however Im working with data.. so this line
NSString *response = [request responseString];
will not work? dose it need to be NSData.. etc I dunno if someone could help me out that would be great.
You can use nsoperationqueue...
you can create one NSoperationInvoke and add those to NSoperationQueue in order(after reciving data sending another request)...You can add observer to NSOperationQueue to ensure that how many request will process at a time...in your case it will be just one...after receiving the notification in the observer that the synchronous process is completed it will call a selector by performonMainThread for starting another request in the observer itself...
on NSString *response = [request responseString];
issue you can check the request object by [request iskindofClass:[ClassName class]];
or nslog("%#",[request describe]);
it will tell what kind of object request is
Have you considered just adding a serial queue to your code?
dispatch_queue_t queue = dispatch_queue_create("com.myapp", NULL);
You are using a concurrent thread and it's causing multiple operations to occur at the same time. Also, wrap properly your ASIHttpRequest code within the queue blocks.
Give that a try and let us know

iPhone objective c Asyncron HTTPS request in NSThread

I need a good solution for my little issue.
What I have at the moment:
My App works with asyncron https request very well. At the moment the app uploads an JSON object, so far so good. After that I save the object in an sqlite database.
Now I have to change to determine what the received server response code is.
I will get an response code like 000 if the uploaded data was valid, and a code like 151 if not. For that I have to wait for the server response to save the response code in the database as well.
I experimented with NSThread, too. But that didn't work out as well as I expected.
Somebody any suggestions? I mean, it should be one of the most common things ;) I just don't see it.
thx, dominik
I usually use an NSOperationQueue to manage my communication. This lets you use a synchronous request instead of asynchronous, and handle the whole shebang in one method.
Example:
-(void)doIt {
NSInvocationOperation *op = [[[NSInvocationOperation alloc] initWithTarget:self selector:#selector(doIt_) object:nil] autorelease];
[opQueue addOperation:op];
}
-(void)doIt_ {
NSData *data;
NSMutableURLRequest *request;
NSURLResponse *response = nil;
NSError *error = nil;
// Build request to spec
data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:error];
// do something with data
[self performSelectorOnMainThread:#selector(yadda) withObject:yaddayadda waitUntilDone:NO];
}
If you do use the asynchronous loading methods, you have to implement a delegate to catch the response data as it comes down, and do something with it when finished.
I recommend that you take a look at ASIHTTPRequest which is a wrapper for the CFNetwork API. Particularly look into the mechanism it offers for asynchronous HTTP requests, where you can define blocks to be executed once the request has completed or failed and can you can inspect the response data easily. Your code would be something like this:
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setRequestMethod:#"POST"];
// add your json object to the request
[request setCompletionBlock:^{
int responseCode = [request responseStatusCode];
NSData *responseData = [request responseData];
// do whatever you want with this info
}];
[request setFailedBlock:^{
NSError *error = [request error];
// handle the error
}];
[request startAsynchronous];

Map view touch event handling

I am using map view in my iOS app. After the user scrolls the map and lifts his finger I need to send web service request to get new data and then I want to plot that lat longs.
Here I want to detect touch end event on map view. Also same time want to handle web service request and response. I tried using tap gesture but not getting proper result.
Please suggest something
Thanks
You need to set the delegate of the map view, then implement this method:
– mapView:regionDidChangeAnimated:
This gets called everytime the user has finished scrolling.
For the HTTP request I suggest using ASI. Its really easy to use....
- (void) grabURLInBackground:(id)sender
{
NSURL *url = [NSURL URLWithString:#"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
// Use when fetching binary data
NSData *responseData = [request responseData];
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}

how to connectASIHTTPRequest for WebService

i am new to iphone....when i need to connect to one of the web service i am using follwing code tat is using ASIHTTP request..when i add this code its coming error
ASIHTTPRequest is undeclared declare it first where i shd declare and wat i shd declare?i am using UIViewController class
how i shd declare? wat i shd do?plz suggest me
the code is given below
-(void)callWebService
{
//this is a typical url for REST webservice, where you can specify the method that you want to call and the parameters directly with GET
NSURL *url = [NSURL URLWithString:#"http://www.yourserver.net/webservice/rest/?method=myMethod&par1=ok"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDidFinishSelector:#selector(requestCompleted:)];
[request setDidFailSelector:#selector(requestError:)];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestCompleted:(ASIHTTPRequest *)request
{
NSString *responseString = [request responseString];
}
- (void)requestError:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
thank u...
First check that you have asihttp package attached in your project.
After that check you have
#import "ASIHTTPRequest.h" import this in your viewcontroller
Dont forget to check that you have attached the following frameworks. CFNetwork, SystemConfiguration, MobileCoreServices, CoreGraphics and libz framework.
You have not tell which method to use
[request setRequestMethod:#"GET"]; BEFORE [request startAsynchronous];
When you will right click on framework folder this popup will appear.

Why does the activity indicator never finish when using ASIHTTPRequest?

I use ASIHTTPRequest to do http requests in my iPhone app. ASIHTTPRequet comes with that feature that starts the activity indicator when issuing a request and stops it when finished. The problem is, once I started a request the indicator never stops and keeps spinning as long as my app runs.
Here is my code, a little utility method that fetches some content from the web synchroniously (since it gets started in a different thread):
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL: [NSURL URLWithString: url]];
[request startSynchronous];
NSError *error = [request error];
NSString *response = nil;
if (error) {
NSLog(#"error %#", error);
return nil;
}
int statusCode = [request responseStatusCode];
response = [NSString stringWithString: [request responseString]];
NSLog(#"status code: %d response: %#", statusCode, response);
if (statusCode != 200) {
return nil;
}
return response;
The above code works just fine, I get the contents of the given URL as a NSString only the indicator keeps spinning. My question is: Why does the indicator never stop and how to fix it? Do I have to release some resources here?
This is a bug that was fixed very recently in the development version of ASIHTTPRequest:
http://github.com/pokeb/asi-http-request/commit/35ea592084145b3332861344f36b52dbcaafa351
(It only affects synchronous requests started on a secondary thread)
Can you try the same thing with an asynchronous request and see if that changes it? I use ASIHTTPRequest and I've never noticed this behavior, but I also never use synchronous requests.