i am fetching around 1500 image url and want to store these images in the document directory of iphone at one go??
please suggest any approach to do it...
thanks
Method to download all URLs and write into one file:
- (BOOL) downloadFilefromCDN :(NSString*)filename {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://example.com/getlinks.php"]]];
[request setHTTPMethod:#"GET"];
NSError *err = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&err];
if (err != nil) { return FALSE; } // Download error
NSArray *searchPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[searchPath objectAtIndex:0] stringByAppendingString:[NSString stringWithFormat:#"/%#",filename]];
if ([data writeToFile:path atomically:YES] != FALSE) {
return TRUE;
} else {
return FALSE; // Error
}
}
You need to write a script that returns an answer including the 1400 links so you can write it into that file.
Method to download all images given by a NSArray* to document directory.
- (id) downloadFilefromCDN :(NSString*)filename {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://example.com/%#",filename]]];
[request setHTTPMethod:#"GET"];
NSError *err = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&err];
if (err != nil) { return FALSE; }
return data;
}
- (NSArray*) downloadFilesfromCDN :(NSArray*)filenames {
NSMutableArray *mfiles = [[NSMutableArray alloc] init];
BOOL error = FALSE;
for (NSString* filename in filenames) {
NSArray *searchPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[searchPath objectAtIndex:0] stringByAppendingString:[NSString stringWithFormat:#"/%#",filename]];
id file = [self downloadFilefromCDN:filename];
if ([file isKindOfClass:[NSData class]]) {
if ([(NSData*)file writeToFile:path atomically:YES] != FALSE) {
[mfiles addObject:path];
} else {
error = TRUE; // Writing of file failed
}
} else {
error = TRUE; // Download failed
}
}
if (error) {
// Handle error
}
[filenames release];
return [NSArray arrayWithArray:mfiles];
}
Note: You need to read the pure filenames into a NSArray. If you have different origins change
[NSString stringWithFormat:#"http://example.com/%#",filename]
to
[NSString stringWithFormat:#"%#",filename]
and read the full paths (http://example.com/file1.png,http://example.com/file2.png) into a NSArray.
Done. Hope it will help.
Sorry for so much editing :S
Related
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
}
}
I am going to work on iphone app which upload the photos on facebook wall.
I am using this code
here
- (void)rateTapped:(id)sender {
NSString *likeString;
NSString *filePath = nil;
if (_imageView.image == [UIImage imageNamed:#"angelina.jpg"]) {
filePath = [[NSBundle mainBundle] pathForResource:#"angelina" ofType:#"jpg"];
likeString = #"babe";
} else if (_imageView.image == [UIImage imageNamed:#"depp.jpg"]) {
filePath = [[NSBundle mainBundle] pathForResource:#"depp" ofType:#"jpg"];
likeString = #"dude";
} else if (_imageView.image == [UIImage imageNamed:#"maltese.jpg"]) {
filePath = [[NSBundle mainBundle] pathForResource:#"maltese" ofType:#"jpg"];
likeString = #"puppy";
}
if (filePath == nil) return;
NSString *adjectiveString;
if (_segControl.selectedSegmentIndex == 0) {
adjectiveString = #"cute";
} else {
adjectiveString = #"ugly";
}
NSString *message = [NSString stringWithFormat:#"I think this is a %# %#!", adjectiveString, likeString];
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/me/photos"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request addFile:filePath forKey:#"file"];
//[request setFile:filePath withFileName:#"myphoto.jpg" andContentType:#"image/jpeg" forKey:#"photo"];
[request setPostValue:message forKey:#"message"];
[request setPostValue:_accessToken forKey:#"access_token"];
[request setDidFinishSelector:#selector(sendToPhotosFinished:)];
[request setDelegate:self];
[request startAsynchronous];
}
here i got Photo id is: (null)
- (void)sendToPhotosFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
NSMutableDictionary *responseJSON = [responseString JSONValue];
NSString *photoId = [responseJSON objectForKey:#"id"];
NSLog(#"Photo id is: %#", photoId);
NSString *urlString = [NSString stringWithFormat:#"https://graph.facebook.com/%#?access_token=%#", photoId, [_accessToken stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURL *url = [NSURL URLWithString:urlString];
ASIHTTPRequest *newRequest = [ASIHTTPRequest requestWithURL:url];
[newRequest setDidFinishSelector:#selector(getFacebookPhotoFinished:)];
[newRequest setDelegate:self];
[newRequest startAsynchronous];
}
- (void)getFacebookProfileFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
NSLog(#"Got Facebook Profile: %#", responseString);
NSString *likesString;
NSMutableDictionary *responseJSON = [responseString JSONValue];
NSArray *interestedIn = [responseJSON objectForKey:#"interested_in"];
if (interestedIn != nil) {
NSString *firstInterest = [interestedIn objectAtIndex:0];
if ([firstInterest compare:#"male"] == 0) {
[_imageView setImage:[UIImage imageNamed:#"depp.jpg"]];
likesString = #"dudes";
} else if ([firstInterest compare:#"female"] == 0) {
[_imageView setImage:[UIImage imageNamed:#"angelina.jpg"]];
likesString = #"babes";
}
} else {
[_imageView setImage:[UIImage imageNamed:#"maltese.jpg"]];
likesString = #"puppies";
}
NSString *username;
NSString *firstName = [responseJSON objectForKey:#"first_name"];
NSString *lastName = [responseJSON objectForKey:#"last_name"];
if (firstName && lastName) {
username = [NSString stringWithFormat:#"%# %#", firstName, lastName];
} else {
username = #"mysterious user";
}
_textView.text = [NSString stringWithFormat:#"Hi %#! I noticed you like %#, so tell me if you think this pic is hot or not!",
username, likesString];
[self refresh];
}
But here am suffered from following error
here in Console i got an error : Got Facebook Photo: {"error":{"message":"(#803) Some of the aliases you requested do not exist: (null)","type":"OAuthException"}}
I tried this by changing various App ID but my problem doesn't solve.
Anyone help me to achieve this.........
Thanks In advance...
You try like this,
NSData *imagedata = UIImageJPEGRepresentation(urPhoto, 10);
[newRequest setPostValue:imagedata forKey:#"data"];
or add image like this,
[newRequest setPostValue:link forKey:#"data"];
I am making an application in which i have use Json parsing. With the help of json parsing i get photo url which is saved in string. To show images in my cell i use this code
NSString *strURL=[NSString stringWithFormat:#"%#", [list_photo objectAtIndex:indexPath.row]];
NSData *imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: strURL]];
CGRect myImage =CGRectMake(13,5,50,50);
UIImageView *imageView = [[UIImageView alloc] initWithFrame:myImage];
[imageView setImage:[UIImage imageWithData: imageData]];
[cell addSubview:imageView];
Now prblem is that when i go back or forword then i have wait for few second to come back on same view. Now i want that i when application is used first tme then i wait for that screen otherwise get images from home directory. How i save these image in my home directory? How access from home directory?
You can save an image in the default documents directory as follows using the imageData;
// Accessing the documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:#"myImage.png"];
//Writing the image file
[imageData writeToFile:savedImagePath atomically:NO];
You can use this to write a file to your Documents Folder
+(BOOL) downloadFileFromURL:(NSString *) url withLocalName:(NSString*) localName
{
//Get the local file and it's size.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *finalPath = [documentsDirectory stringByAppendingPathComponent:localName];
NSError *error;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:finalPath error:&error];
NSAssert (error == nil, ([NSString stringWithFormat:#"Error: %#", error]));
if (error) return NO;
int localFileSize = [[fileAttributes objectForKey:NSFileSize] intValue];
//Prepare a request for the desired resource.
NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"HEAD"];
//Send the request for just the HTTP header.
NSURLResponse *response;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSAssert (error == nil, ([NSString stringWithFormat:#"Error: %#", error]));
if (error) return NO;
//Check the response code
int status = 404;
if ([response respondsToSelector:#selector(statusCode)])
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*) response;
status = [httpResponse statusCode];
}
if (status != 200)
{
//file not found
return NO;
}
else
{
//file found
}
//Get the expected file size of the downloaded file
int remoteFileSize = [response expectedContentLength];
//If the file isn't already downloaded, download it.
if (localFileSize != remoteFileSize || (localFileSize == 0))
{
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
[[NSFileManager defaultManager] createFileAtPath:finalPath contents:data attributes:nil];
return YES;
}
//here we may wish to check the dates or the file contents to ensure they are the same file.
//The file is already downloaded
return YES;
}
and this to read:
+(UIImage*) fileAtLocation:(NSString*) docLocation
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *finalPath = [documentsDirectory stringByAppendingPathComponent:docLocation];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
[[NSFileManager defaultManager] createFileAtPath:finalPath contents:data attributes:nil];
NSData *databuffer = [[NSFileManager defaultManager] contentsAtPath:finalPath];
UIImage *image = [UIImage imageWithData:databuffer];
return image;
}
I have written code like this but I can't understand how to find if the data is present or not in the URL. Can anyone help me in solving this problem?
Note: This code terminates when the loop is entering the second condition. That is where it's terminating.
-(void)getdetails
{
NSLog(#"in get details");
NSURL *jsonurl=[NSURL URLWithString:#"http://www.myappdemo.com/checkout/services/getonlineusers.php"];
NSMutableURLRequest *request=[[[NSMutableURLRequest alloc]init ]autorelease];
[request setURL:jsonurl];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSError *error;
NSURLResponse *response;
NSData *serverReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *replyString = [[NSString alloc] initWithBytes:[serverReply bytes] length:[serverReply length] encoding: NSASCIIStringEncoding];
if([replyString isEqualToString:#"Invalid."]){ // i have not set the php code to output "invalid" so this will not work for now ...
NSLog(#"%#",replyString);
}
else {
NSMutableArray *tempArray =[replyString JSONValue];
int count=0;
self.temparray=tempArray;
for(int i=0;i<[tempArray count];i++)
{
///////Here in this loop when it is entering it is terminating /////////
NSDictionary *dict=[tempArray objectAtIndex:i];
NSLog(#"DICT is %#",dict);
NSString *string=[dict objectForKey:#"profilepic"];
NSURL *finalURL = [NSURL URLWithString:[string stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSLog(#"encoding string is %#",finalURL);
NSURL *url=[NSURL URLWithString:string];
NSString *source = [NSString stringWithContentsOfURL:finalURL encoding:NSUTF8StringEncoding error:nil];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:url];
NSLog(#"url is %#",url);
NSData *data=[NSData dataWithContentsOfURL:url];
if(!(data==nil))
{
NSLog(#"data is there");
UIImage *image=[[UIImage alloc]initWithData:data];
[self.array addObject:image];
[image release];
}
else {
/*
NSLog(#"if data is null condition block");
UIImage *image=[[UIImage alloc]init];
[self.array addObject:image];
[image release];
*/
}
count=count+1;
NSLog(#"count is %d",count);
}
}
[replyString release];
}
Where does the app terminate and what is the exception? Have you stepped through to see what the array object looks like during each iteration? Is it failing at NSData initWithContentsOfURL? Why don't you issue that as a separate synchronous request and test to see if you got a response?
Regarding your first (and any subsequent) synchronous request, it would probably be good to add a check to ensure you received a valid response (sorry for the formatting, the code tag isn't playing nicely at the moment)
if (response!=nil) {if([response isKindOfClass:[NSHTTPURLResponse class]]) {
// you have a valid response }}
i want to download file(s) from web server.
Scenario:
As user will select row (file name- user can select 1 or more files to download) and and press download, i am getting URL for each file(all have different URL) and storing into pathArray.
and doing following
-(void)downloadFile {
for (int i = 0; i<[pathArray count]; i++) {
NSURL *fileURL = [NSURL fileURLWithPath:[pathArray objectAtIndex:i]];
NSString *ResultURL = [fileURL absoluteString];
NSURL *url = [[NSURL alloc] initWithString:ResultURL];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL: url
cachePolicy: NSURLRequestReloadIgnoringCacheData timeoutInterval: 60.0];
conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if (conn) {
NSLog(#"*************CONNECTED************");
webData = [[NSMutableData data] retain];
NSLog(#"weblength : %d : ", [webData length]);
downloadTag = YES;
} else {
NSLog(#"*************Connection NOT DONE************");
downloadTag=NO;
}
}
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(#"*************Try to receive data************");
[webData appendData:data];
NSLog(#"weblength : %d : ", [webData length]);
NSLog(#"*************Data Received an append too ***********");
if (downloadTag == YES) {
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
self.documentsDir = [[paths objectAtIndex:0]stringByAppendingPathComponent:#"NewResult.zip" ];
[[NSFileManager defaultManager] createFileAtPath:documentsDir contents:nil attributes:nil];
NSFileHandle *file1 = [NSFileHandle fileHandleForUpdatingAtPath: documentsDir];
[file1 writeData: webData];
NSLog(#"Webdata : %d",[webData length]);
[file1 closeFile];
}
}
if i am not using for loop i.e only one file download then it work fine but not with for loop....its really important for me to solve this issue.
thank you very much
take a look at ASIHTTPRequest, it has a nice queue for downloading and monitoring progress http://allseeing-i.com/ASIHTTPRequest/How-to-use
You're using asynchronous downloads, but the delegate for each download item is the same object, causing all of the downloaded data to get appended to the same file. The way I do it is to have a small Object (DownloadQueueItem) that is the delegate for a single download. When you download another file, you create a new DownloadQueueItem and it handles everything.
Edit:
Q: instead of %i putting by my self i am searching is there any way to create new file every time like if ""NewResult.zip" is exist then create "NewResult1.zip" and so on
A: You could do something like this:
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filename = #"NewResult%#.zip";
for (int i = 0; ; i++) {
NSString *filename = NULL;
if (i == 0) {
filename = [NSString stringWithFormat:filename, #""];
}
else {
filename = [NSString stringWithFormat:filename, [NSString stringWithFormat:#"%i", i]];
}
if (![[NSFileManager defaultManager] fileExistsAtPath:filename]) {
// Save file.
break;
}
}