Unable to unzip using ZipArchieve in ios? - ios

I have downloaded a file(ZipSecretExcel.zip) which is stored in the document directory. I am now trying to unzip this file in the document directory using ZipArchieve using the following code:
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *zipFilePath = [documentsDirectory stringByAppendingPathComponent:#"ZippSecretExcel.zip"];
NSString *output = [documentsDirectory stringByAppendingPathComponent:#"UnZipSecret"];
ZipArchive* za = [[ZipArchive alloc] init];
if( [za UnzipOpenFile:zipFilePath] ) {
if( [za UnzipFileTo:output overWrite:YES] != NO ) {
//unzip data success
//do something
//NSLog(#"Folder successfully zipped");
}
[za UnzipCloseFile];
}
However, folder successfully zipped log message never gets printed which means there is failure in unzipping. Can anyone tell what is that I am doing wrong?

Related

File is present but error : "no such table"

I have a problem in my app and I don't know where it comes from ...
So I add my file to my project The on highlighted !
But when I want to init and select in my table I have an error :
no such table
I'm pretty sure the table is here beceause in my terminal I got this :
And I do the same request in my code :
tableData = [sqlManager getList:#"SELECT name_fr FROM info_max"];
sqlManager works with the 3 other files ..
I use this to init
-(id)initDatabase:(NSString*)dbName {
if (self = [super init]) {
//Nom de la base de données
databaseName = dbName;
//Obtention du chemin complet de la base de données
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
}
return self;
}
EDIT
And my query is executed like this :
-(NSMutableDictionary *)getList:(NSString*)typeOfRequest{
sqlite3 *database;
const char *sqlStatement = [typeOfRequest UTF8String];
NSMutableDictionary *aromaArray = [[NSMutableDictionary alloc] init];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
sqlite3_stmt *compiledStatement;
//Compilation de la requete et verification du succes
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
NSDictionary *dictionary = [self indexByColumnName:compiledStatement]; // Creation d'un dictionnaire des noms de colonnes
NSMutableArray *array = [[NSMutableArray alloc] init];
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
char *tab = (char*)sqlite3_column_text(compiledStatement, [[dictionary objectForKey:nil] intValue]);
NSString *finalUpperCase = [[NSString stringWithUTF8String:tab] capitalizedString];
if (finalUpperCase != nil && finalUpperCase.length >0 && !([finalUpperCase isEqualToString:#"Null"])) {
[array addObject:finalUpperCase];
}
}
aromaArray = [self getDictionnary:array];
}
else {
NSAssert1(0, #"Erreur :. '%s'", sqlite3_errmsg(database));
}
sqlite3_finalize(compiledStatement); // Finalise la requete et libere le statement
}
else {
NSAssert(0, #"Erreur d'ouverture de la base de donnees");
}
sqlite3_close(database);
return aromaArray;
}
Sometimes Xcode its a mess and it's Derived Data keep references of files, so sometimes you need to clear the Product and Run it again.
Quit XCode
Go to derived data's folder, delete them (also from trash).
Open XCode clean project and try to build it again
For insert and Update queries that is not enough:
Insert and Update Queries
When you copy this file to bundle (target) you have this file only read-only. To make it readable and be able to make insert queries follow the solution below:
This code creates a writable copy of the bundled default database in the application Documents directory. Put it on application didFinishLaunchingWithOptions on appDelegate and now you will be able to test your queries:
// First, test for existence.
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"info_max.sqlite3"];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success) return;
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"info_max.sqlite3"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success)
{
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
You must have to also try move that Database(sqlite) file to out of project directory and add it again and clear all cache data.
it is work for me.

linphone_call_take_video_snapshot saved empty file

I am working on a project based on Linphone-iPhone, the project requires taking a snapshot of current video stream (both in and out).
I've found this 'linphone_call_take_video_snapshot' in liblinphone and gave it a try.
The code was simple and running without any error, but the size of the saved file is always 0 kb!
Here's the code:
- (void)capture {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *file_path = [documentsDirectory stringByAppendingPathComponent:#"snapshot.jpeg"];
LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]);
const char *c_file_path = [file_path cStringUsingEncoding:NSUTF8StringEncoding];
int ret = linphone_call_take_video_snapshot(call, c_file_path);
if (ret >= 0 && [[NSFileManager defaultManager] fileExistsAtPath:file_path]) {
UIImageWriteToSavedPhotosAlbum([UIImage imageWithContentsOfFile:file_path], nil,nil,nil);
}
}
Does linphone_call_take_video_snapshot really work? If so, what have I been doing wrong?

Unzipping NSData with ZipArchive

I am using ZipArchive and am reading data in from a device. What I want to do is take the data from the device and unzip it. The only examples I can find are taking the data, writing it to a file on the iOS device, and reading (unzipping) it back again...
This is the code (not working) that I have writing it to disk...
// Read the data in...
if ((recvStringLen = recvfrom(connectSock, recvString, 1025, 0, (struct sockaddr *)&broadcastAddr, &recvStringLen)) < 0) {
NSLog(#"ERROR: Unable to receive user perms message.");
[self showTimeoutError];
return -1;
}
// get the file size...
unsigned int fileSize = (( recvString[16] << 24 ) & 0xff000000) |
(( recvString[17] << 16 ) & 0xff0000) |
(( recvString[18] << 8 ) & 0xff00 ) |
( recvString[19] & 0xff );
NSLog(#"fileSize: %i", fileSize);
recvString[20+fileSize] = '\0'; // terminate the string...
// convert the char data to a string
NSString *stringData = [[[NSString alloc] initWithFormat:#"%s", &recvString[20]] autorelease];
NSData *data = [[[NSData alloc] initWithBytes:stringData length:fileSize] autorelease];
// write the data...
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:#"userinfo.zip"];
[data writeToFile:appFile atomically:YES];
// exist?
BOOL zipExists = [[NSFileManager defaultManager] fileExistsAtPath:appFile];
NSString *zipFilePath = [documentsDirectory stringByAppendingPathComponent:#"userinfo.zip"];
NSString *output = [documentsDirectory stringByAppendingPathComponent:#"userinfo.dat"];
ZipArchive* za = [[ZipArchive alloc] init];
// unzip it...
BOOL success = [za UnzipOpenFile:zipFilePath];
if( success ) {
BOOL outSuccess = [za UnzipFileTo:output overWrite:YES];
if( outSuccess != NO ) {
NSLog(#"success");
}
[za UnzipCloseFile];
}
[za release];
BOOL datExists = [[NSFileManager defaultManager] fileExistsAtPath:output];
When it gets to 'success', it is always NO... even though 'zipExists' is YES.
The two issues I have:
1. The I haven't successfully written the data to disk, read it back, and unzipped it.
2. I would rather just unzip the data (NSData) instead of going thru writing it to disk and reading it back again...
I searched before posting, but was unable to find a solution...
Skip creating a NSString - that is your problem (or one of them). Create the data object from recvString directly. Think about what happens using %s if the data has a null byte.

Not able to access iOS SQLite database: sqlite3_prepare_v2 and 'no such table' sqlite3_errmsg

This is the first time I'm trying to create and access a SQLite db in iOS and I followed a tutorial, but I can't make this work. These are the steps I've followed:
Created a database through the Firefox plugin ("testDatabase") and a
table ("testTable") with several columns
Saved the "testDatabase.sqlite" file in a directory
Dragged and dropped such file into my "Supporting Files" group in my
Xcode project
Added "libsqlite3.dylib" in Build Phases > Link Binary With
Libraries
Added "-lsqlite3" in Build Settings > Linking > Other Linker Flags >
Debug and Release
In a ViewController, called this method:
-(NSString *)copyDatabaseToDocuments {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"testDatabase.sqlite"];
if ( ![fileManager fileExistsAtPath:filePath] ) {
NSString *bundlePath = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:#"testDatabase.sqlite"];
[fileManager copyItemAtPath:bundlePath toPath:filePath error:nil];
}
return filePath;
}
Then, trying to write in the database:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"testDatabase.sqlite"];
sqlite3 *database;
if(sqlite3_open([filePath UTF8String], &database) == SQLITE_OK) {
const char *sqlStatement = "insert into testTable (id) VALUES (?)";
sqlite3_stmt *compiledStatement;
if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
sqlite3_bind_int(compiledStatement, 1, newObject.ID);
}
if(sqlite3_step(compiledStatement) == SQLITE_DONE) {
sqlite3_finalize(compiledStatement);
}
}
sqlite3_close(database);
I have read several posts regarding a similar error, but nothing of what I tried has worked for me... I also tried with NSString *filePath = [[NSBundle mainBundle] pathForResource:#"testDatabase" ofType:#"sqlite"]; but it is null, and also have underplayed and redeployed my app in the simulator several times...
Thanks in advance
I finally got this working by simply deleting the app folder generated in /Users/[user]/Library/Application Support/iPhone Simulator/5.1/Applications/ to be created again when running the simulator

Why does NSBundle mainBundle work, but not documentsDirectory?

I am trying to to make a connection to a database and I'm finding that it is successful when I make the path go to NSBundle, but not when I try make the path be in my app's documents directory. Here is my code:
-(IBAction)setInput:(id)sender
{
NSString *strStoreNumber;
NSString *strRegNumber;
strStoreNumber = StoreNumber.text;
strRegNumber = RegNumber.text;
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths lastObject];
NSString* databasePath = [documentsDirectory stringByAppendingPathComponent:#"tblStore.sqlite"];
// NSString* databasePath = [[NSBundle mainBundle] pathForResource:#"tblStore" ofType:#"sqlite"];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"Opened sqlite database at %#", databasePath);
sqlite3_exec(database, "CREATE TABLE IF NOT EXISTS tblStore (ID INTEGER PRIMARY KEY AUTOINCREMENT, Message TEXT)", NULL, NULL, NULL);
//...stuff
}
else
{
NSLog(#"Failed to open database at %# with error %s", databasePath, sqlite3_errmsg(database));
sqlite3_close (database);
}
//
NSString *querystring;
// create your statement
querystring = [NSString stringWithFormat:#"SELECT strStore, strReg FROM tblStore WHERE strStore = %# AND strReg = %#;", strStoreNumber, strRegNumber];
const char *sql = [querystring UTF8String];
NSString *szStore = nil;
NSString *szReg = nil;
sqlite3_stmt *statement = nil;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL)!=SQLITE_OK) //queryString = Statement
{
NSLog(#"sql problem occured with: %s", sql);
NSLog(#"%s", sqlite3_errmsg(database));
}
else
{
// you could handle multiple rows here
while (sqlite3_step(statement) == SQLITE_ROW)
{
szStore = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)];
szReg = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 1)];
}
}
sqlite3_finalize(statement);
lblStoreNumber.text = szStore;
lblRegNumber.text = szReg;
//
}
I commented out the line:
NSString* databasePath = [[NSBundle mainBundle] pathForResource:#"tblStore" ofType:#"sqlite"];
When this line is NOT commented out, and the lines above it ARE commented out:
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths lastObject];
NSString* databasePath = [documentsDirectory stringByAppendingPathComponent:#"tblStore.sqlite"];
Then it works fine. However, if those three lines are not commented out (as shown in the setInput method, then I get the following errors:
2012-05-07 13:44:29.511 CCoDBTry[1981:f803] Opened sqlite database at /Users/Matt****/Library/Application Support/iPhone Simulator/5.1/Applications/5DB7A218-A0F6- 485F-B366-91FD2F9BC062/Documents/tblStore.sqlite
2012-05-07 13:44:29.545 CCoDBTry[1981:f803] sql problem occured with: SELECT strStore, strReg FROM tblStore WHERE strStore = 8053 AND strReg = 4;
2012-05-07 13:44:29.546 CCoDBTry[1981:f803] no such column: strStore
Keep in mind, this same database table is accessed and works just fine when I use the NSBundle logic. I admit I don't fully understand the difference between NSBundle and documentsDirectory, but I think I would want my table to exist in my app's documents. I would greatly appreciate any help on this.
Thanks!
NSBundle is used to access resources within your application itself: that is, everything inside YourApp.app. The documentsDirectory is a location outside of your app -- it's in the "home directory" which is part of your app sandbox, and which is analogous to your user home directory on the Mac.
These are different locations, so using one to find a file at the same subpath of another won't work.
What #rickster is saying is this:
If you add the sqlite database to your project in Xcode, the database's file gets added to your app's bundle.
If you create the database in code, the file will (most likely) get created in your documents directory (but surely not in your bundle).
The two locations are completely separate. Your bundle is created when your app is compiled and cannot be changed later. Your documents directory is "sandboxed", which allows you access to it; you can read/write/delete files here.
Copy from NSBUndle TO NSDocumentDirectory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"culinary-Info.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:path])
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"culinary-Info" ofType:#"sqlite"];
[fileManager copyItemAtPath:bundle toPath:path error:nil];
}

Resources