Unzipping NSData with ZipArchive - ios

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.

Related

We are facing problem while creating compressed file of transferred socket data in hex string to converting to .tgz file in iOS App

We are facing problem while creating compressed file at iOS Device Document Directory, .tgz file is in Hex string transferring from pin-pad device to iPad iOS App at TCP socket layer. We used below HexToString function to convert that hex string and make file with .tgz. but at the end file is corrupted.
Can anyone please help us here, how to create compress file at iOS level with below hex string ? Please suggest us any code changes.
Note :- we had tried multiple NSStringEncoding technique, like ASCII, Unicode, Utf8, etc.
HEX String:-
1F8B08003058A8620203EDCA3B0A80301045D1594A5660265FB7E036065422A8453282CB57B4B2B112419CD3DCE2BD6966DD8F54925E4A975B62D22551EE741A2A5E199E80BBE8F1681DFDA5270BC6DB60D1398735A0092E0650082F580A53566A6F36F7BFFBFDA39A01841042FCD0062C8057FA00080000
we are using Xcode Version:13.1 and IOS Version 15.1 and above.
//Below function we used for creating .tgz file
//fileName here is abc.tgz which is compress file type
//content here is hex string mention aboved
+ (void)writeToLogFile:(NSString*)content fileName:(NSString*)fileNameString{
content = [NSString stringWithFormat:#"%#",content];
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:fileNameString];
NSData *fileOriginalString = [self HextoString:content];
NSData *fileData = [fileOriginalString dataUsingEncoding:NSASCIIStringEncoding];
***//In alternative we also tried direct hex string to NSData type by calling below commentented method but it still failing
//NSData *fileData = [self dataFromHexString:content];***
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSError *error = nil;
[fileData writeToFile:fileName options:NSDataWritingAtomic error:&error];
NSLog(#"Write returned error: %#", [error localizedDescription]);
});
}
//Below function we used for Hex to String conversion
+(NSString*)HextoString:(NSString*)string{
#try{
NSMutableString * StrResult = [[NSMutableString alloc] init];
int i = 0;
while (i < [string length]){
NSString * hexChar = [string substringWithRange: NSMakeRange(i, 2)];
int value = 0;
sscanf([hexChar cStringUsingEncoding:NSASCIIStringEncoding], "%x", &value);
[StrResult appendFormat:#"%c", (char)value];
i+=2;
}
return StrResult;
}
#catch (NSException *exception){
[AELoggerManager info:[NSString stringWithFormat:#" %s EXCEPTION ::%#",__FUNCTION__,exception]];
}
}
+ (NSData *)dataFromHexString:(NSString *) string {
if([string length] % 2 == 1){
string = [#"0"stringByAppendingString:string];
}
const char *chars = [string UTF8String];
int i = 0, len = (int)[string length];
NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {'\0','\0','\0'};
unsigned long wholeByte;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:2];
}
return data;
}

Best way to save lots of streaming data from iPhone

