cocoa how to get the ALREADY mounted unmountable disk - disk

NSWorkspaceDidMountNotification works well to get the information of just mounted disk.
But how can I get the information of already mounted disks before my app start?
command line: "diskutil list" and "diskutil info /" works but there should be a simple programmatically method there.
searched result of "DiskArbitration" or "VolumeToBSDNode example" don't work, IOkit difficult.
BTW, anyone recommend of using this?
[NSWorkspace getFileSystemInfoForPath:isRemovable:isWritable:isUnmountable:description:type:]

How about [NSFileManager mountedVolumeURLsIncludingResourceValuesForKeys:options:]?
Edit: Here's a snippet of code for how to use this to get removable drives and their volume names.
NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeNameKey, NSURLVolumeIsRemovableKey, nil];
NSArray *urls = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:keys options:0];
for (NSURL *url in urls) {
NSError *error;
NSNumber *isRemovable;
NSString *volumeName;
[url getResourceValue:&isRemovable forKey:NSURLVolumeIsRemovableKey error:&error];
if ([isRemovable boolValue]) {
[url getResourceValue:&volumeName forKey:NSURLVolumeNameKey error:&error];
NSLog(#"%#", volumeName);
}
}

Related

xcode cannot get sound file to play with AVAudioPlayer

I am new to iOS and trying to add sound to my app. I have followed several tutorials about adding a simple sound file to my project, but ALL with the same result. I get no errors, but no sound plays. Any ideas on what I am doing wrong? Any help would be appreciated!
- (IBAction)playSound:(id)sender {
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSLog(soundFilePath);
NSError *error;
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];
player.numberOfLoops = 1;
[player play];
}
**UPDATE***
So I never had any luck with the above code which is very discouraging, but I did end up getting it to work using the AudioToolbox Framework instead, using this:
SystemSoundID soundID;
NSString *soundFile = [[NSBundle mainBundle]
pathForResource:#"test" ofType:#"mp3"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)
[NSURL fileURLWithPath:soundFile], & soundID);
AudioServicesPlaySystemSound(soundID);
Can anyone explain to me the difference, why this one works and the other does not?? I am curious more than anything. Would love some clarification.
Finally figured it out. I needed to create a property for AVAudioPlayer in my header file in order to get it to work. Here is what I did:
// .h file
#interface ThirdViewController : UIViewController {
AVAudioPlayer *audioPlayer;
}
#property (nonatomic, retain) AVAudioPlayer *audioPlayer;
- (void) playSound //method in .m file
{
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"test"
ofType:#"mp3"]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
[audioPlayer play];
}
Simplify your code by doing the follow. Also drop your test.mp3 to the root of your project directory in xcode. Your mp3 placement and location is very important. Also ensure volume is up, and vibrate is off of your device, and it's unmuted.
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"test"
ofType:#"mp3"]];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:nil];
[audioPlayer play];
Make sure you install quartz.h, or a specific framework that supports audio players. Just double check.
Had the same problem a while back and the framework must be installed properly.

How do you read/write to/from and xcode plist?

I have a utility app with the flipsideview and I'm trying to use the flipsideview to enable the user to change settings that will effect the main view. I thought the easiest way to do this would be to write changes made on the flip side view to a plist but I am new to objective-c and can't seem to find any help in any forums. When I use the code I found online I keep getting a "Initializer element is not a compile-time constant". This is the code:
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"Settings.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"settings" ofType:#"plist"];
[fileManager copyItemAtPath:bundle toPath: path error:&error];
}
Also, I am new to objective-c (making the transition from html, css, etc.) and so a description of what's going on would be much appreciated. And please don't just paste a link to the apple developer tutorials. I've been through them and can't seem to grasp it being I learn much better by doing a practical example.
Thanks ahead of time.
Use NSUserDefaults. That's what you're supposed to use for saving user preferences.

A method for 'Save As...' in Core Data app

