Log Accelerometer data to a file on Iphone IOS - ios

Hi I am trying to write to a file from the accelerometer data. Here is my code:
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
//xax.text = [NSString stringWithFormat:#"X:[%2.6f]",acceleration.x];
//yax.text = [NSString stringWithFormat:#"Y:[%2.6f]",acceleration.y];
//zax.text = [NSString stringWithFormat:#"Z:[%2.6f]",acceleration.z];
NSString *acc_x = [[NSString alloc] initWithFormat:#"X:[%2.6f]",acceleration.x];
NSString *acc_y = [[NSString alloc] initWithFormat:#"Y:[%2.6f]",acceleration.y];
NSString *acc_z = [[NSString alloc] initWithFormat:#"Z:[%2.6f]",acceleration.z];
xax.text = acc_x;
yax.text = acc_y;
zax.text = acc_z;
[acc_x release];
[acc_y release];
[acc_z release];
//wfm == 2 //Initialization of Appending to the file
if (wfm == 2)
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *txtFileName = [[NSString alloc] initWithFormat:#"tmp/%#.txt",txtName.text];
NSString *fileName = [NSHomeDirectory() stringByAppendingPathComponent:txtFileName];
//NSString *fileName = [NSHomeDirectory() stringByAppendingPathComponent:#"tmp/acc_w_trial2.txt"];
//Current Contents of the file
NSString *fileCurrent = [[NSString alloc] initWithContentsOfFile:fileName];
//Date and Time of each Accelerometer Data
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd 'at' HH:mm:ss:SSS"];
NSDate *date = [NSDate date];
NSString *formattedDateString = [dateFormatter stringFromDate:date];
NSString *msg = [[NSString alloc] initWithFormat:#"%#%# %#%#%# \n",fileCurrent,formattedDateString,xax.text,yax.text,zax.text];
//Convert NSstring to NSData
NSData* data=[msg dataUsingEncoding: [NSString defaultCStringEncoding]];
//bool fileCreationSuccess = [fileManager createFileAtPath:fileName contents:data attributes:nil];
[fileManager createFileAtPath:fileName contents:data attributes:nil];
[msg release];
[dateFormatter release];
[fileCurrent release];
[txtFileName release];
}
}
I get the warning level 1 and level 2. Is there a way I can release the NSFileManager memory to prevent this from locking up?

Your handler method to collect accelerometer data seems not very performant. You are allocating the resources (memory, file) everytime which can take a long time.
You should allocate the needed resources only once (i.e. use dispatch_once) and keep the file open. Use a NSFileHandle (method fileHandleForWritingAtPath) in order to append the data at the end of the file.
Furthermore NSHomeDirectory() is not where you're supposed to save user data, as iOS apps are sandboxed.
Either use NSTemporaryDirectory() or write in the Documents or Library Folder. The following is from Apple's sample code, usually in application delegate class:
- (NSString *)applicationDocumentsDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}

You can try using an Autorelease Pool.

Related

iOS11.2 NSFileManager API behivour is different than previous iOS versions

I am using below piece of code to calculate a checksum for files I added in a "temp" folder for app bundle. I am getting different checksum values in iOS11.2 compared to all lower iOS version. I was wondering what has changed among these versions? Is some changes in File system in iOS 11.2 is reason for the difference? Can somebody please throw light on the issue or faced similar issues? Below is the piece of code I used.
NSString* bundleRootDir;
bundleRootDir = [[NSBundle mainBundle] bundlePath];
NSLog(#"bundleRootDir %# ",bundleRootDir );
NSString *tmpDir = [bundleRootDir stringByAppendingPathComponent:#"temp"];
NSLog(#"tmpDir %# ",tmpDir);
NSFileManager *fileManager1=[[NSFileManager alloc] init];
NSDirectoryEnumerator *dirEnum = [fileManager1 enumeratorAtPath:tmpDir];
// NSFileManager *fileManager1 = [NSFileManager defaultManager];
//NSArray *filePathsArray1 = [fileManager1 subpathsOfDirectoryAtPath:tmpDir error:nil];
NSMutableData *allFilesData1 = [NSMutableData new];
uLong crc1 = crc32(0L, Z_NULL, 0);
NSInteger filecount1=0;
//for (NSString *file1 in filePathsArray1) {
NSString *file1;
while ((file1 = [dirEnum nextObject])) {
NSString *fullPathToFile1 = [tmpDir stringByAppendingPathComponent:file1];
BOOL isDirectory1;
if ([fileManager1 fileExistsAtPath:fullPathToFile1 isDirectory:&isDirectory1] && isDirectory1 ) {
// ignore directories...
continue;
}
else {
NSData *myData1 = [NSData dataWithContentsOfFile:fullPathToFile1];
[allFilesData1 appendData:myData1];
NSLog(#"Checksum files included %# , %d",fullPathToFile1,filecount1);
}
filecount1++;
}
NSLog(#"Checksum cal : length of data %lu",[allFilesData1 length]);
NSString *strData = [[NSString alloc]initWithData:allFilesData1 encoding:NSUTF8StringEncoding];
NSLog(#"All Data for checksum %#",strData);
crc1 = crc32(crc, [allFilesData1 bytes], [allFilesData1 length]);
NSLog(#"WL_INIT_PACKAGE - testWebResourcesChecksum crc32 output %lu",crc1);
NSString *checksum1 = [NSString stringWithFormat:#"%lu", crc1];
NSLog(#"WL_INIT_PACKAGE - testWebResourcesChecksum crc32 output %#",checksum1);

Modified (filtered) UIImage doesn't save in document directory

When I save an image taken with the camera without filtering it goes smoothly, but if i filter the image, when I save it, it doesn't work.
i'm using : [CIFilter filterWithName:#"CIColorControls"] and its options to filter.
Here the code used to save the image (wether or not its been filtered).
- (IBAction)save:(id)sender {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSData *binaryImageData = UIImageJPEGRepresentation(_photo, 0.3); // PNG without compression paramenter works too
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"yyyy-MM-dd-HH-mm"];
NSString *imageName = [formatter stringFromDate:[NSDate date]];
[binaryImageData writeToFile:[basePath stringByAppendingPathComponent:imageName] atomically:YES];
}
EDIT :
When I use the breakpoint, the NSData receives (counter) data and becomes nil when I proceed to NSDateFormatter

How to save unique image name in document directory

In my ios app i am stuck on a task. I need to take pic from camera and save it on document directory.Problem is that i want save unique name of image.I was try to add current time with a name. but there are length problem to save image.Please suggest me how can i do that task.
Thanks
Given a proposed name like NString *name = #"Lake":
NSString *myUniqueName = [NSString stringWithFormat:#"%#-%u", name, (NSUInteger)([[NSDate date] timeIntervalSince1970]*10.0)];
EDIT: updated so that the only chance of a duplicate is the same original name, submitted within 100 ms of the first (virtually impossible in my opinion, if this is a concern use 100 instead of 10)
-(NSString*)getFilePathToSaveUnUpdatedImage
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *directory = [paths objectAtIndex:0];
for (int i = 0 ; TRUE ; i++)
{
if(![[NSFileManager defaultManager]fileExistsAtPath:[NSString stringWithFormat:#"%#/UnUpdatedItems/Image%d.png", directory , i]])
return [NSString stringWithFormat:#"%#/UnUpdatedItems/Image%d.png", directory , i];
}
}
Try like this just formate the date and save the image
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *now = [NSDate date];
NSString *theDate = [dateFormat stringFromDate:now];
[data writeToFile:[NSString stringWithFormat:#"%#.png",theDate] atomically:YES];
use this line of code to give name.
[NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterShortStyle]]
This works for me for same problem.
-(NSString*)getImagePathName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *directory = [paths objectAtIndex:0];
for (int i = 0 ; TRUE ; i++)
{
if(![[NSFileManager defaultManager]fileExistsAtPath:[NSString stringWithFormat:#"%#/Image%d.png", directory , i]])
return [NSString stringWithFormat:#"%#/Image%d.png", directory , i];
}
}

iOS release not working as expected

I am using this code to get book names from a config.plist file. However my memory management is problematic. The '[dict release]' breaks the app completely and it exits.
The code works when the '[dict release]' is removed but it causes memory leaks as far as I can tell.
bnames is a global NSMutableArray
What am I doing wrong?
- (NSString *)loadBookname: (NSInteger) bookToLoad {
bookToLoad = [self bookOrder:bookToLoad];
//---get the path to the property list file---
plistFileNameConf = [[self documentsPath] stringByAppendingPathComponent:#"Config.plist"];
//---if the property list file can be found---
if ([[NSFileManager defaultManager] fileExistsAtPath:plistFileNameConf]) {
//---load the content of the property list file into a NSDictionary object---
dict = [[NSDictionary alloc] initWithContentsOfFile:plistFileNameConf];
bnames = [dict valueForKey:#"BookNames"];
[dict release];
}
else {
//---load the property list from the Resources folder---
NSString *pListPath = [[NSBundle mainBundle] pathForResource:#"Config" ofType:#"plist"];
dict = [[NSDictionary alloc] initWithContentsOfFile:pListPath];
bnames = [dict valueForKey:#"BookNames"];
[dict release];
}
plistFileNameConf = nil;
NSString *bookNameTemp;
bookNameTemp = [bnames objectAtIndex:bookToLoad - 1];
NSLog(#"bookName: %#", bookNameTemp);
return bookNameTemp;
}
You need to allocate your array properly:
bnames = [[NSArray alloc] initWithArray:[dict valueForKey:#"BookNames"]];
Double check that your dict returns the right data type.
There does not appear to be anything wrong with the way you allocate NSDictionary (although you could also use the [NSDictionary dictionaryWithContentsOfFile:] and save yourself having to worry about the release.
Either way I would suggest the issue is not with the [release] but probably the line BEFORE release:
bnames = [dict valueForKey:#"BookNames"];
a) Where is that allocated. I don't see an allocation or declaration of it anywhere?
b) What type of value do you expect back?
Put a break point on it and make sure your getting what you expect or anything.
If dict is not already a strong property, make it one. Then, use self.dict when assigning to it (and keep the release).
I've found what appears to be a better solution to the issue. This lets iOS manage the memory.
//---finds the path to the application's Documents directory---
- (NSString *) documentsPath {
NSLog(#"Start documentsPath");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
// NSLog(#"Found documentsPath 40");
NSLog(#"End documentsPath");
return documentsDir;
}
- (NSString *) configPath {
NSLog(#"Start configPath");
NSString *plistFileNameConf = [[self documentsPath] stringByAppendingPathComponent:#"Config.plist"];
if (![[NSFileManager defaultManager] fileExistsAtPath:plistFileNameConf]) {
plistFileNameConf = [[NSBundle mainBundle] pathForResource:#"Config" ofType:#"plist"];
}
NSLog(#"plistFile: %#",plistFileNameConf);
NSLog(#"End configPath");
return plistFileNameConf;
}
The following calls the above code as necessary:
NSString *Choice;
NSArray *properties;
NSString *errorDesc = nil;
NSPropertyListFormat format;
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:[self configPath]];
NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
if (!temp) {
NSLog(#"Error reading plist: %#, format: %d", errorDesc, format);
}
Choice = [temp objectForKey:#"Choice"];
properties = [temp objectForKey:Choice];

Storing and reading files from Documents directory iOS 5

In my game, when a level is completed the app stores a "1" in a file in the Documents directory of the app. When the game then loads, a player can only play a level if the previous level has been completed. When I test the game via Xcode and on a device the app works properly and a level cannot be played until the previous level has been completed. However, when the app was approved and released on the App Store, the app behaves as if each level has been completed (no locked levels). I can't figure this one out and would appreciate someone's help! The devices I'm testing on are all iOs 5.0 or higher.
Below is the code that saves the completed level in the Documents directory:
NSMutableData* data = [[NSMutableData alloc] init];
NSKeyedArchiver* coder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
NSString *levelString = [NSString stringWithFormat:#"Level%d",level];
[coder encodeInteger:1 forKey:levelString];
[coder finishEncoding];
NSString *levelString2 = [NSString stringWithFormat:#"Level%d.save",level];
///
NSFileManager *filemgr;
NSString *dataFile;
NSString *docsDir;
NSArray *dirPaths;
filemgr = [NSFileManager defaultManager];
// Identify the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Build the path to the data file
dataFile = [docsDir stringByAppendingPathComponent:levelString2];
// Check if the file already exists
if ([filemgr fileExistsAtPath: dataFile])
{
[[NSFileManager defaultManager] removeItemAtPath:dataFile error:nil];
}
[data writeToFile:dataFile atomically:YES];
[coder release];
[data release];
}
#catch (NSException* ex)
{
CCLOG(#"level save failed: %#", ex);
}
Below is the code that reads the Document directory to see if the level has been completed:
if ([self loadCompletedLevels:6] == 1) { //// level gets unlocked **** }
-(int) loadCompletedLevels:(int)theLevel; {
int isLevelCompleted; //1 = completed
NSString* kSaveFile = [NSString stringWithFormat:#"Level%d.save",theLevel];
NSString *levelString = [NSString stringWithFormat:#"Level%d",theLevel];
#try
{
NSFileManager *filemgr;
NSString *dataFile;
NSString *docsDir;
NSArray *dirPaths;
filemgr = [NSFileManager defaultManager];
// Identify the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
// Build the path to the data file
dataFile = [docsDir stringByAppendingPathComponent:kSaveFile];
if ([[NSFileManager defaultManager] fileExistsAtPath:dataFile])
{
NSData* data = [[NSData alloc] initWithContentsOfFile:dataFile];
if (data && [data length] > 0)
{
NSKeyedUnarchiver* decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
isLevelCompleted = [decoder decodeIntForKey:levelString];
[decoder release];
}
[data release];
}
if (isLevelCompleted == 1) {
levelCompleted = YES;
}
}
#catch (NSException* ex)
{
levelCompleted = NO;
}
return isLevelCompleted; }
You should probably use a different approach for storing your data, but the real problem is that you are not initializing the return value, isLevelCompleted. It is on the stack, and does not have a default value. It starts out with whatever happens to be at that stack location.
So, if you don't set it, it will have an arbitrary value.
Also, you should probably use BOOL for a boolean value, but if you make this:
int isLevelCompleted = 0; //1 = completed
you will initialize it to "false" so it must be explicitly changed to "true" by your code.

Resources