Currently, I am streaming image and depth data from my iphone X and doing a series of computations on it using a compute metal kernel. The output every cycle (frame) is approximately 900,000 floats. Assuming there are 30 cycles (frames) a second, this represents 27million floats a second.
I would like to save a few seconds (3-5) of this data to a file, which I can then access later.
My current approach of writing the output every cycle is too slow (I/O is expensive) and I am not sure how to buffer the results of a few cycles correctly (I tried creating an array of arrays but then run into memory issues).
Copy data from mtl buffers:
//number of elements per frame approx 300,000
size_t len = elementCount
finalArrayX = new float [len];
finalArrayY = new float [len];
finalArrayZ = new float [len];
//MTLBuffers
finalArrayX = (float*) resultsBufferX.contents;
finalArrayY = (float*) resultsBufferY.contents;
finalArrayZ = (float*) resultsBufferZ.contents;
writeToFile(finalArrayX, finalArrayY, finalArrayZ)
writeToFile:
/*
* Get file handle to append to
*/
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documentTXTPath = [documentsDirectory stringByAppendingPathComponent:#"test.txt"];
if(![[NSFileManager defaultManager] fileExistsAtPath: documentTXTPath]) {
[[NSFileManager defaultManager] createFileAtPath: documentTXTPath contents:nil attributes:nil];
}
NSFileHandle *myHandle = [NSFileHandle fileHandleForWritingAtPath:documentTXTPath];
[myHandle seekToEndOfFile];
/*
* Create strings and write line by line
*/
for(int k = 0; k < elementCount; k ++){
NSString *x_i = [NSString stringWithFormat:#"%.2f", finalArrayX[k]];
NSString *y_i = [NSString stringWithFormat:#"%.2f", finalArrayY[k]];
NSString *z_i = [NSString stringWithFormat:#"%.2f", finalArrayZ[k]];
NSString *temp = [line stringByAppendingString: x_i];
temp = [temp stringByAppendingString: #" "];
NSString *tempTwo = [temp stringByAppendingString: y_i];
tempTwo = [tempTwo stringByAppendingString: #" "];
NSString *tempThree = [tempTwo stringByAppendingString: z_i];
NSString *totalLine = [tempThree stringByAppendingString: #"\n"];
[myHandle writeData:[totalLine dataUsingEncoding:NSUTF8StringEncoding]];
}
Whats the best way to go about this?

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?

Sqlite DB no such table exists

Ok so I have a database in my iPhone simulator documents. And I now know for sure it's in the applications sandbox. Something is funky in the code I have. So I first get the DB path:
-(NSString *)getsynDbPath
{
NSString* dataBAse = [[NSBundle mainBundle] pathForResource:#"ddd"ofType:#"sqlite"];
return dataBAse;
}
Then I test the path:
NSString *testData;
testData = [self getsynDbPath];
NSFileManager * fileManager = [NSFileManager defaultManager];
BOOL success = [fileManager fileExistsAtPath:testData];
if (success) {
NSLog(#"Oh no! There was a big problem!");
} else {
//Successfully opened
if(sqlite3_open([testData UTF8String], &db)==SQLITE_OK){
NSLog(#"Raise the roof!");
//Calling method to loop through columns
[self listOfCols];
}
}
I then go to a custom method where I loop through the columns inside the database:
-(NSArray *)listOfCols{
NSMutableArray *retval = [[[NSMutableArray alloc]init]autorelease];
NSString *query = #"SELECT KEY_ID FROM CON_DETAIL";
sqlite3_stmt *statement;
//Does not execute
if (sqlite3_prepare_v2(db, [query UTF8String], -1, &statement, nil)==SQLITE_OK) {
while (sqlite3_step(statement)==SQLITE_ROW) {
int key_id = sqlite3_column_int(statement, 0);
NSLog(#"Key ID: %d", key_id);
char *nameChars = (char *) sqlite3_column_text(statement, 1);
NSLog(#"chars %s", nameChars);
char *cityChars = (char *) sqlite3_column_text(statement, 2);
NSLog(#"chars %s", cityChars);
}
}
NSLog(#"%s Why '%s' (%1d)", __FUNCTION__, sqlite3_errmsg(db), sqlite3_errcode(db));
return retval;
}
So here's my question. After I successfully opened the database, why the heck am I getting a log error that says: no such table: CON_DETAIL ? Any help is appreciated.
I think you have to copy your db in your document directory and then try to fetch. Copy it with following functions.
-(void) dbconnect{
self.databaseName = #”yourdbname.sqlite”;
// Get the path to the documents directory and append the databaseName
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
self.databasePath = [documentsDir stringByAppendingPathComponent:self.databaseName];
// Execute the “checkAndCreateDatabase” function
[self checkAndCreateDatabase];
}
-(void) checkAndCreateDatabase{
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;
// Create a FileManager object, we will use this to check the status
// of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:databasePath];
// If the database already exists then return without doing anything
if(success) {
return;
}
// If not then proceed to copy the database from the application to the users filesystem
// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:self.databasePath error:nil];
[fileManager release];
}
NOTE: If you are not getting db in your app’s document directory do the following.
Go to : Target -> “Build Phases” -> “copy bundle Resources” Then add that particular file here.
After that call your "listOfCols" method.

Unable to unzip using ZipArchieve in 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?

Resources