Exc_Bad_Access Exception on creating database in Iphone - objective-c

i receive this exception after calling the following method. And it only comes when app load for the first time. When i again open the app it works fine. Can anyone help?
-(void) createAndCheckDatabase
{
BOOL success;
self.databaseName = #"database.db";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentPaths objectAtIndex:0];
self.databasePath = [[documentDir stringByAppendingPathComponent:self.databaseName]retain];
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:self.databasePath];
if(success) return;
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseName];
NSError *err;
[fileManager copyItemAtPath:databasePathFromApp toPath:self.databasePath error:nil];
if (err) {
// DebugLog(#"%#", [err description]);
}
}

if (err) ... will crash because err is not initialized! and you dont use it in fileManager copyItemAtPath:

EXEC_BAD_ACCESS almost always means either a bug dealing with pointers or C-arrays, or an object was over-releaseed.
The good news is that you should have a stack-trace in the Debugger (if running in Xcode), or a crash log, that shows exactly what went wrong. (How to gather and read crash logs).
"Profiling" your code with the Zombies instrument is the best way to get more information about over-releases.
If you can post a symbolicated stacktrace, we can try and give you a better diagnosis.

Related

How to replace a file or folder by using NSFileManager?

For using "copyItemAtPath" method of NSFileManager, if exists the same file or folder, occur error.
Is there the replace feature in NSFileManager?
(If exists the same file, delete and copy If not, just copy.)
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self generateTableContents];
}
- (void)generateTableContents {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *appsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [appsDirectory objectAtIndex:0];
[fileManager changeCurrentDirectoryPath:documentPath];
[fileManager createDirectoryAtPath:#"user_List1" withIntermediateDirectories:YES attributes:nil error:nil];
NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
NSError *error; // to hold the error details if things go wrong
NSString *sourcePath = [[NSBundle mainBundle] pathForResource:#"IMG_0523" ofType:#"JPG"];
if ([fileManager copyItemAtPath:sourcePath toPath: #"./user_List1/newIMG_0523.JPG" error:&error]) {
NSLog(#"Copy complete!");
} else {
NSLog(#"Copy Failed : %#", error);
}
if ([fileManager copyItemAtPath:#"./user_List1" toPath: #"./user_List2" error:&error]) {
NSLog(#"Copy complete!");
} else {
NSLog(#"Copy Failed : %#", error);
}
}
Excuted result is complete.
/Users/nice7285/Library/Caches/appCode10/DerivedData/tempPrg-dd15264d/Build/Products/Debug-iphonesimulator/tempPrg.app/tempPrg
Simulator session started with process 1184
2012-10-04 06:28:32.653 tempPrg[1184:11303] Copy complete!
2012-10-04 06:28:32.672 tempPrg[1184:11303] Copy complete!
Process finished with exit code 143
But When already exist folder.
Result is fail.
2012-10-04 06:48:31.488 tempPrg[1243:11303] Copy Failed
2012-10-04 06:48:31.497 tempPrg[1243:11303] Copy Failed
You need to do an atomic save, for example:
NSData *myData = ...; //fetched from somewhere
[myData writeToFile:targetPath atomically:YES];
But since you're using copyItemAtPath, I have no idea if atomically works with it so I would just go for the quick dirty hack:
if ([fileManager fileExistsAtPath:txtPath] == YES) {
[fileManager removeItemAtPath:txtPath error:&error]
}
NSString *resourcePath = [[NSBundle mainBundle] pathForResource:#"txtFile" ofType:#"txt"];
[fileManager copyItemAtPath:resourcePath toPath:txtPath error:&error];
Sources: IOS: copy a file in documents folder
Starting with iOS 4 (and macOS 10.7) there is an explicit method for replacing one item with another. It even keeps the properties of the original file (optional)
- (BOOL)replaceItemAtURL:(NSURL *)originalItemURL withItemAtURL:(NSURL *)newItemURL backupItemName:(NSString *)backupItemName options:(NSFileManagerItemReplacementOptions)options resultingItemURL:(NSURL * _Nullable *)resultingURL error:(NSError * _Nullable *)error;
Replaces the contents of the item at the specified URL in a manner
that ensures no data loss occurs.
replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:

unable to play audio file from document?

when ever i try to play audio this error appears
2010-08-27 09:13:40.466 VoiceRecorder[3127:207] Failed with reason: The operation couldn’t be completed. (OSStatus error -43.)
what does it mean
I am physically storing file in Iphone Document folder and copying its name in my database
so when ever I play it from database its correctly get file path
and file name from document and database concat perfectly but unable to play
2010-08-30 12:22:00.592 VoiceRecorder[8140:207] /Users/Username/Library/Application Support/iPhone Simulator/4.0.1/Applications/4BF0B5C7-59C9-462F-94EC-
662EBCE8505E/Documents/30Aug10_12_21_58.aif
2010-08-30 12:22:00.593 VoiceRecorder[8140:207] 30Aug10_12_21_58.aif
2010-08-30 12:22:00.618 VoiceRecorder[8140:207] Failed with reason: The operation couldn’t be completed. (OSStatus error -43.)
need an urgent reply
here is my code
-(IBAction)playevent{
VoiceRecorderAppDelegate *appDelegate=(VoiceRecorderAppDelegate*)[[UIApplication sharedApplication]delegate];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *fullpath = [documentsDir stringByAppendingPathComponent:appDelegate.filenamefrompath];
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check if the database has already been created in the users filesystem
BOOL success = [fileManager fileExistsAtPath:fullpath];
// If the database already exists then return without doing anything
if(success) { NSLog(#"Yes exists"); }else{ NSLog(#"no"); }
//return [documentsDir stringByAppendingPathComponent:appDelegate.filenamefrompath];
NSError* err;
NSLog(#"%#",fullpath);
player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:fullpath] error:&err];
//NSString *filePath = [[NSBundle mainBundle] pathForResource:appDelegate.filenamefrompath ofType:#"aif"];
// NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];
// player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
NSLog(#"%#",appDelegate.filenamefrompath);
player.delegate = self;
if( err ){
//bail!
NSLog(#"Failed with reason: %#", [err localizedDescription]);
}
[player play];
}
Please check my code for error
The code looks OK on the surface
Strangely tracking down the errors definitions is not entirely easy
They are in MacErrors.h
fnfErr = -43, /*File not found*/
Can you verify that the URL you are feeding the player in [NSURL fileURLWithPath:fullpath] is valid.
And more to the point is the file you are trying to play there in the Sim folder?
and off topic if this is supposed to be an IBAction then the signature should be
-(IBAction)playevent:(id)sender

iPhone/Objective C: Can't delete a file

In my application, I let the user record a sound clip and later, if the user chooses, I want him to be able to delete it.
This is the code I use:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSLog(#"File exists: %d", [fileManager fileExistsAtPath:path]);
NSLog(#"Is deletable file at path: %d", [fileManager isDeletableFileAtPath:path]);
[fileManager removeItemAtPath:path error:&error];
if (error != nil)
{
NSLog(#"Error: %#", error);
NSLog(#"Path to file: %#", path);
}
The problem is that fileExistsAtPath and isDeletableFileAtPath return null and the removeItemAtPath doesn't work, and throws this error,
Error: Error Domain=NSCocoaErrorDomain Code=4 UserInfo=0x391b7f0 "Operation could not be completed. (Cocoa error 4.)"
The path has this form:
/Users/andrei/Library/Application%20Support/iPhone%20Simulator/User/Applications/5472B318-FA57-4F8D-AD91-7E06E9609215/Documents/1280913694.caf
There is a file there called 1280913694.caf, but it doesn't pick it up. Does it have something to do with the way in which the path should be represented?
The path works when playing the audio file with AVAudioPlayer.
I've also changed the %# to %d for fileExistsAtPath and isDeletableFileAtPath and the answer is 0, which I suppose means FALSE.
The name of the file is stored in a database, and the path to the file is retrieved with this method:
-(NSString *)returnFullPathToDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return documentsDirectory;
}
After I get this value, I use it in the following code
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
Your check for (error != nil) is incorrect. You should set a BOOL to the return value of the method and use that to handle error conditions as it is possible for the method to complete successfully and for error to be non nil afterwards. So, the file might actually have been deleted but you are getting an incorrect error back.
You should also not try to delete the file if it doesn't exist.
Also, I usually just log the error's localizedDescription as that is easier to read
This code works in my project (path was defined elsewhere):
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
BOOL fileExists = [fileManager fileExistsAtPath:path];
NSLog(#"Path to file: %#", path);
NSLog(#"File exists: %d", fileExists);
NSLog(#"Is deletable file at path: %d", [fileManager isDeletableFileAtPath:path]);
if (fileExists)
{
BOOL success = [fileManager removeItemAtPath:path error:&error];
if (!success) NSLog(#"Error: %#", [error localizedDescription]);
}
related answer:
NSError: Does using nil to detect Error actually turn off error reporting?
The url encoded file path looks suspicious to me. I read somewhere that iPhone file paths should be represented as URL these days, but I don't think spaces need to be url encoded.
Try removing the %20's from your path and trying again?
try to change
NSFileManager *fileManager = [NSFileManager defaultManager];
to:
NSFileManager *fileManager = [NSFileManager new];

NSString fails, app crashes trying to NSLog the NSError

What it says on the tin. All I want to do is save an NSString to a .txt file in my Documents directory so it can be accessed by the user. This is called in applicationWillTerminate:
NSError* err;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// the path to write file
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"TheFile.txt"];
BOOL success = [[textView text] writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&err];
if (!success) {
NSLog(#"Error: %# %#", err, [err userInfo]);
}
In my case, success comes back as NO, and my app crashes (EXC_BAD_ACCESS) on the NSLog line. Any ideas?
If textView (or [textView text]) is nil, success will be NO but err will be uninitialized. That's the only possible way to crash here.
Try setting NSError* err = nil;
I believe you should be checking the error object, not the success boolean value. After all - that's why you're passing it's address for the write operation.
if (error) {
NSLog(#"Error: %#", err);
}
Also you may want to check that [textView text] does not return nil and if textView isn't nil itself.

SQLite Step Failed: attempt to write a readonly database , using wrapper

I keep getting an error "SQLite Step Failed: attempt to write a readonly database" when using this code to copy a database:
-(void)createEditableCopyOfDatabaseIfNeeded
{
// Testing 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:#"Money.sqlite"];
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:#"Money.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath
toPath:writableDBPath
error:&error];
if(!success)
{
NSAssert1(0,#"Failed to create writable database file with Message : '%#'.",
[error localizedDescription]);
}
}
I am using the above code in AppDelegate
and this:
NSString *writableDBPath =
[[NSBundle mainBundle] pathForResource:#"Money"
ofType:#"sqlite"];
In ViewController.m
I am using http://th30z.netsons.org/2008/11/objective-c-sqlite-wrapper/ what am I doing wrong?
This is happening again and again... It was working fine before but again the problem started.
The problem is that you cannot write anything to your bundle. To be able to change your database you need to copy it to application's documents or caches folder and work with that copy.