I have used some ways to check MD5 after downloading files. But, it seems that checking too much files md5 always lead to memory warning or crash for low memory. Does someone have a good solution for this?
I have use method to check MD5 from Joel's Writings, and other methods from other posts, but all could not solve my problem.
NSInteger index = 0;
while (downloadQueue.count > 0) {
NSLog(#"%i files need to download.", downloadQueue.count);
NSLog(#"00: %u", [MenChecker get_free_memory]);
#autoreleasepool {
NSString *src = [downloadQueue objectAtIndex:index];
NSString *path = [self.storageRoot stringByAppendingPathComponent:[storageList objectAtIndex:index]];
NSString *md5 = [md5CheckList objectAtIndex:index];
BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:path];
if (isExist) {
NSString *md5OfData = nil;
CFStringRef fileMD5Hash = FileMD5HashCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData);
if (fileMD5Hash) {
md5OfData = (__bridge NSString *)fileMD5Hash;
CFRelease(fileMD5Hash);
}
if ([md5OfData isEqualToString:md5]) {
[downloadQueue removeObjectAtIndex:index];
[storageList removeObjectAtIndex:index];
[md5CheckList removeObjectAtIndex:index];
}
else {
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
ASIHTTPRequest *request_cover = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:src]];
[request_cover setDownloadDestinationPath:path];
[request_cover startSynchronous];
NSString *md5OfDataFile = nil;
CFStringRef dataFileMD5Hash = FileMD5HashCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData);
if (dataFileMD5Hash) {
md5OfDataFile = (__bridge NSString *)dataFileMD5Hash;
CFRelease(dataFileMD5Hash);
}
if ([[NSFileManager defaultManager] fileExistsAtPath:path] && [md5OfDataFile isEqualToString:md5]) {
[downloadQueue removeObjectAtIndex:index];
[storageList removeObjectAtIndex:index];
[md5CheckList removeObjectAtIndex:index];
}
else {
index ++;
}
md5OfDataFile = nil;
}
md5OfData = nil;
}
else {
NSString *directory = [path stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#"/%#", [path lastPathComponent]] withString:#""];
[[NSFileManager defaultManager] createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:nil];
ASIHTTPRequest *request_cover = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:src]];
[request_cover setDownloadDestinationPath:path];
[request_cover startSynchronous];
request_cover = nil;
NSString *md5OfData = nil;
CFStringRef fileMD5Hash = FileMD5HashCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData);
if (fileMD5Hash) {
md5OfData = (__bridge NSString *)fileMD5Hash;
CFRelease(fileMD5Hash);
}
if ([[NSFileManager defaultManager] fileExistsAtPath:path] && [md5OfData isEqualToString:md5]) {
[downloadQueue removeObjectAtIndex:index];
[storageList removeObjectAtIndex:index];
[md5CheckList removeObjectAtIndex:index];
}
else {
index ++;
}
md5OfData = nil;
}
if (index >= downloadQueue.count) {
index = 0;
}
}
Related
Basically I got response from server side and then i saved it in local file.Actually I fetched the response from server side and then saved into documents directory ,and now trying to fetch but it comes in NSString only ,i unable to get in NSDictionary....Here is following code
- (IBAction)loginButtonPressed:(id)sender
{
NSString *URLString = #"http://localhost/rest/login";
AFHTTPSessionManager *manager =[AFHTTPSessionManager manager];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
NSDictionary *params = #{#"username": userNameTxtField.text, #"password": pwdTextField.text};
NSLog(#"Parameters:\n%#",params);
[manager POST:URLString parameters:params progress:nil success:^(NSURLSessionDataTask *operation, id responseObject)
{
NSLog(#"Successfully Login ....: %#", responseObject);
NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
path = [NSString stringWithFormat:#"%#/sample.json", documents];
NSOutputStream *stream = [[NSOutputStream alloc] initToFileAtPath:path append:YES];
[stream open];
NSError *writeError = nil;
NSInteger bytesWritten = [NSJSONSerialization writeJSONObject:responseObject toStream:stream options:NSJSONWritingPrettyPrinted error:&writeError];
if ((bytesWritten = 0))
{
NSLog(#"Error writing JSON Data");
}
else{
NSLog(#"Sucessfuly saved data...");
}
[stream close];
NSLog(#"path is :%#",path);
} failure:^(NSURLSessionDataTask *operation, NSError *error)
{
NSLog(#"Error: %#", error);
}];
}
- (IBAction)fetch:(id)sender
{
NSError *deserializingError;
NSData *data=[NSData dataWithContentsOfFile:path];
NSString *jsonString = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&deserializingError];
NSMutableDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(#"vaues are:%#",dict);
}
Your response object should be a type of NSDictionary. Therefore you can use its writeToFileAtPath method to save it to your documents directory.
When recreating the dictionary, you can use the NSDictionary's alloc and initWithContentsOfFile method to directly create a NSDictionary instance.
There are tons of posts on how to do that if you do a little Google search!
Try this!! It's working fine.
NSMutableDictionary *testStore = [[NSMutableDictionary alloc] init];
[testStore setObject:#"vignesh" forKey:#"username"];
[testStore setObject:#"password" forKey:#"password"];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:testStore // Here you can pass array or dictionary
options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
error:&error];
NSString *jsonString;
if (jsonData) {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
//This is your JSON String
//NSUTF8StringEncoding encodes special characters using an escaping scheme
} else {
NSLog(#"Got an error: %#", error);
jsonString = #"";
}
[self writeStringToFile:jsonString];
NSLog(#"Your JSON String is %#", [self readStringFromFile]);
- (void)writeStringToFile:(NSString*)aString {
// Build the path, and create if needed.
NSString* filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* fileName = #"bookmark.json";
NSString* fileAtPath = [filePath stringByAppendingPathComponent:fileName];
if (![[NSFileManager defaultManager] fileExistsAtPath:fileAtPath]) {
[[NSFileManager defaultManager] createFileAtPath:fileAtPath contents:nil attributes:nil];
}
// Write to file
[[aString dataUsingEncoding:NSUTF8StringEncoding] writeToFile:fileAtPath atomically:NO];
}
- (NSString*)readStringFromFile {
// Build the path...
NSString* filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* fileName = #"bookmark.json";
NSString* fileAtPath = [filePath stringByAppendingPathComponent:fileName];
// read from file
return [[NSString alloc] initWithData:[NSData dataWithContentsOfFile:fileAtPath] encoding:NSUTF8StringEncoding];
}
static const char *dbPath = nil;
static sqlite3_stmt *ermsg = nil;
static sqlite3 *studs =nil;
static DatabaseOperation *_sharedInstances = nil;
#implementation DatabaseOperation
#synthesize databasePath;
+(DatabaseOperation*)sharedInstances{
if(!_sharedInstances){
_sharedInstances =[[super allocWithZone:nil]init];
}
return _sharedInstances;
}
+(id)allocWithZone:(struct _NSZone *)zone{
return [self sharedInstances];
}
-(id)init{
NSLog(#"Only first time Instances using Singleton:");
self =[super init];
if(self){
[self CreateDbpath];
}
return self;
}
-(BOOL)CreateDbpath{
NSArray *dbpaths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docdir=[[NSString alloc]initWithString:[dbpaths objectAtIndex:0]];
self.databasePath =[[NSString alloc]initWithString:[docdir stringByAppendingPathComponent:#"Mindset.sqlite"]];
NSFileManager *flg = [NSFileManager defaultManager];
BOOL isSuccess = false;
if([flg fileExistsAtPath:databasePath]==NO){
char *ermsgss = nil;
char const *dbpathss =[self.databasePath UTF8String];
if(sqlite3_open(dbpathss, &studs)==SQLITE_OK){
char *sqlQuery ="create table if not exists emp(name text,city text,img blob)";
if(sqlite3_exec(studs, sqlQuery, nil, nil, &ermsgss)!=SQLITE_OK){
NSLog(#"Failed to create table:");
}
else{
NSLog(#"Successfully to create table:");
}
}
sqlite3_close(studs);
}
return isSuccess;
}
-(void)insertDatabaseValue:(DataManagers *)getInserted{
dbPath = [self.databasePath UTF8String];
if(sqlite3_open(dbPath, &studs)==SQLITE_OK){
NSString *sqlQuery=[[NSString alloc]initWithFormat:#"insert into emp values(?,?,?)"];
const char *_sqlQuery=[sqlQuery UTF8String];
if(sqlite3_prepare_v2(studs, _sqlQuery, -1, &ermsg, nil)==SQLITE_OK){
sqlite3_bind_text(ermsg, 1, [getInserted.userName UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(ermsg, 2, [getInserted.cityName UTF8String], -1, SQLITE_TRANSIENT);
NSData *jpegData =[[NSData alloc]init];
NSData *imgeData =UIImageJPEGRepresentation(getInserted.profileImg, 0.85f);
UIImage *imgesData =[UIImage imageWithData:imgeData];
CGRect rect = CGRectMake(0, 0, 185, 150);
UIGraphicsBeginImageContext(rect.size);
[imgesData drawInRect:rect];
UIImage *img =UIGraphicsGetImageFromCurrentImageContext()
;
UIGraphicsEndImageContext();
jpegData = UIImageJPEGRepresentation(img, 0.01f);
sqlite3_bind_blob(ermsg, 3, [jpegData bytes], [jpegData length], SQLITE_TRANSIENT);
if(sqlite3_step(ermsg)==SQLITE_DONE){
NSLog(#"Successfully inserted into db:");
}
else {
NSLog(#"Error %s",sqlite3_errmsg(studs));
}
}
sqlite3_close(studs);
sqlite3_finalize(ermsg);
}
}
-(NSMutableArray*)getAllData {
NSMutableArray *array =[[NSMutableArray alloc]init];
dbPath = [self.databasePath UTF8String];
if(sqlite3_open(dbPath, &studs)==SQLITE_OK){
NSString *sqlQuery =[[NSString alloc]initWithFormat:#"select * from emp"];
const char *_sqlQuery =[sqlQuery UTF8String];
if(sqlite3_prepare_v2(studs, _sqlQuery, -1, &ermsg, nil)==SQLITE_OK){
while (sqlite3_step(ermsg)==SQLITE_ROW) {
DataManagers *mgr =[[DataManagers alloc]init];
NSString *_Firstname = (const char*)sqlite3_column_text(ermsg, 0) ? [NSString stringWithUTF8String:(const char*)sqlite3_column_text(ermsg, 0)]:nil;
mgr.userName = _Firstname;
NSString *lastName =(const char*)sqlite3_column_text(ermsg, 1)?[NSString stringWithUTF8String:(const char*)sqlite3_column_text(ermsg, 1)]:nil;
mgr.cityName = lastName;
int imgBytes = sqlite3_column_bytes(ermsg, 2);
UIImage *img =[UIImage imageWithData:[NSData dataWithBytes:sqlite3_column_blob(ermsg, 2) length:imgBytes]];
mgr.profileImg = img;
[array addObject:mgr];
}
}
}
return array;
}
I need to sort 8145 objects (there may be more) for files and folders. (Tested on A8X).
First method.
for(NSString *filename in FilesList) //This method takes an average of 7.7 seconds.
{
fileExtension = (__bridge CFStringRef)[filename pathExtension];
fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
if ([[[[NSFileManager defaultManager] attributesOfItemAtPath:[FolderPath stringByAppendingPathComponent:filename] error:nil] fileType] isEqualToString:#"NSFileTypeDirectory"] && !UTTypeConformsTo(fileUTI, kUTTypeRTFD))
[OnlyFolderList addObject:filename];
else
[OnlyFilesList addObject:filename];
}
Second method.
for(NSString *filename in FilesList) //This method takes an average of 2.9 seconds.
{
fileExtension = (__bridge CFStringRef)[filename pathExtension];
fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
[[NSFileManager defaultManager] fileExistsAtPath:[FolderPath stringByAppendingPathComponent:filename] isDirectory:&isDir];
if (isDir && !UTTypeConformsTo(fileUTI, kUTTypeRTFD))
[OnlyFolderList addObject:filename];
else
[OnlyFilesList addObject:filename];
}
Do you know a faster way?
-----Update with add fastest method----- // 0.26 seconds for 8145 objects!
NSNumber *isDirectory;
NSError *error = nil;
NSString *name;
NSArray *FilesList = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:[NSURL fileURLWithPath:FolderPath] includingPropertiesForKeys:[NSArray arrayWithObjects:NSURLIsDirectoryKey,NSURLNameKey,nil] options:NSDirectoryEnumerationSkipsHiddenFiles error:nil];
for (NSURL *url in FilesList)
{
[url getResourceValue:&name forKey:NSURLNameKey error:&error];
[url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error];
if ([isDirectory boolValue])
{
CFStringRef fileExtension = (__bridge CFStringRef)[name pathExtension];
CFStringRef fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
if (!UTTypeConformsTo(fileUTI, kUTTypeRTFD))
[OnlyFolderList addObject:name];
else
[OnlyFilesList addObject:name];
}
else
[OnlyFilesList addObject:name];
}
Try using contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error::
NSURL *root = ... // the root URL to get the file list from
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
NSArray *filesList = [fm contentsOfDirectoryAtURL:root includingPropertiesForKeys:#[ NSURLIsDirectoryKey, NSURLTypeIdentifierKey ] options:NSDirectoryEnumerationSkipsHiddenFiles error:&error];
if (dirURLs) {
for (NSURL *fileURL in filesList) {
NSString *filename = [[fileURL path] lastPathComponent];
NSNumber *isDir = nil;
[fileURL getResourceValue:&isDir forKey:NSURLIsDirectoryKey error:nil]
if ([isDir boolValue]) {
NSString *uti;
[fileURL getResourceValue:&uti forKey:NSURLTypeIdentifierKey error:nil];
if ([(__bridge NSString *)kUTTypeRTFD isEqualToString:uti]) {
[OnlyFilesList addObject:filename];
} else {
[OnlyFoldersList addObject:filename];
}
} else {
[OnlyFilesList addObject:filename];
}
}
} else {
NSLog(#"Unable to get list of files in %#: %#", root, error);
}
In the second method move fileExtension and fileUTI inside a test for isDir so that code does not run if the file is not potentially a directory.
Try this:
NSFileManager *fileManager = [NSFileManager defaultManager];
for(NSString *filename in FilesList) {
[fileManager fileExistsAtPath:[FolderPath stringByAppendingPathComponent:filename] isDirectory:&isDir];
if (isDir) {
CFStringRef fileExtension = (__bridge CFStringRef)[filename pathExtension];
CFStringRef fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
if (!UTTypeConformsTo(fileUTI, kUTTypeRTFD))
[OnlyFolderList addObject:filename];
else
[OnlyFilesList addObject:filename];
}
else
[OnlyFilesList addObject:filename];
}
Try using the BSD API directly.
static BOOL cStringHasSuffix(const char *string, const char *suffix) {
unsigned long stringLength = strlen(string);
unsigned long suffixLength = strlen(suffix);
return stringLength >= suffixLength && memcmp(string + stringLength - suffixLength, suffix, suffixLength) == 0;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSURL *url = [[NSBundle mainBundle] bundleURL];
NSMutableArray *folderNames = [NSMutableArray array];
NSMutableArray *fileNames = [NSMutableArray array];
const char *rtfdSuffix = ".rtfd";
DIR *dir = opendir(url.fileSystemRepresentation);
struct dirent *item;
while ((item = readdir(dir))) {
NSString *name = [NSString stringWithUTF8String:item->d_name];
if (item->d_type == 0) {
NSLog(#"unknown type for %#", name);
} else if (item->d_type == DT_DIR) {
if (cStringHasSuffix(item->d_name, rtfdSuffix)) {
[fileNames addObject:name];
} else {
[folderNames addObject:name];
}
} else if (item->d_type == DT_REG) {
[fileNames addObject:name];
} else {
NSLog(#"unexpected type %d for %#", item->d_type, name);
}
}
closedir(dir);
NSLog(#"fileNames = %#", fileNames);
NSLog(#"folderNames = %#", folderNames);
return YES;
}
I successfully test my in app purchase function and downloaded the content. However I am not sure of an right way to transfer it to Document folder. I tested with the code:
-(void)paymentQueue:(SKPaymentQueue *)queue updatedDownloads:(NSArray *)downloads
{
for (SKDownload *download in downloads)
{
switch (download.downloadState) {
case SKDownloadStateActive:
NSLog(#"Download progress = %f",
download.progress);
NSLog(#"Download time = %f",
download.timeRemaining);
break;
case SKDownloadStateFinished:
[self downloadFromURL:download.contentURL];///<--This is the function.
break;
}
}
}
-(void)downloadFromURL: (NSURL *) temporaryURL {
NSString *folderName = [[temporaryURL path] lastPathComponent];
NSArray *pathArr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *folder = [pathArr objectAtIndex:0];
NSString *filePath = [folder stringByAppendingPathComponent:folderName];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
NSError *writeError = nil;
NSData *downloadData = [[NSData alloc] initWithContentsOfURL:temporaryURL];
[downloadData writeToURL: fileURL options:0 error:&writeError];
if( writeError) {
NSLog(#"Error in writing file %#' : \n %# ", filePath , writeError);
return;
}
NSLog(#"File successfully downloaded. Url is %#",fileURL.absoluteString);
//myFileURL = fileURL;
NSFileManager *filemgr;
NSArray *filelist;
int count;
int i;
filemgr =[NSFileManager defaultManager];
filelist = [filemgr contentsOfDirectoryAtPath:folder error:NULL];
count = [filelist count];
NSLog(#"file count %i",count);
for (i = 0; i < count; i++)
NSLog(#"%#", filelist[i]);
}
I get a #"File successfully downloaded. Url is %#" from the code above but NSLog(#"%#", filelist[i]); give me no content. What else is missing here? I found out about this link
but not sure how to incorporate into my code. Any pointer will be good.
Let's check:
-(void)downloadFromURL: (NSURL *) temporaryURL {
// at this time, file is downloaded successfully???
// I think you should check here
NSURL * temporaryURL;
NSFileManager *fm = [NSFileManager defaultManager];
BOOL existed = [fm fileExistsAtPath:temporaryURL.path];
if(existed) // file is existed
else // file is not existed == maybe download fails
}
I have gotten this code from somewhere else with a little editing which allows to go through all the directories with the starting path specified using enumeratorAtPath. With this code i am able to retrieve files with a certain extension which has read attribute using isReadableFileAtPath. What i would like is to retrieve all files with any extension which has read attribute and classify them into different categories based on their last folder name.
Example if i have a path /a/b/c/example.plist, /a/b/c/example.plist would be classified under c.
- (NSString *) retrievePaths
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableString *filePaths = [[NSMutableString alloc] init];
NSDirectoryEnumerator *dirnum = [[NSFileManager defaultManager] enumeratorAtPath:#"/"];
NSString *nextItem = [NSString string];
int i = 0;
while( (nextItem = [dirnum nextObject]))
{
if([[nextItem pathExtension] isEqualToString:#"db"] || [[nextItem pathExtension] isEqualToString:#"sqlitedb"] || [[nextItem pathExtension] isEqualToString:#"sqlite"]) {
if([fileManager isReadableFileAtPath:nextItem])
{
i++;
[filePaths appendFormat:#"%d)",i];
[filePaths appendString:nextItem];
[filePaths appendString:#"\n"];
}
}
}
NSString *format = [NSString stringWithFormat:#"Paths : %#", filePaths];
return format;
}
Remove below if condition from your code and you will be able to get all files with readable access permission
if([[nextItem pathExtension] isEqualToString:#"db"] || [[nextItem pathExtension] isEqualToString:#"sqlitedb"] || [[nextItem pathExtension] isEqualToString:#"sqlite"])
EDIT
Updated function try this, will work for you..
- (NSString *) retrievePaths
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableString *filePaths = [[NSMutableString alloc] init];
NSString *path = #"/Assign/your/path/"; // assign your path
NSDirectoryEnumerator *dirnum = [[NSFileManager defaultManager] enumeratorAtPath:path];
NSString *nextItem = [NSString string];
int i = 0;
while( (nextItem = [dirnum nextObject]))
{
NSString *filePath = [path stringByAppendingPathComponent:nextItem];
BOOL isDir = NO;
[[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDir];
if(NO == isDir) {
if([fileManager isReadableFileAtPath:filePath])
{
i++;
[filePaths appendFormat:#"%d)",i];
[filePaths appendString:nextItem];
[filePaths appendString:#"\n"];
}
}
}
NSString *format = [NSString stringWithFormat:#"Paths : %#", filePaths];
return format;
}
In my app I want to copy files from one directory to another directory. In the source directory there are files and folders.
I do this in the code below:
- (BOOL)copyDirectory:(NSString*)Directory toDirectory:(NSString*)targetDirectory
{
NSLog(#"start copy");
#try
{
NSError *error = nil;
NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES) objectAtIndex:0];
NSString *folderPath = [path stringByAppendingPathComponent:targetDirectory];
BOOL succes = [[NSFileManager defaultManager] fileExistsAtPath:folderPath];
if(succes){
return NO;
}
else
{
NSString *wwwPath = [[NSBundle mainBundle] pathForResource:Directory ofType:nil];
NSArray *target= [[NSFileManager defaultManager] contentsOfDirectoryAtPath:wwwPath error:&error];
[[NSFileManager defaultManager] createDirectoryAtPath:folderPath withIntermediateDirectories:NO attributes:nil error:nil];
int a = 0 ;
for(a = 0 ; a < target.count;a++){
NSString *temp = [target objectAtIndex:a];
if([temp rangeOfString:#"."].location == NSNotFound)
{
NSString *sourceDirectory = [NSString stringWithFormat:#"%#/%#",Directory,temp ];
NSString *DestanistionDirectory = [NSString stringWithFormat:#"%#/%#",targetDirectory,temp];
if([self copyDirectory:sourceDirectory toDirectory:DestanistionDirectory] == NO){
return NO;
}
}
else
{
NSString *source = [NSString stringWithFormat:#"%#/%#",wwwPath,temp];
NSString *target = [NSString stringWithFormat:#"%#/%#",folderPath,temp];
BOOL result = [[NSFileManager defaultManager] copyItemAtPath:source toPath:target error:&error];
if(result)
currentFileCounter++;
[self performSelectorInBackground:#selector(updatePrograsBar) withObject:nil];
if(error != nil){
if(IsDEBUG) NSLog(#"error: %#",[error description]);
return NO;
}
}
}
}
}
#catch (NSException *exception)
{
if(IsDEBUG)NSLog(#"%#",exception.description);
return NO;
}
NSLog(#"end copy");
return YES;
}
To save time, when I call to
- (BOOL)copyDirectory:(NSString*)Directory to Directory:(NSString*)target Directory
in recursive I call in new thread.
- (BOOL)copyDirectory:(NSString*)Directory toDirectory:(NSString*)targetDirectory
{
NSLog(#"start copy");
#try
{
NSError *error = nil;
NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES) objectAtIndex:0];
NSString *folderPath = [path stringByAppendingPathComponent:targetDirectory];
BOOL succes = [[NSFileManager defaultManager] fileExistsAtPath:folderPath];
if(succes){
return NO;
}
else
{
NSString *wwwPath = [[NSBundle mainBundle] pathForResource:Directory ofType:nil];
NSArray *target= [[NSFileManager defaultManager] contentsOfDirectoryAtPath:wwwPath error:&error];
[[NSFileManager defaultManager] createDirectoryAtPath:folderPath withIntermediateDirectories:NO attributes:nil error:nil];
int a = 0 ;
for(a = 0 ; a < target.count;a++){
NSString *temp = [target objectAtIndex:a];
if([temp rangeOfString:#"."].location == NSNotFound)
{
NSString *sourceDirectory = [NSString stringWithFormat:#"%#/%#",Directory,temp ];
NSString *DestanistionDirectory = [NSString stringWithFormat:#"%#/%#",targetDirectory,temp];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self copyDirectory:sourceDirectory toDirectory:DestanistionDirectory];
});
}
else
{
NSString *source = [NSString stringWithFormat:#"%#/%#",wwwPath,temp];
NSString *target = [NSString stringWithFormat:#"%#/%#",folderPath,temp];
BOOL result = [[NSFileManager defaultManager] copyItemAtPath:source toPath:target error:&error];
if(result)
currentFileCounter++;
[self performSelectorInBackground:#selector(updatePrograsBar) withObject:nil];
if(error != nil){
if(IsDEBUG) NSLog(#"error: %#",[error description]);
return NO;
}
}
}
}
}
#catch (NSException *exception)
{
if(IsDEBUG)NSLog(#"%#",exception.description);
return NO;
}
NSLog(#"end copy");
return YES;
}
but I need to know when is finish to copy all the files and folder and not return from the main call to
-(BOOL)copyDirectory:(NSString*)Directory to Directory:(NSString*)target Directory
until finish all.