Unzipping .sqlite file using SSZipArchive OBJ-C - ios

I have a requirement of downloading .zip file from server and use it to project after extracting it. I have successfully downloaded the .sqlite file and i am able to extract it using right click(manually) but when i am trying to extract it using minizip and SSZipArchive or ZipArchive it's giving an error "Can't open the file".
If i extract .sqlite manually and compress .sqlite file by right clicking in mac then my code is extracting it completely but whenever i try to extract downloaded file directly then this issue is occurring.
I have applied below name formats for writing and extracting file.
While writing file the name was XYZ.sqlite.zip but it is also giving error
XYZ.zip and contained file name is XYZ.sqlite. This also giving error
I also have written file with name XYZ.sqlite.zip and then rename it with XYZ.zip and then extracted but that was also not working.
Below is the code.
For Downloading the file:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:zipURL]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[zipURL lastPathComponent]];
operation = [[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:path shouldResume:YES];
[operation.securityPolicy setAllowInvalidCertificates:YES];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
[self unzipDBFile:path];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation setProgressiveDownloadProgressBlock:
^(AFDownloadRequestOperation *operation, NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpected, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile) {
NSArray *progress = [NSArray arrayWithObjects:obj_Pro,[NSNumber numberWithFloat:totalBytesReadForFile/(float)totalBytesExpectedToReadForFile], nil];
[self performSelectorOnMainThread:#selector(updateProgressBar:) withObject:progress waitUntilDone:NO];
}];
[operation start];
For Extracting the file:
-(void)unzipDBFile:(NSString *)filePath
{
NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES) objectAtIndex:0];
NSString *outputPath = [documentDir stringByAppendingPathComponent:#"/DBFolder"];
BOOL isExtracted =[SSZipArchive unzipFileAtPath:outputPath toDestination:documentDir];
// NSString *filepath = [[NSBundle mainBundle] pathForResource:#"ZipFileName" ofType:#"zip"];
// ZipArchive *zipArchive = [[ZipArchive alloc] init];
// [zipArchive UnzipOpenFile:filePath];
// NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// NSString *path = [paths objectAtIndex:0];
// BOOL isExtracted=[zipArchive UnzipFileTo:path overWrite:YES];
// NSLog(#"PATH=%#",path);
if (!isExtracted)
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Error in extracting" message:#"" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}else{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Extract Success" message:#"" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
// [zipArchive UnzipCloseFile];
// [zipArchive release];
}
Below is the code for update progressbar:
- (void)updateProgressBar:(NSArray *)progress
{
UIProgressView *pgr = (UIProgressView *)[progress objectAtIndex:0];
[pgr setProgress:[[progress objectAtIndex:1] floatValue]];
}

I have examined the issue and found that .net developer, Who created .zip has used gzip compression so minizip is not able to extract it.
For decompress it, I have used iOS zlib framework and below code and that has solved my problem. You have to add below two things in the header before implementing this method.
#import <zlib.h>
#define CHUNK 16384
-(BOOL)unzipDBFile:(NSString *)filePath
{
NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES) objectAtIndex:0];
documentDir=[documentDir stringByAppendingPathComponent:DATABASE_FILE_NAME];
gzFile file = gzopen([filePath UTF8String], "rb");
FILE *dest = fopen([documentDir UTF8String], "w");
unsigned char buffer[CHUNK];
int uncompressedLength;
while ((uncompressedLength = gzread(file, buffer, CHUNK)) ) {
// got data out of our file
if(fwrite(buffer, 1, uncompressedLength, dest) != uncompressedLength || ferror(dest)) {
return FALSE;
}
}
fclose(dest);
gzclose(file);
return TRUE;
}

Related

How to remove extra data in my CSV Export?

