ASIHTTPRequest - download problem - iphone

I try to download a file from my server, this is the code, on my console I see the xml file, but I can't save it.
Where is the problem for you?
- (IBAction)grabURL:(id)sender{
NSURL *url = [NSURL URLWithString:#"http://www.endurodoc.net/photo/data.xml"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
NSError *error = [request error];
if (!error) {
NSString *response = [request responseString];
NSLog(#"%#",response);
}
else{
NSLog(#"Errore");
}
//[request setDownloadDestinationPath:#"/Users/kikko/Desktop/data.xml"];
// SAVED PDF PATH
// Get the Document directory
NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
// Add your filename to the directory to create your saved pdf location
NSString *pdfLocation = [documentDirectory stringByAppendingPathComponent:#"data.xml"];
// TEMPORARY PDF PATH
// Get the Caches directory
NSString *cachesDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
// Add your filename to the directory to create your temp pdf location
NSString *tempPdfLocation = [cachesDirectory stringByAppendingPathComponent:#"data.xml"];
// Tell ASIHTTPRequest where to save things:
[request setTemporaryFileDownloadPath:tempPdfLocation];
[request setDownloadDestinationPath:pdfLocation];
}

You need to put:
[request setTemporaryFileDownloadPath:tempPdfLocation];
[request setDownloadDestinationPath:pdfLocation];
before:
[request startSynchronous];
ASIHTTPRequest does the file saving when the request is made, so if you set those properties after the request has already happened then nothing will happen.

Related

Downloading plist with ASIHTTPRequest works only partially

I have a game where there are different categories to play with. These categories are basically plist files. So, if in the future, I want to add plists, the user should be able to download a plist and play new levels. So what I am aiming for is:
Download .plist from URL
Save .plist file in documents directory on iphone (forever)
use .plist
Here is what I did and it works (console logs "finished !!"), but if I check whether the file is in the documents directory, there is no response (the boolean fileExists stays NO).
-(void)startGame:(id)sender{
NSArray *categoriesArray = [[GameStateSingleton sharedMySingleton] categoriesArray];
NSString *category = [NSString stringWithFormat:[categoriesArray objectAtIndex:[sender tag]]];
NSString *thePath = [mainPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.plist",category]];
NSDictionary *categoryPlist = [NSDictionary dictionaryWithContentsOfFile:thePath];
if(categoryPlist != nil){
[[GameStateSingleton sharedMySingleton]setCurrentCategory:category];
[[GameStateSingleton sharedMySingleton]updateHexCountAndInitalTime];
[[CCDirector sharedDirector]replaceScene:[CCTransitionFade transitionWithDuration:TRANSITIONDURATION scene:[LevelSets scene]]];
}
else{
[self plistForCategory:category];
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *myCategory= [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.plist",category]];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:myCategory];
if(fileExists == YES){
[[GameStateSingleton sharedMySingleton]setCurrentCategory:category];
[[GameStateSingleton sharedMySingleton]updateHexCountAndInitalTime];
[[CCDirector sharedDirector]replaceScene:[CCTransitionFade transitionWithDuration:TRANSITIONDURATION scene:[LevelSets scene]]];
NSLog(#"category exists now");
}
}
}
-(void)plistForCategory:(NSString*)category
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSURL *url = [NSURL URLWithString:[ NSString stringWithFormat:#"http://www.tinycles.com/wannaplay/plists/%#.plist",category]];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:documentsDirectory];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSLog(#"finished !!");
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
// Download failed. This is why.
NSError *error = [request error];
NSLog(#"%#", error);
}
Maybe the problem is because you're starting an async request, so if the request has not finished, your if(fileExist==YES) still returns NO; i suggest you in this case to start a sync request:
- (IBAction)startRequest:(id)sender
{
NSURL *url = [NSURL URLWithString:LINK_TO_PLIST];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:DOC_PATH];
[request startSynchronous];
NSError *error = [request error];
if (!error) {
//start your game after the file is downloaded
}
}

Uploading a file with ASIFormDataRequest does not work

I am using the ASIHTTPRequest framework trying to upload a file to my websever via iPhone.
Below is the code. As long as I don't use the setFile method, I get a 200 back from the server, so everthing is fine. As soon as I implement setFile, the server returns 0. I would expect a 401 or anything like this, as I could imagine that I deal with an authentication issue.
My server is an IIS, why I use the NTLM way in the request. Do I miss something?
NSInteger httpStatus;
NSString *httpResponseString;
NSError *httpRequestError;
NSArray *paths = [[[NSArray alloc] init] autorelease];
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filename = [documentsDirectory stringByAppendingPathComponent:#"abiliator_basis_de_ar.xml"];
NSURL *myURL = [NSURL URLWithString: #"http://my.url.com/"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:myURL];
[request setShouldPresentCredentialsBeforeChallenge:NO];
[request setUsername:#"myUserName"];
[request setPassword:#"myPassword"];
[request setDomain:#"myDomainName"];
[request setFile:[NSURL URLWithString:filename] forKey:#"xml"];
[request startSynchronous];
httpRequestError = [request error];
httpResponseString = [request responseString];
httpStatus = [request responseStatusCode];
if (!httpRequestError) {
httpStatus = [request responseStatusCode];
NSLog(#"Class %#, Method: %# - OK login and filetransfer successful '%i'", self.myClassName, NSStringFromSelector(_cmd), httpStatus);
}
else {
NSLog(#"Class %#, Method: %# - Error '%i' occurred sending the http request", self.myClassName, NSStringFromSelector(_cmd), httpStatus);
}
Yes the file exists, here the result from the ls:
rene-stegs-macbook-pro:~ renesteg$ ls -ltr '/Users/renesteg/Library/Application Support/iPhone Simulator/5.1/Applications/417BD791-64BC-48D0-B519-F10C7F617E36/Documents/abiliator_basis_de_ar.xml'
-rw-r--r--# 1 renesteg staff 1062 22 Mai 13:44 /Users/renesteg/Library/Application Support/iPhone Simulator/5.1/Applications/417BD791-64BC-48D0-B519-F10C7F617E36/Documents/abiliator_basis_de_ar.xml
And here the value of filename:
Filename string is: '/Users/renesteg/Library/Application Support/iPhone Simulator/5.1/Applications/417BD791-64BC-48D0-B519-F10C7F617E36/Documents/abiliator_basis_de_ar.xml
You are doing something wrong while uploading file.
it need to like this
NSFileManager *fileManager = [NSFileManager defaultManager];
request = [[[ASIFormDataRequest alloc] initWithURL:url] autorelease];
[request setRequestMethod:#"POST"];
[request setTimeOutSeconds:120];
[request setPostFormat:ASIMultipartFormDataPostFormat];
[request addRequestHeader:#"Content-Type" value:#"multipart/form-data"];
if ([fileManager fileExistsAtPath:filePath] == YES) {
[request setFile:filePath withFileName:#"test.xml" andContentType:#"xml" forKey:#"FieldName"];
}
Here file path need to set for fromdata request.
Hope this will work for you.
You should probably try usingsetData:forKey: and send the data of the xml file, example below..
.....
NSURL *myURL = [NSURL URLWithString: #"http://my.url.com/"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:myURL];
[request setShouldPresentCredentialsBeforeChallenge:NO];
[request setUsername:#"myUserName"];
[request setPassword:#"myPassword"];
[request setDomain:#"myDomainName"];
[request setData:[NSData dataWithContentsOfFile:fileName] forKey:#"xml"];
[request startSynchronous];
.....
Also, you should probably make this an asynchronous request.
i think the error occurs because you should use:
[request setFile:[NSURL fileURLWithPath:filename] forKey:#"xml"];
Ok, the issue was between the line of Neels comment: missing PHP.
And this of course needs to be called in the URL, so the correct way to build the URL is:
NSURL *myURL = [NSURL URLWithString: #"http://my.url.com/upload.php"];
This way I got the mapping my iPhone httpRequest code and the PHP.
Here's the required PHP code:
<?php
$target = "upload/";
$target = $target . basename( $_FILES['xml']['name']) ;
$ok=1;
if(move_uploaded_file($_FILES['xml']['tmp_name'], $target))
{
echo "The file ". basename( $_FILES['xml']['name']). " has been uploaded";
}
else {
echo "Error uploading". basename( $_FILES['xml']['name']). " occured";
}
?>

Resume downloading a file using ASIHTTPRequest gives error

I am using ASIHTTPRequestfor resuming the downloading of a file gives the error as below and the Resume code is given at the bottom:
Error Domain=ASIHTTPRequestErrorDomain Code=8 "Decompression of /Users/xxxx/Library/Application Support/iPhone Simulator/4.3.2/Applications/6E0D8E0F-08FD-440C-82F6-8E39E219884E/Documents/myPdf.pdf.download failed with code -3" UserInfo=0x4c6a8e0 {NSLocalizedDescription=Decompression of /Users/xxxx/Library/Application Support/iPhone Simulator/4.3.2/Applications/6E0D8E0F-08FD-440C-82F6-8E39E219884E/Documents/myPdf.pdf.download failed with code -3}
Starting download as below:
-(IBAction)startDownload:(id)sender
{
NSURL *url = [NSURL URLWithString:self.sourcePath];
ASIHTTPRequest *req =[[ASIHTTPRequest alloc] initWithURL:url];
[request setDownloadDestinationPath:self.destinationPath];
// This file has part of the download in it already
[request setTemporaryFileDownloadPath:self.temporaryPath];
[req setDownloadProgressDelegate:self];
[req setDelegate:self];
[req startAsynchronous];
self.request = req;
}
and Pause Downloading as below:
-(IBAction)pauseDownload:(id)sender
{
// Cancels an asynchronous request
[request cancel];
// Cancels an asynchronous request, clearing all delegates and blocks first
// [request clearDelegatesAndCancel];
}
and Resume Download as below:
- (IBAction)resumeDownload:(id)sender
{
NSURL *url = [NSURL URLWithString:
self.sourcePath];
ASIHTTPRequest *request1 = [ASIHTTPRequest requestWithURL:url];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSError *err;
NSDictionary *fileDict = [[NSFileManager defaultManager] attributesOfItemAtPath:destinationPath error:&err];
NSLog(#"file Dict: %#", fileDict);
NSLog(#"size: %#",[fileDict valueForKey:NSFileSize]);
NSInteger nSize =[[fileDict valueForKey:NSFileSize] intValue];
// unsigned long long int size1 = [[fileDict valueForKey:NSFileSize] intValue];
NSString *size = [NSString stringWithFormat:#"bytes=%d", nSize];
NSLog(#"file size: %#",size);
[dict setValue:size forKey:#"Range"];
[request1 setRequestHeaders:dict];
// NSString *downloadPath = #"/Users/ben/Desktop/my_work_in_progress.txt";
// The full file will be moved here if and when the request completes successfully
[request1 setDownloadDestinationPath:self.destinationPath];
// This file has part of the download in it already
[request1 setDownloadProgressDelegate:self];
[request1 setDelegate:self];
[request1 setTemporaryFileDownloadPath:self.temporaryPath];
[request1 setAllowResumeForFileDownloads:YES];
[request1 startAsynchronous];
self.request = request1;
//The whole file should be here now.
// NSString *theContent = [NSString stringWithContentsOfFile:downloadPath];
}
And I set the "Range" HTTP header field to the corresponding file size. The same file on server supports download pause, resume on the app http://itunes.apple.com/us/app/download-manager-pro-lite/id348573579?mt=8
How to implement the Resuming a download
Thanks in advance.
You should refer How to Pause and Resume Downloading Files with ASIHTTP Request in iPhone and
ASIHTTPRequest documentation.

How to obtain the zip filename being downloaded in iphone

Currently using SSZipArchive method to download the zip file and unzip at Documents directory folder. I am downloading the zip file name from URL and currently unaware of the file name because it changes each time there are any updates. How can I retrieve the file name when I receive my data ?
- (void)viewDidLoad {
fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
directoryPath = [paths objectAtIndex:0];
filePath = [NSString stringWithFormat:#"%#/ZipFiles.zip", directoryPath];
NSURL *url=[NSURL URLWithString:#"http://www.abc.com/test/test.cfc?id=123"];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSError *error;
NSURLResponse *response;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
[fileManager createFileAtPath:filePath contents:urlData attributes:nil];
[SSZipArchive unzipFileAtPath:filePath toDestination:directoryPath];
NSString *responseString = [[NSString alloc] initWithData:urlData encoding:NSASCIIStringEncoding];
///***Answer to my own question for future needs****//
NSString *fileName = [response suggestedFilename];
}
NSURLResponse has a method - (NSString *)suggestedFilename which will attempt to get the file name in this order.
A filename specified using the content disposition header.
The last path component of the URL.
The host of the URL.
The content disposition header would be the best solution so make sure that the server sets it.

Failed to move file error in ASIHTTPRequest

I am using ASIHTTPRequest for downloading file from server but its giving error
Failed to move file from '/Users/admin/Library/Application
Support/iPhone
Simulator/3.1.3/Applications/8650FFE4-9C18-425C-9CEE-7392FD788E6D/Documents/temp/test.zip.download'
to '/Users/admin/Library/Application Support/iPhone
Simulator/3.1.3/Applications/8650FFE4-9C18-425C-9CEE-7392FD788E6D/Documents/test.zip'
can any body tell mw this error what wrong in my code......
NSURL *url = [NSURL URLWithString:#"http://wordpress.org/latest.zip"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
NSArray *dirArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [NSString stringWithFormat:#"%#/test.zip", [dirArray objectAtIndex:0]];
//NSString *tempPath = [NSString stringWithFormat:#"%#test.zip", NSTemporaryDirectory()] ;
NSString *tempPath =[NSString stringWithFormat:#"%#/temp/test.zip.download", [dirArray objectAtIndex:0]];
// The full file will be moved here if and when the request completes successfully
[request setDownloadDestinationPath:path];
[request setTemporaryFileDownloadPath:tempPath];
[request setDidFinishSelector:#selector(requestDone:)];
[request setDidFailSelector:#selector(requestWentWrong:)];
[[self queue] addOperation:request]; //queue is an NSOperationQueue
do you already have a temp.zip in that location ?
It also happens if you didn't set the destination path correctly, using this method setDownloadDestinationPath: of ASIHTTPRequest...
Your call
[request setTemporaryFileDownloadPath:tempPath];
is not necessary, and is more than likely the source of your error.