While profiling the app for Zombies, I get the error below:
Stack:
Code:
When the app is launched, we access several NSUserDefaults properties using similar code as below. Sometimes the app crashes on different methods that are trying to access the defaults.
+(NSString*)getSettingsFileName{
prefs = [NSUserDefaults standardUserDefaults];
return [prefs objectForKey:#"SettingsFileName"]; // EXC_BAD_ACCES (code=1, address=0x8178b6ed)
}
I tried synching NSUserDefaults before accessing it, but I get the same behavior.
Any tips on how to resolve this would be greatly appreciated!
EDIT
+(void)readSettingsDataAndUpdateIncludeDomain:(BOOL)updateDomain MBMHost:(BOOL)updateMBMHost
{
//Read from Documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *settingsFileName = [documentsDirectory stringByAppendingPathComponent:SETTINGS_FILE];
NSDictionary *settingsDic = nil;
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL fileExists = [fileManager fileExistsAtPath:settingsFileName];
if(fileExists) {
settingsDic = [NSDictionary dictionaryWithContentsOfFile:settingsFileName];
} else {
NSError *error = nil;
NSString *settingsBundleFilePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:SETTINGS_FILE];
BOOL success = [fileManager copyItemAtPath:settingsBundleFilePath toPath:settingsFileName error:&error];
if(success)
settingsDic = [NSDictionary dictionaryWithContentsOfFile:settingsFileName];
}
prefs = [NSUserDefaults standardUserDefaults];
if(!fileExists)
{
//subscription
[prefs setBool:YES forKey:#"Resubscribe"];
}
[prefs setObject:[settingsDic objectForKey:#"ADDRNAME"] forKey:#"ADDRNAME"];
if( updateDomain )
{
[prefs setObject:[settingsDic objectForKey:#"Domain"] forKey:#"Domain"];
}
[prefs setBool:[[settingsDic objectForKey:#"Https"] boolValue] forKey:#"Https"];
if( updateMBMHost )
{
[prefs setObject:[settingsDic objectForKey:#"Host"] forKey:#"Host"];
}
[prefs setObject:[settingsDic objectForKey:#"ServerNode"] forKey:#"ServerNode"];
[prefs removeObjectForKey:#"ULVersion"];
[prefs setObject:[settingsDic objectForKey:#"ULVersion"] forKey:#"ULVersion"];
forKey:#"ULDownloadOnly"];
[prefs setObject:[settingsDic objectForKey:#"AgentName"] forKey:#"AgentName"];
if ([[Settings getSettingsFileName] length] < 1) //This is the Line where it usually crashes"
[prefs setObject:[settingsDic objectForKey:#"SettingsFileName"] forKey:#"SettingsFileName"];
[prefs setObject:[settingsDic objectForKey:#"ScannerType"] forKey:#"ScannerType"];
NSString *supportEmailAddress = [settingsDic objectForKey:#"SupportEmailAddress"];
if( supportEmailAddress == nil )
{
supportEmailAddress = SUPPORT_EMAIL_ADDRESS;
}
[prefs setObject:supportEmailAddress forKey:#"SupportEmailAddress"];
//Don't set SyncCalContactsMode from plist since this will overide the user's selection
if([[settingsDic objectForKey:#"Instance"] length] > 1)
[prefs setObject:[settingsDic objectForKey:#"Instance"] forKey:#"Instance"];
else if ([[Settings getInstance] length] < 1)
[prefs setObject:#"Company" forKey:#"Instance"];
NSString *info = [NSString stringWithFormat:#"ULVersion = %#, ULDownloadOnly = %# ", ([Settings getULVersion]==nil)?#"Version1":[Settings getULVersion], [Settings getULDownloadOnly]?#"YES":#"NO"];
[DebugLog writeDebugData:info];
}
Related
I have a folder called 'thepdfpowerpoints'. I simply want to at launch, create a PLIST file that will create an entry for each PDF in the folder showing the path to that particular file. I have the following set up, and it puts the right number of entries, but each entry is the same path listed 399 times.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"mastersonglist.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path]) {
path = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat:#"mastersonglist.plist"] ];
}
NSMutableDictionary *data;
if ([fileManager fileExistsAtPath: path]) {
data = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
}
else {
// If the file doesn’t exist, create an empty dictionary
data = [[NSMutableDictionary alloc] init];
}
NSBundle *bundle = [NSBundle mainBundle];
self.files = [bundle pathsForResourcesOfType:#"pdf" inDirectory:#"thepdfpowerpoints"];
NSMutableArray *names = [NSMutableArray arrayWithCapacity:[self.files count]];
for (NSString *pathoffile in self.files) {
pathoffile = [self.files objectAtIndex:thepath.row];
[names addObject:pathoffile];
}
for (NSString *test in names) {
test = [self.files objectAtIndex:thepath.row];
[data setObject:names forKey:#"thename"];
[data writeToFile:path atomically:YES];
}
I have a working code, but now find the need to import & save two different Sqlite files via email "Open in" option, I tried using UIAlertView to create to different save file paths but it only seems to work with one way
- (void)handleOpenURL:(NSURL *)urlx {
NSData *dbimport = [[NSData alloc] initWithContentsOfURL:urlx];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:dbimport forKey:#"import"];
[defaults synchronize];
NSLog(#"import saved");
databaseName = #"svrStoreData2.sql";
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSError *writeError = nil;
NSString *filePathx = [documentsPath stringByAppendingPathComponent:databaseName]; [dbimport writeToFile:filePathx atomically:YES];
if (writeError)
{
NSLog(#"Error writing file: %#", writeError);
}
}
Both file have specific file names so was wonder if I could use "if equal to string" & use an if statement after I have synchronised NSUserDefaults to give two file path save options
Thanks for any help in advance
This was my UIALertView try
UIAlertView *alertdata = [[UIAlertView alloc]
initWithTitle:#"What type of data do you want to import?"
message:#"Choose data type"
delegate:self
cancelButtonTitle:#"Import RM Name Data"
otherButtonTitles:#"Import Store Visit Data", nil];
NSInteger *buttonIndex = NULL;
NSLog(#"Button Index =%ld",(long)buttonIndex);
if (buttonIndex == 0)
{
}
else if (buttonIndex == 1)
{
databaseExportName = #"export.sql";
NSArray *pathssqlite3 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathssqliteDir2 = [pathssqlite3 objectAtIndex:0];
filePathsqlite3 = [pathssqliteDir2 stringByAppendingPathComponent:databaseExportName];
NSData *dbimport = [[NSData alloc] initWithContentsOfURL:urlx];
NSMutableData *dbimport = [[NSMutableData alloc] initWithContentsOfURL:urlx];
NSError *writeError = nil;
[dbimport writeToFile:filePathsqlite3 atomically:YES];
if (writeError)
{
NSLog(#"Error writing file: %#", writeError);
} } [alertdata show];
Still trying to resolve, was hoping this would work, but still cannot crack it
`- (void)handleOpenURL:(NSURL *)urlx {
NSData *dbimport = [[NSData alloc] initWithContentsOfURL:urlx];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:dbimport forKey:#"import"];
[defaults synchronize];
NSLog(#"import saved");
if([[urlx absoluteString] isEqualToString:#"svrStoreData2.sql"])
{
NSLog(#"If statement called");
//
databaseName = #"svrStoreData2.sql";
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSError *writeError = nil;
NSString *filePathx = [documentsPath stringByAppendingPathComponent:databaseName];
[dbimport writeToFile:filePathx atomically:YES];
if (writeError)
{
NSLog(#"Error writing file: %#", writeError);
}
//
else {
databaseExportName = #"export.sql";
NSString *documentsPathy = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSError *writeError = nil;
NSString *filePathy = [documentsPathy stringByAppendingPathComponent:databaseExportName];
[dbimport writeToFile:filePathy atomically:YES];
if (writeError)
{
NSLog(#"Error writing file: %#", writeError);
}
NSLog(#"If statement Not called");
}
}
}
`
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex(NSInteger)buttonIndex {
if ([alertView tag] == 14)
{
if (buttonIndex == 1)
{
[self reviewSave];
}
}
if ([alertView tag] == 11) {
if (buttonIndex == 1)
{
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
for (NSString *key in [defaultsDictionary allKeys]) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];}
}
}
Solved the problem, I had another UIAlert, so by adding Tags sorted it
Right now my App is placing the database in the ~/Library folder but I would like it to place it in a more organized manner ~/Library/App Name but I can not figure out how to do that with this block of code.
(NSPersistentStoreCoordinator *) persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSFileManager *fileManager;
NSString *applicationSupportFolder = nil;
NSString *dataFilePath;
NSURL *url;
NSError *error;
fileManager = [NSFileManager defaultManager];
applicationSupportFolder = [self applicationSupportFolder];
if ( ![fileManager fileExistsAtPath:applicationSupportFolder isDirectory:NULL] ) {
[fileManager createDirectoryAtPath:applicationSupportFolder attributes:nil];
}
dataFilePath = [applicationSupportFolder stringByAppendingPathComponent: #"sample.dat"];
if( NO == [[ NSFileManager defaultManager ] fileExistsAtPath: dataFilePath ] )
{
[[ NSFileManager defaultManager ] copyPath: [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: #"sample.dat"]
toPath: dataFilePath handler: NULL ];
}
url = [NSURL fileURLWithPath:dataFilePath];
if( url )
{
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error]){
[[NSApplication sharedApplication] presentError:error];
}
}
return persistentStoreCoordinator;
}
This code works it just places the database in a pretty terrible location IMO. I am new to Obj-C and just inherited this code set from a another developer.
UPDATE:
Adding the final working code below.
(NSPersistentStoreCoordinator *) persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSFileManager *fileManager;
NSString *applicationSupportFolder = nil;
NSString *dataFilePath;
NSURL *url;
NSError *error;
fileManager = [NSFileManager defaultManager];
applicationSupportFolder = [self applicationSupportFolder];
NSString *aappSupportFolder = [applicationSupportFolder stringByAppendingPathComponent: #"APP"];
if ( ![fileManager fileExistsAtPath:aappSupportFolder isDirectory:NULL] ) {
[fileManager createDirectoryAtPath:aappSupportFolder attributes:nil];
}
dataFilePath = [aappSupportFolder stringByAppendingPathComponent: #"sample.dat"];
if( NO == [[ NSFileManager defaultManager ] fileExistsAtPath: dataFilePath ] )
{
[[ NSFileManager defaultManager ] copyPath: [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: #"sample.dat"]
toPath: dataFilePath handler: NULL ];
}
url = [NSURL fileURLWithPath:dataFilePath];
if( url )
{
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error]){
[[NSApplication sharedApplication] presentError:error];
}
}
return persistentStoreCoordinator;
}
Well it is very simple just you have to create folder name APP inside library folder of your machine and then you have to move your app inside the same path . Please try below:-
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *pathString= [paths objectAtIndex:0];
NSError *err=nil;
//below is your application previous path which we will move to new path
NSString *dataFilePath = [pathString stringByAppendingPathComponent: #"sample.dat"];
NSString *applicationSupportFolder = [pathString stringByAppendingPathComponent: #"App"];
//Here we have created directory folder as App inside Library below
if ( ![fileManager fileExistsAtPath:applicationSupportFolder isDirectory:NULL] ) {
[fileManager createDirectoryAtPath:applicationSupportFolder attributes:nil];
}
if ([fm moveItemAtPath:dataFilePath toPath:applicationSupportFolder error:&err])
{
NSLog(#"success");
}
else
{
NSLog(#"%#",[err localizedDescription]);
}
I have created a Cocoa document based picture drawing application. I want that the default location of a new document created using my app in Save/Save As dialog should be in ~/Pictures/MyAppName/ directory.
How can I achieve this?
I tried more or less what Ole suggested below, but it doesn't work. Here is my implementation of prepareSavePanel. What am I doing wrong?
- (BOOL)prepareSavePanel:(NSSavePanel *)savePanel
{
if ([self fileURL] == nil) {
//new, not saved yet
[savePanel setExtensionHidden:NO];
//set default save location
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSPicturesDirectory, NSUserDomainMask, YES);
if ([paths count] > 0) {
NSString *userPicturesPath = [paths objectAtIndex:0];
NSString *myDirPath = [userPicturesPath stringByAppendingPathComponent:#"MyAppName"];
//create directory is it doesn't already exist
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isDir;
BOOL useMyAppDir = NO;
if([fileManager fileExistsAtPath:myDirPath isDirectory:&isDir]){
if (isDir) {
useMyAppDir = YES;
}
} else {
//create the directory
if([fileManager createDirectoryAtPath:myDirPath withIntermediateDirectories:YES attributes:nil error:nil]){
useMyAppDir = YES;
}
}
if (useMyAppDir) {
NSURL * myAppDirectoryURL = [NSURL URLWithString:myDirPath];
[savePanel setDirectoryURL:myAppDirectoryURL];
}
}
} else {
[savePanel setExtensionHidden:[self fileNameExtensionWasHiddenInLastRunSavePanel]];
}
return YES;
}
In your NSDocument subclass, override -prepareSavePanel:
- (BOOL) prepareSavePanel:(NSSavePanel *)savePanel
{
// Set default folder if no default preference is present
NSDictionary *userDefaults = [[NSUserDefaults standardUserDefaults] persistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
if ([userDefaults objectForKey:#"NSNavLastRootDirectory"] == nil) {
NSArray *picturesFolderURLs = [[NSFileManager defaultManager] URLsForDirectory:NSPicturesDirectory inDomains:NSUserDomainMask];
if ([picturesFolderURLs count] > 0) {
NSURL *picturesFolderURL = [[picturesFolderURLs objectAtIndex:0] URLByAppendingPathComponent:#"MyAppName"];
[savePanel setDirectoryURL:picturesFolderURL];
}
}
return YES;
}
I'm trying to write Boolean to a plist file. My code is:
NSString *filePath = [self dataFilePath];
if (filePath)
{
if (check)
{
NSLog(#"Clear");
[item setObject:[NSNumber numberWithBool:NO] forKey:#"check"];
[item writeToFile:filePath atomically: YES];
}else{
NSLog(#"Green");
[item setObject:[NSNumber numberWithBool:YES] forKey:#"check"];
[item writeToFile:filePath atomically: YES];
}
NSLog([[NSString alloc] initWithContentsOfFile:filePath]);
}else{
NSLog(#"write file was not found");
}
My filePath is:
- (NSString *)dataFilePath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"CheckMark.plist"];
}
I load my array with:
- (void)viewDidLoad
{
NSString *filePath = [self dataFilePath];
NSLog(#"%#", filePath);
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSString *myPathInfo = [[NSBundle mainBundle] pathForResource:#"CheckMark" ofType:#"plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager copyItemAtPath:myPathInfo toPath:filePath error:NULL];
}
// load our data from a plist file inside our app bundle
self.dataArray = [NSMutableArray arrayWithContentsOfFile:filePath];
NSLog([[NSString alloc] initWithContentsOfFile:filePath]);
NSLog(#"%#", filePath);
NSLog(#"read dataArray");
Every thing works fine, except when I look at the plist file, nothing changes.
I'm writing the plist file to my Documents directory.
Thanks for any help you can give me.
Remember that you need to be using an NSMutableDictionary to be able to set values.