CD's been an enormous learning curve for me and there's still a bit for me to go, but any help on the following could enable me to lift the current weight on my shoulders!
I'm trying to write a method that implements a "Save As.." for the user in my CD app.
So far I've got:
[saveAsPanel beginSheetModalForWindow:window completionHandler:^(NSInteger userResult)
{
if (userResult == NSOKButton) {
NSPersistentStoreCoordinator *psc = [self persistentStoreCoordinator];
NSURL *oldURL = [self URLOfInternalStore]; //returns the current store's URL
NSURL *newURL = [saveAsPanel URL];
NSError *error = nil;
NSPersistentStore *oldStore = [psc persistentStoreForURL:oldURL];
NSPersistentStore *sqLiteStore = [psc migratePersistentStore:oldStore
toURL:newURL
options:nil
withType:NSXMLStoreType
error:&error];
}
}];
Unfortunately, I just get the error:
Object's persistent store is not reachable from this NSManagedObjectContext's coordinator.
Should I 'remove' and then 'addPersistentStore...' to update it to the new URL? The doc's seem to suggest that all will be handled with in the 'migrate' method.
Thanks in advance!
Edit:
Ok, well, I've come up with my own 'dirty' method. I can imagine that this isn't an approved way of doing things, but there's no error thrown up and the app works as expected at all times (not often I can say that, either!):
-(IBAction)saveAsAction:(id)sender
{
NSSavePanel *saveAsPanel = [NSSavePanel savePanel];
[saveAsPanel beginSheetModalForWindow:window completionHandler:^(NSInteger userResult)
{
if (userResult == NSOKButton) {
[self saveAction:#"saveAsCalling"];
NSURL *newURL = [saveAsPanel URL];
NSError *error = nil;
[[NSFileManager defaultManager] copyItemAtURL:[NSURL fileURLWithPath:internalStore] toURL:newURL error:&error];
//internalStore is a hard-wired NSString that holds the path to the bundle's database
}
}];
}
-(IBAction)loadAction:(id)sender
{
NSOpenPanel *loadPanel = [NSOpenPanel openPanel];
[loadPanel beginSheetModalForWindow:window completionHandler:^(NSInteger userResult)
{
if (userResult == NSOKButton) {
[self saveAction:#"loadCalling"];
NSURL *newURL = [loadPanel URL];
NSURL *oldURL = [NSURL fileURLWithPath:internalStore];
NSError *error = nil;
NSPersistentStoreCoordinator *psc = [SELF_MOC persistentStoreCoordinator];
[psc removePersistentStore:[[self persistentStoreCoordinator] persistentStoreForURL:oldURL] error:&error];
[psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:newURL options:nil error:&error];
[[NSFileManager defaultManager] removeItemAtURL:oldURL error:&error];
[[NSFileManager defaultManager] copyItemAtURL:newURL toURL:oldURL error:&error];
[psc removePersistentStore:[[self persistentStoreCoordinator] persistentStoreForURL:newURL] error:&error];
[psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:oldURL options:nil error:&error];
}
}];
}
The basic reasoning is this: to do a 'SaveAs...' I simply copy out the SQLLite store file in the mainBundle to wherever the user selects and rename it to what they want - as per TechZen's suggestion.
To do a 'Load' then I first removePersistentStore from the bundle's file, add the one that the user's just chosen. Delete the bundle store (which in theory isn't now being used) and then copy the user's choice back into the bundle. Finally, the two operations of remove and addPersistentStore are performed to point the app back to it's bundle's file which is now the user's choice.
Hope that makes sense. If anyone has any thoughts on just how unprofessional a methodology this is then please - be kind as I'm fairly new - let me know. I can't find anything that is more elegant.
I know Apple don't like you using removePersistentStore and addPersistentStore but, as I say no errors are reported (in my actual code I scattered NSLog lines throughout to report what error is holding).
You only use a SaveAs... in a document based app. If you use Core Data as your model, you need to use NSPersistentDocument to save your data. It provide the SaveAs... functionality you seek.
Straight Core Data is used for more database-like apps in which the entire app operates from one data set (more or less.)

Overwriting a file programmatically in Cocoa

This code copies the referenced file and places it in the Docs Directory. I'm trying to build a simple backup solution. The problem is this operation does not overwrite the existing file if the operation is repeated.
Two questions:
What's the best way to overwrite in code?
How difficult would it be to append the current date to each copied file? In this case there would be no overwrite operation. This would be much more useful for keeping incremental backups. If I decide to do it this way I understand I would need to create a new path in order to keep things organized.
Thanks.
Paul
NSString * name = #"testFile";
NSArray * files = [NSArray arrayWithObject: name];
NSWorkspace * ws = [NSWorkspace sharedWorkspace];
[ws performFileOperation: NSWorkspaceCopyOperation
source: #"~/Library/Application Support/testApp"
destination: #"~/Documents/"
files: files
tag: 0];
You could try using NSFileManager, example below (untested):
// Better way to get the Application Support Directory, similar method for Documents Directory
- (NSString *)applicationSupportDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory();
return [basePath stringByAppendingPathComponent:#"testApp"];
}
- (void) removeFile {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *applicationSupportDirectory = [self applicationSupportDirectory];
NSError *error = nil;
NSString* filePath = [applicationSupportDirectory stringByAppendingPathComponent: #"testFile"];
if ([fileManager fileExistsAtPath:filePath isDirectory:NULL]) {
[fileManager removeItemAtPath:filePath error:&error];
}
}
Edit:
Take a look at the NSFileManager Class Reference for other functions that might be useful (for your second question).

xcode EGODatabase update

I am trying to do a simple update to a sqlite database using EGODatabase and although the code runs the update does not occur?
NSArray *params = [NSArray arrayWithObjects:#"TEST", nil];
EGODatabase *database = [EGODatabase databaseWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"db_USBV1.sqlite3"]];
[database executeQuery:#"update users set locked = 0 where UID = ?" parameters:params ];
I saw on previous post that must copy the db to the users directory which i am doing as below;
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:#"db_USBV1.sqlite3"];
NSFileManager *fileManager = [[NSFileManager alloc] init];
if (![fileManager fileExistsAtPath:filePath]) {
NSError *error = nil;
[fileManager copyItemAtPath:[[NSBundle mainBundle] pathForResource:#"db_USBV1" ofType:#"sqlite3"] toPath:filePath error:&error];
}
[fileManager release];
But update is not occurring.
Any help much appreciated.
Thanks,
Mike
Thanks for the pointers. I was still attempting to work with the file in the bundle and not the file that was copied.

Resources