This is for my iOS app using Core Data.
I'm getting some extra information in my CSV export that I'd like to remove. Below is my code and an example of what I am seeing.
Code:
NSOutputStream *stream = [[NSOutputStream alloc] initToMemory];
CHCSVWriter *writer = [[CHCSVWriter alloc] initWithOutputStream:stream encoding:NSUTF8StringEncoding delimiter:','];
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Notes"];
self.fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest error:nil];
for (NSString *instance in self.fetchedObjects) {
[writer writeLineOfFields:#[instance.description]];
}
[writer closeStream];
NSData *buffer = [stream propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
NSString *output = [[NSString alloc] initWithData:buffer encoding:NSUTF8StringEncoding];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths firstObject];
NSString * csvPath = [documentsDirectory stringByAppendingPathComponent:#"mydata.csv"];
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController * mailView = [[MFMailComposeViewController alloc] init];
mailView.mailComposeDelegate = self;
[[mailView navigationBar] setTintColor:[UIColor whiteColor]];
[mailView setSubject:#"My Subject Line"];
if (![[NSFileManager defaultManager] fileExistsAtPath:csvPath]) {
[[NSFileManager defaultManager] createFileAtPath:csvPath contents:nil attributes:nil];
}
BOOL res = [[output dataUsingEncoding:NSUTF8StringEncoding] writeToFile:csvPath atomically:NO];
if (!res) {
[[[UIAlertView alloc] initWithTitle:#"Error Creating CSV" message:#"Check your permissions to make sure this app can create files so you may email the app data" delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles: nil] show];
} else{
NSLog(#"Data saved! File path = %#", csvPath);
[mailView addAttachmentData:[NSData dataWithContentsOfFile:csvPath] mimeType:#"text/csv" fileName:#"mydata.csv"];
[self presentViewController:mailView animated:YES completion:nil];
}
} else {
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:#"Mail Error" message:#"Your device is not configured to send mail." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
Output Example:
<Notes: 0x1c009fb30> (entity: Notes; id: 0xd000000000080000 <x-coredata://597EDC54-FFDE-43FA-8C61-DE67763C1D13/Notes/p2> ; data: {
// My data shows here.
})
What I want:
I just want the saved data from the user input. Not the extra data about the entity, id, etc.
Also:
My data does not load in the email initially. I have to go into my UIViewController and then when I go to my Settings page and send the email the data shows. What would cause this?
You're getting that result because you're relying the description method to get information about your objects. That method produces a string, and the string is what you're seeing-- something that's not CSV, or easy to convert to CSV.
I'm not familiar with CHCSVParser but it looks like you might want to override description in your Notes class to produce something that CHCSVParser can handle. The default implementation on NSManagedObject-- which is what you're using now-- is not a good choice for this situation.

UIImageJPEGRepresentation fills Memory

The code below pumps the memory to the limit. I loaded about 100 Images and the memory went to 200MB. If I put the app in background and foreground, than it purge the memory from 200MB to around 10MB. How can I release the memory? The #autoreleasepool didn't work
#autoreleasepool {
NSData *imgData = UIImageJPEGRepresentation(image, 0.5);
NSString *name = [[NSUUID UUID] UUIDString];
NSString *path = [NSString stringWithFormat:#"Documents/%#.jpg", name];
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:path];
if ([imgData writeToFile:jpgPath atomically:YES]) {
data.imagePath = path;
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreWithCompletion:nil];
} else {
[[[UIAlertView alloc] initWithTitle:#"Error"
message:#"There was an error saving your photo. Try again."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil] show];
}
imgData = nil;
}

Unable to download image and PDF from mail successfully

I'm new to IOS development and i have a problem in downloading my attachments from mail.when i'm trying to download image or PDF attachments from my mail to documents directory using MailCore2 SDK it is downloading sucessfully.but my problem is that the downloaded image or PDF displays nothing (i.e.,).It gives me the file but with a empty file with zero bytes.im able to know that problem is with the NSData what im using to writeToFile is incorrect.But im unable to solve it.please help me.
Here is the code i'm using to download file from mail
MCOIMAPFetchContentOperation * op = [self.imapSession fetchMessageByUIDOperationWithFolder:#"INBOX" uid:[sender tag]];
[op start:^(NSError * error, NSData * data) {
if ([error code] != MCOErrorNone) {
return;
}
NSAssert(data != nil, #"data != nil");
MCOMessageParser * msg = [MCOMessageParser messageParserWithData:data];
if ([msg.attachments count] > 0)
{
MCOIMAPPart *part = [msg.attachments objectAtIndex:0];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *saveDirectory = [paths objectAtIndex:0];
NSLog(#"%#",part.filename);
NSString *attachmentPath = [[saveDirectory stringByAppendingString:#"/Downloads"] stringByAppendingPathComponent:part.filename];
if (fileExists) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message"
message:#"Fail Existed in Download Path."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
else{
[msg.data writeToFile:attachmentPath atomically:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message"
message:#"Download Success /n Saved in Downloads"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
[self.tableView reloadData];
}
}];
please help me to get out of this problem and tell me where am i doing mistake.
Thanks in advance.
I used like this:
MCOIMAPFetchContentOperation * op = [self.imapSession fetchMessageByUIDOperationWithFolder:#"INBOX" uid:[sender tag]];
[op start:^(NSError * error, NSData * data)
{
if ([error code] != MCOErrorNone)
{
return;
}
NSAssert(data != nil, #"data != nil");
MCOMessageParser * msg = [MCOMessageParser messageParserWithData:data];
if ([msg.attachments count] > 0)
{
MCOAttachment *attachment = [msg.attachments objectAtIndex:0];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *saveDirectory = [paths objectAtIndex:0];
NSLog(#"%#",attachment.filename);
NSString *downLoadDirectory = [saveDirectory stringByAppendingString:#"/Downloads"];
if (![[NSFileManager defaultManager] fileExistsAtPath:downLoadDirectory])
{
[[NSFileManager defaultManager] createDirectoryAtPath:downLoadDirectory withIntermediateDirectories:YES attributes:nil error:nil];
}
NSString *attachmentPath = [downLoadDirectory stringByAppendingPathComponent:attachment.filename];
if ([[NSFileManager defaultManager] fileExistsAtPath:attachmentPath])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message"
message:#"Fail Existed in Download Path."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
else
{
BOOL res = [[attachment data] writeToFile:attachmentPath atomically:YES];
if (res)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message"
message:#"Download Success /n Saved in Downloads"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
}
}];
I hope they are useful.

iOS iPhone can't open generated/saved KML file with Google Earth App

with the following code i try to open a generated and saved KML file in Google Earth App.
Google Earth app opens but it do nothing.
When i send this file with email and open it with GE App it works fine.
is there a way to open mml from my app in GE?
That the url i try to open:
kml:///var/mobile/Applications/****/Documents/google_earth.kml
here the code:
NSError *error;
BOOL success;
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileNameKML = [NSString stringWithFormat:#"%#/google_earth.kml", documentsDirectory];
NSString *GoogleEarthfileName = [NSString stringWithFormat:#"kml://%#", fileNameKML];
//NSLog([NSString stringWithFormat:#"Google Earth filename: %#", GoogleEarthfileName]);
NSURL *newURL = [NSURL URLWithString:GoogleEarthfileName];
success = [kmlExport writeToFile:fileNameKML atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (success){
if ([[UIApplication sharedApplication] canOpenURL:newURL])
{
[[UIApplication sharedApplication] openURL:newURL];
}
else
{
UIAlertView * alertView = [[[UIAlertView alloc] initWithTitle:#"Google Earth not installed" message:#"Please install Google Earth to view your tracked route." delegate:self cancelButtonTitle:NSLocalizedString(#"TXTOK", nil) otherButtonTitles: nil] autorelease];
[alertView show];
}
}
Thanks Kevin

How to compare user input to a column data in csv file?

I use the following code, but it only checks first column in first row. But I want to check first column of all rows in a csv file. Please help
- (void) SearchStudent
{
NSArray *DocumentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //I upload the csv file to documents folder of the app through itunes
NSString *DocumentDirectory = [DocumentPath objectAtIndex:0];
NSString *FullPath = [DocumentDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"example.csv"]];
NSString * pstrCSVFile= [NSString stringWithContentsOfFile:FullPath encoding:NSASCIIStringEncoding error:NULL];
NSArray * paRowsOfCSVFile= [pstrCSVFile componentsSeparatedByString:#"\n"];
NSArray *paColumnsOfRow;
NSString *pstrFirstColumn;
for(NSString * pstrRow in paRowsOfCSVFile)
{
paColumnsOfRow= [pstrRow componentsSeparatedByString:#","];
pstrFirstColumn= [paColumnsOfRow objectAtIndex:0];
if([pstrFirstColumn localizedCaseInsensitiveCompare:GWIDText.text] == NSOrderedSame)
{
UIAlertView *alertingFileName = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Found" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertingFileName show];
break;
}
else
{
UIAlertView *alertingFileName1 = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Not Found" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertingFileName1 show];
}
}
}
paColumnsOfRow contain all rows.

Resources