I have a tested and working php script that pulls from a db and returns as an XML.
I have used ASIHTTPRequest to make a POST to the php script successfully.
I have looked for online help to get this to work. From what I understand, all the code is solid. It compiles properly, runs without problem, even makes the request without problem. I get no errors.
Since I have thoroughly tested and successfully used the php, I assume the break is on the iPhone side.
I do not understand why it does not download the XML file to the specified location.
Any insight would be greatly appreciated.
// Create the request
NSURL *url=[[NSURL alloc]initWithString:#"http://localhost:8888/Project/script.php"];
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:url]retain];
// gather *ALL* data present
if ( [txtEmail.text length] > 0 )
[request setPostValue:txtEmail.text forKey:#"email"];
if ( [txtFName.text length] > 0 )
[request setPostValue:txtFName.text forKey:#"firstname"];
if ( [txtID.text length] > 0 )
[request setPostValue:txtID.text forKey:#"id"];
if ( [txtLName.text length] > 0 )
[request setPostValue:txtLName.text forKey:#"lastname"];
[request setDidFailSelector:#selector(requestFailed:)];
[request setDidFinishSelector:#selector(requestDone:)];
[request setDownloadDestinationPath:#"/Library/Project/dbInfo.xml"];
[request setDelegate:self];
[request startSynchronous];
[request release];
[url release];
a few points on your code:
Why are you using a POST request to download a file? usually downloading is done via a GET request (if we're talking REST). You could use a simple ASIHTTPRequest + adding your post values as URL-Parameters (+ handle it on the php side accordingly).
you are allocating and retaining your ASIFormDataRequest instance, but only releasing it once -> results in a memory leak. (for every alloc/copy/retain -> release it).
To answer you question:
i think the downloadDestinationPath is wrong (the application has no permissions to write there).
Better:
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [docDir stringByAppendingPathComponent:#"dbInfo.xml"];
[request setDownloadDestinationPath:path];
Now your "dbInfo.xml" File is saved in the documents folder of your application.
If you're running your app in the simulator, you can find the directory at:
~/Library/Application Support/iPhone Simulator/IOS_SDK_VERSION/Applications/APP_UID/Documents
And:
if you implement the downloadProgressDelegate: request:didReceiveBytes: method, you can check if you're actually receiving data:
-(void)request:(ASIHTTPRequest *)request didReceiveBytes:(long long)bytes {
NSLog(#"received bytes ..") ;
}
Related
I'm trying to to send some post data to a Apache server from iPad application using the ASIHttp library.
actually I need to send huge data to the server and that means I need to compress the request body so I write some code to send the data and compress the request BUT there are no parameters received on the server !!!
the iOS code is :
NSURL * URL = [NSURL URLWithString:myURL];
ASIFormDataRequest *ASIRequest = [ASIFormDataRequest requestWithURL:URL];
ASIRequest.shouldCompressRequestBody=YES;
ASIRequest setPostValue:data forKey:#"data"];
[ASIRequest startSynchronous];
NSError *error = [ASIRequest error];
if (!error) {
NSString *response = [ASIRequest responseString];
NSLog(#"response %#" , response);
}
PS: if I removed the ASIRequest.shouldCompressRequestBody=YES; everything works fine and I can see the data but when use it I see nothing on the server
the request can be seen on the server but with no parameter
noway to send such data over GET method.
the server configuration are fine.
any solution ? any comment or idea can help ?
By default, most web servers do not support compression on POSTs. The accepted answer here does a really good job explainining it: Why can't browser send gzip request?
According to official documentation, this feature has only been tested with Apache servers.
EDIT:
Here is a code snipt that compresses the actual post data:
if ([self shouldCompressRequestBody]) {
NSError *err = nil;
NSData *compressedBody = [ASIDataCompressor compressData:[self postBody] error:&err];
if (err) {
[self failWithError:err];
return;
}
[self setCompressedPostBody:compressedBody];
[self setPostLength:[[self compressedPostBody] length]];
}
Source: http://forums.three20.info/discussion/77/tturlrequest-vs-asihttprequest/p1
I want to download audio files Asynchronously from internet through ASIHTTP request. I have written a piece of code, but it's not working properly.
+(ASIHTTPRequest *)getDownloadedLectureAndSeries:(id)target :(NSString *)downloadString FinishSelector:(SEL) finishselector FailSelector:(SEL) failselector
{
NSString *api=downloadStrin;
NSURL *url = [NSURL URLWithString:api];
[api release];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request startAsynchronous];
[request setDelegate:target];
[request setDidFinishSelector:finishselector];
[request setDidFailSelector:failselector];
return request;
}
Help me, if you can. Thanks in advance.
Doesn't look like you are acctually saving the file anywhere in your code. (Unless you are trying to do it in your finishselector.
Add this line to have the request automatically save the file
[request setDownloadDestinationPath:path];
Where path is a NSString to where you want the file to be stored (such as your Documents directory
I am trying to use the ASIDownloadCache from the ASIHTTPRequest library. I think I have it almost set up but the data I am printing to the log is a bunch of numbers.. I think it might be a formatting problem.. but I would like to run it past someone with more experience first to make sure I'm doing it correctly and then to hopefully help me fix the issue.
The code belows shows you how I am setting up my cache, I am using this view for several data sets, hence the need to use an if statement so that I am only setting up the cache on specific data.
- (IBAction)setRequestString:(NSString *)string
{
//Set database address
NSMutableString *databaseURL = [[NSMutableString alloc] initWithString:#"http://***.***.***.***:8888/codeData/"]; // 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];
checkDataSet = [[NSString alloc] initWithFormat:string]; //Loads ICMfg.xml into checkDataSet for setting up cache
//Create If statments here
if ([checkDataSet isEqualToString:#"ICMfg.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
[request setDelegate:self]; // A delegate must be specified
[request startSynchronous];
//[request setDidFinishSelector:#selector(requestFinished:)]; // And an appropriate
}
else
{
//this else statments lets all of the other datasets come through here
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}
}
From here, when [checkDataSet isEqualToString:#"ICMfg.xml"] is true it will set the cache parameters and then calls the following method where I get everything ready to parse my information
- (void)requestFinished:(ASIHTTPRequest *)request
{
if ([checkDataSet isEqualToString:#"ICMfg.xml"]) {
BOOL success = [request didUseCachedResponse];
NSLog(#"------------>>>>>>> Success is %#\n", (success ? #"YES" : #"NO"));
responseString = [request responseString];
capturedResponseData = [responseString dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"%#", capturedResponseData); //this prints out the weird data.
[self startTheParsingProcess:capturedResponseData];
}
else
{
responseString = [request responseString]; //Pass requested text from server over to NSString
capturedResponseData = [responseString dataUsingEncoding:NSUTF8StringEncoding];
[self startTheParsingProcess:capturedResponseData];
}
}
From here, I check my nslog to see the result of that NSlog and it spits out a bunch of numbers, below is a small section of the output. The next step for me is to check to see if anything is actually being parsed.. and also to see if the cache is working or not.. then I need to figure out hopefully with your help how to format the data correctly if thats my main problem..
also I would like to ask how to get this working asynchronously as currently I can only get it to work synchonosly.
2011-11-09 09:29:55.216 code[3968:207] ------------>>>>>>> Success is YES
2011-11-09 09:29:55.239 code[3968:207] <3c3f786d 6c207665 7273696f 6e3d2231 2e302220 656e636f 64696e67 3d225554 462d3822 3f3e0d0a 3c494345 6e673e3c 52657375 6c742044 42566572 73696f6e 3d223132 33223e3c 5461626c 65733e3c 5461626c 65205461 626c654e 616d653d 2249434d 6667223e 3c526f77 733e3c52 6f77204d 414e5546 41435455 52455249 443d2237 30362220 4d414e55 46414354 55524552 3d22412d 445a4722 2049534c 4f434b4d 414e5546 41435455 5245523d 22462220 49535645 4849434c 453d2246 223e3c2f 526f773e 3c526f77 204d414e 55464143 54555245 5249443d 22333138 22204d41 4e554641 43545552 45523d22 412e522e 452e2220 49534c4f 434b4d41 4e554641 43545552 45523d22 46222049
any help would be greatly appreciated.
I don't see anything that immediately sticks out in your code as wrong.
The NSLog() is printing an NSData object, which is binary data so the hexadecimal numbers you are seeing are the representations of the bytes which is exactly what you would expect.
The NSData Class Reference:
description
Returns an NSString object that contains a hexadecimal
representation of the receiver’s contents.
(NSString *)description
Return Value
An NSString object that contains a hexadecimal representation of the receiver’s contents in
NSData property list format.
If you want to print out the string representation of this data, use:
NSString *capturedResponseString = [NSString stringWithUTF8String:[capturedResponseData bytes]];
I've been trying to load images from a url using ASIHTTPRequest but I always come up with a blank UIImage. I think it might have something to do with iOS automatically choosing the #2x named version of images or vica versa.
[ASIHTTPRequest setDefaultCache:[ASIDownloadCache sharedCache]];
NSString *url_string = [NSString stringWithFormat:#"http://173.246.100.185/%#", [eventDictionary objectForKey:kEventDescriptionImageURLKey]];
NSURL *url = [NSURL URLWithString:url_string];
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
[request setCachePolicy:ASIAskServerIfModifiedCachePolicy|ASIFallbackToCacheIfLoadFailsCachePolicy];
[request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
[request setSecondsToCache:86400];
[request setDelegate:self];
[request setCompletionBlock:^{
NSLog(#"Successful Update");
[self makeAssignment];
}];
[request setFailedBlock:^{
NSError *error = [request error];
NSLog(#"%#", [error localizedDescription]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Update Failed"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}];
[request startAsynchronous];
NSLog(#"%#", url_string);
The makeAssignment method is below.
NSString *url_string = [NSString stringWithFormat:#"http://173.246.100.185/%#", [eventDictionary objectForKey:kEventDescriptionImageURLKey]];
NSURL *url = [NSURL URLWithString:url_string];
downloadedImage = [[UIImage alloc] initWithContentsOfFile:[[ASIDownloadCache sharedCache] pathToCachedResponseDataForURL:url]];
NSLog(#"%#", downloadedImage);
NSLog(#"%#", [[ASIDownloadCache sharedCache] pathToCachedResponseDataForURL:url]);
Nothing I do, including naming images #2x on the server or providing both versions, gets it to load. Any ideas? Has anyone done this before? When I load them locally (from within the package) I don't have any issues.
Thanks!
EDIT
Here's the log output
2011-03-19 11:46:11.088 clv[82974:207] Successful Update
2011-03-19 11:46:12.822 clv[82974:207] http://173.246.100.185/ying_yang_concert#2x.png
2011-03-19 11:46:12.844 clv[82974:207] >
2011-03-19 11:46:12.913 clv[82974:207] Successful Update
2011-03-19 11:46:12.932 clv[82974:207]
2011-03-19 11:46:12.932 clv[82974:207] /Users/jonathantpage/Library/Application Support/iPhone Simulator/4.3/Applications/A17C0938-D2ED-447C-BD17-94726C5E5A66/Library/Caches/ASIHTTPRequestCache/PermanentStore/FE05295C8CD7687DC7A505C9070B6FC7.png
It won't be the automatic #2x thing - if the system can't find an image with '#2x' appended to it it will simply use the original image and scale it up. If you want to verify that, just run the app on the simulator using the non-retina display mode.
If you run your app on the simulator you can actually browse the cache directory using the finder to verify your images are there as you expect. In your user directory, you would go to ~/Library/Application Support/iPhone Simulator/[Your SDK version]/Applications/[Your app]/ to get to your app sandbox, and form there probably into the app's library/cache directory.
Also, you log the cache path: what does it come out as? Are you sure it's a valid path? Again, if you're on the simulator you can quickly verify this by trying to open the path in the terminal/another app.
Nothing in your code looks particularly wrong to me at least, so it feels like there's something happening with the local file path. Perhaps you could post the NSLogs you're getting to the console.
So it turns out that everything was fine. What was wrong is that the completion block was being executed after the assignment to the UIImageView. By placing that in the makeAssignment method everything works. Previously I was just populating the UIImage there and then assigning that to the UIImageView in the main thread.
I just wanted to ask you if anyone can help me parsing the returned data from the Twitpic API?
I'm creating a HTTPFormRequest using the ASIHTTPRequest Wrapper for Cocoa. This all happens in an iPhone application:
NSURL *url = [NSURL URLWithString:#"http://twitpic.com/api/upload"];
NSString *username = t_user;
NSString *password = t_pass;
NSData *twitpicImage = UIImagePNGRepresentation(imageView.image);
// Now, set up the post data:
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease];
[request setPostValue:twitpicImage forKey:#"media"];
[request setPostValue:username forKey:#"username"];
[request setPostValue:password forKey:#"password"];
[request setData:twitpicImage forKey:#"media"];
// Initiate the WebService request
[request start];
if ([request error]) {
NSLog(#"%#", [request error]);
} else if ([request responseString]) {
NSLog(#"%#", [request responseString]);
}}
Now comes the hard part, I don't know how to parse the data that is in [request responseString]. I know I need to use NSXMLParser, but I dunno how to use it. All I need is to get the url of the image.
Thx in advance.
Feel free to have a look at my little XML parse classes here http://www.memention.com/blog/2009/10/31/The-XML-Runner.html
I have started to use them for parsing the response from image upload to yfrog.com
Basically I do like this...
In NameValueParser.m I changed the entry tag to rsp like this
entryName = [[NSString stringWithString:#"rsp"] retain];
then where the response has been received I parse it like this
NameValueParser *parser = [NameValueParser parser];
[parser addFieldName:#"statusid"];
[parser addFieldName:#"userid"];
[parser addFieldName:#"mediaid"];
[parser addFieldName:#"mediaurl"];
[parser addFieldName:#"err"];
[parser parseData:responseData]; // the response received by ASIHTTPRequest
NSArray *rspArray = [parser list];
NSLog(#"%#", rspArray); // Have a look at it here
Try it as written at the bottom of this tutorial click here using NSScanner. They are showing exactly what you need, retrieving only the mediaurl = URL of uploaded image.
NSScanner *scanner = [NSScanner scannerWithString:responseString]; ...
GSTwitPicEngine does XML and JSON parsing both: http://github.com/Gurpartap/GSTwitPicEngine
Though, why not use JSON format for the Twitpic API responses? It's easy to parse and deal with using yajl, TouchJSON, json-framework or other Cocoa JSON libraries