Checking if file exists when file on an external device - objective-c

A playlist file .m3u contains entries available on an external device (a USB key in this case) such as:
/Volumes/KINGSTON/folder/mytitle.mp3
I'd like to check if the file exists:
NSURL *url = [NSURL URLWithString:#"/Volumes/KINGSTON/folder/mytitle.mp3"];
NSFileManager *manager = [NSFileManager defaultManager];
NSLog(#"%d",[manager fileExistsAtPath:[url absoluteString]]); //returns 0. I expect 1
I also tried:
NSURL *u = [[NSURL alloc]initWithScheme:#"/Volumes" host:#"/KINGSTON" path:#"/folder/mytitle.mp3"];
NSLog(#"%d",[manager fileExistsAtPath:[u absoluteString]]); //0
What did I do wrong?
Thanks,
Roland

NSURL *url = [NSURL URLWithString:#"/Volumes/KINGSTON/folder/mytitle.mp3"];
That string does not describe a URL. It's a pathname. Use fileURLWithPath:.
NSLog(#"%d",[manager fileExistsAtPath:[url absoluteString]]);
absoluteString does not return a path; it returns a string describing a URL. Use path.
Or, better yet, use checkResourceIsReachableAndReturnError:.
I also tried:
NSURL *u = [[NSURL alloc]initWithScheme:#"/Volumes" host:#"/KINGSTON" path:#"/folder/mytitle.mp3"];
/Volumes isn't a scheme, /KINGSTON isn't a host, and /folder/mytitle.mp3 is a path but does not refer to anything that exists.
The scheme for a file URL is file:, and the host is generally either localhost or the empty string. The path of a file URL is the complete absolute path to the file.

In your first example, you need to use +[NSURL fileURLWithPath:]. In your second example, I see what you're trying to do, but you're simply going about it the wrong way.
I assume there's a reason you're bothering with NSURL when you have the path you could pass directly to -fileExistsAtPath:?

Related

Issues playing local files with AVPlayer?

Basically, I'm writing a video file to the Application Support directory and then saving it's path:
NSString *guid = [[NSUUID new] UUIDString];
NSString *outputFile = [NSString stringWithFormat:#"video_%#.mp4", guid];
NSString *outputDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *tempPath = [outputDirectory stringByAppendingPathComponent:outputFile];
NSURL *fileURL = [NSURL fileURLWithPath:tempPath]
// code to write a video to fileURL
I save the string path itself by calling [fileURL path];
Now later when I try to create an AVAssetItem from it, I can't actually get it to play.
EDIT:
Ok, so it seems the issue is the space in Application Support. I tried saving the file to just the Library directory and it worked fine.
So the question becomes, how can I play a video I save in the Application Support directory. I wasn't able to create a valid NSURL without escaping the space (when I tried it would return a nil NSURL) but it seems that the space/escaping doesn't allow it to play correctly.
Assume the NSURL to NSString conversion is required (unless it really should be avoided).
Also, side note, but if anyone could give some insight as to why this question was down voted so I can improve the quality of my questions, that would be appreciated. I don't understand?
While I am not informed enough to opine about whether this would change if I had used matt's recommended methods: URLForDirectory:inDomain:appropriateForURL:create:error: and URLByAppendingPathComponent: the actual issue here isn't converting an NSURL to NSString
It's that I'm saving the full URL ([fileURL path]). This is because the [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) objectAtIndex:0]; dynamically changes and the full path won't always point me to the appropriate file.
Instead I need to save just the name of my file (in my case I needed to persist outputFile) and then later dynamically build the the full path when I need it.
The same exact process:
NSString *outputDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *tempPath = [outputDirectory stringByAppendingPathComponent:outputFile];
NSURL *fileURL = [NSURL fileURLWithPath:tempPath];
worked just fine.
TLDR: Saving a full path doesn't work

NSURL fileUrlWithPath method returns double path

this is the scenario:
In a sandboxed app for OS X 10.10.5 I have some path saved in NSString object, say #"file:///Users/xxx/".
Then I execute [NSURL fileURLWithPath:object]. That gives me NSURL object like this
#"file:/Users/xxx --
file:///Users/xxx/Library/Containers/com.123456.App/Data/"
.
I only need this part #"file:///Users/xxx/Library/Containers/com.123456.App/Data/"
Somehow the source string is twisted and doubled and extra dashes added in the middle.
Can anyone explain why does it happen?
Xcode 6.4
fileURLWithPath: will return a file URL path.
i.e starting with: file:///
This means that the string path that you pass it should be in the form of:
#"/Users/xxx/Library/Containers/com.123456.App/Data/"
You do not need to prepend the path with file:///. Or you will get the result that you are getting.
Example:
NSString * stringPath = #"/Users/xxx/Library/Containers/com.123456.App/Data/";
NSURL * anUrl =[NSURL fileURLWithPath:stringPath ];
NSLog(#"nUrl %#",anUrl);
----> nUrl file:///Users/xxx/Library/Containers/com.123456.App/Data/
Can you try something like this? By giving fileName and extension.
NSURL *url=[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"fileName" ofType:#"fileExtension"]];

Getting NSURL of System Root Directory

I want to get the NSURL of the root directory. I have tried this:
NSURL *rootURL = [NSURL fileURLWithPath:#"/" isDirectory:YES];
but it prints
file://localhost/
I want my output to be
file:///
Any help on this simple one?
This should work:
NSURL *url = [NSURL URLWithString:#"file:///"];
It returns what you want.
file://localhost/ is valid.. I don't know if file:/// is also a valid url but if it would be, they are identical.

NSURL path not working, but NSString path working

I saved an object to file and I am now trying to run a check on whether or not that file exists. I have confirmed the path of the file and concluded that the IF statement works when I hard code the path as a NSString, see first block. However, when I try saving the path as a NSURL, and convert it to an NSString so that fileManager can run it's method on it, it does not locate the file at the path. Anything that I am missing here?
LOCATES FILE HERE USING HARD CODE NSSTRING:
[NSKeyedArchiver archiveRootObject:employees toFile:#"/Users/xxx/Documents/employees.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *employeesPath = #"/Users/xxx/Documents/employees.plist";
if ([fileManager fileExistsAtPath:employeesPath]) {
NSLog(#"It exists! yes!");
}
else {
NSLog(#"Doesn't exist, sorry bud");
}
DOES NOT LOCATE FILE USING NSURL:
[NSKeyedArchiver archiveRootObject:employees toFile:#"/Users/xxx/Documents/employees.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *employeesPath = [NSURL fileURLWithPath:#"/Users/xxx/Documents/employees.plist"];
NSString *employeesString = [employeesPath absoluteString];
if ([fileManager fileExistsAtPath:employeesString]) {
NSLog(#"It exists! yes!");
}
else {
NSLog(#"Doesn't exist, sorry bud");
}
EDIT
-- if I wanted to use the NSURL method, I could by making a function to store the path into a NSString the proper way. This ended up working:
NSString* getPropertyListPath() {
NSURL *documentDir = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
NSURL *plist = [documentDir URLByAppendingPathComponent:#"employees.plist"];
return plist.path;
}
You are correct to use NSURL, giuseppe, instead of string literals.
NSURL is more compatible and robust than a string literal. NSURL types will give you access to more methods and functionality.
The trick that you stumbled into is that you needed the file path without the "scheme" or "domain" included in the format.
You are correct to call the path method on your NSURL object to retrieve the correct path format for what you need. The path method only returns the path component to the NSURL address path. It doesn't return the scheme or domain components.
NSString *correctPathFormat = [yourNsurlObject path];
For Example:
If I have a file in the following directory path:
NSString* myDirPath = #"/Users/yourUserName/imageFolder";
and load this into a NSURL object:
NSURL *nsurlDirPath = [NSURL fileURLWithPath:myDirPath];
then append the file name and file type:
NSURL *nsurlFilePath = [nsurlDirPath URLByAppendingPathComponent:#"employee.plist"];
If you call the [nsurlFilePath absoluteString] method you will get an NSString value in the format of "scheme://domain/path"
NSString *retrievePath = [nsurlFilePath absoluteString];
NSLog(#"%#",retrievePath);
This logs out:
file:///Users/yourUserName/imageFolder/employee.plist
Special Note: This is the equivalent to the file path:
file://localhost/Users/yourUserName/imageFolder/employee.plist
The "localhost" is just omitted because this is by default implied, so that is why you see the tripple "///" in "file:///Users/...".
"localhost" is an alias that refers to the local device's ip address, or in other words, the device the code is running on.
Finally, to get the correct path format you need you would run the 'path' method on the NSURL object, which takes us back to the answer at the very beginning of my response:
NSString *correctPathFormat = [nsurlFilePath path];
This logs out the correct "path" component, minus the "scheme" & "domain":
/Users/yourUserName/imageFolder/employee.plist
Further Explanation:
NSURLS have three parts:
scheme : [http, https, ftp, file]
domain : [www.stackoverflow.com, localhost, ipAddress]
path : [/questions/26663573/, /Users/youUserName/subDirName]
scheme | domain | path
file://localhost/Users/youruserName/file.txt
Don't use a NSURL as a file path intermediary.
NSURL *employeesPath = [NSURL fileURLWithPath:#"/Users/xxx/Documents/employees.plist"];
NSString *employeesString = [employeesPath absoluteString];
NSLog(#"employeesString: %#", 'employeesString');
Output:
employeesString: 'file:///Users/xxx/Documents/employees.plist'
Which is clearly not a file path.

How to see the path of a NSURL bookmark even if it's unavailable

I'm saving a NSURL given from a save panel in the user preferences. I'm wondering how to see the path of the URL even if the device on which the file resides is not available, i.e. [NSURL URLByResolvingBookmarkData:options:bookmarkDataIsStale:error:] returns nil.
The last known path of a bookmark can be retrieved like so:
NSDictionary *values = [[NSURL resourceValuesForKeys:#[NSURLPathKey]
fromBookmarkData:bookmarkData]
NSString *path = [values objectForKey:NSURLPathKey];
I made a full writeup of this.