ChatGPT解决这个技术问题 Extra ChatGPT

Check if file exists at URL instead of path

How can I check if a file exists at a URL (instead of a path), in order to set a pre-populated default store into the iPhone Simulator:

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Food.sqlite"];
/*
 Set up the store.
 For the sake of illustration, provide a pre-populated default store.
 */
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the expected store doesn't exist, copy the default store.
if (![fileManager fileExistsAtPath:storePath]) {
    NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"Food" ofType:@"sqlite"];
    if (defaultStorePath) {
        [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
    }
}

I've read that in recent versions of the templates, the applicationDocumentsDirectory method returns an URL, so I've changed the code to use NSURL objects to represent the file path. But at [fileManager fileExistsAtPath:storePath], I need to change fileExistsAtPath to something like fileExistsAtURL (obviously it doesn't exist).

I've checked the NSFileManager Class Reference and I didn't find any suitable task suited for my purpose.

Any hints please?


M
Mundi
if (![fileManager fileExistsAtPath:[storeURL path]]) 
...

From the documentation:

If this URL object contains a file URL (as determined with isFileURL), the return value of this method is suitable for input into methods of NSFileManager or NSPathUtilities. If the path has a trailing slash it is stripped.


was having an error using [url absoluteString]. DO NOT USE absoluteString. Cheers.
Thank you codrut!!!!! absoluteString was messing with my file. Now using .path instead of .absoluteString everything is fine!
It should. The store URL is just different because it is not in the app sandbox but in a shared container folder. This implementation detail is abstracted away, so it should work.
v
vadian

For a file system URL NSURL itself has a method to check the reachability of an URL

NSError *error;
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Food.sqlite"];
if ([storeURL checkResourceIsReachableAndReturnError:&error]) {
  // do something
} else {
  NSLog(@"%@", error);
}

Most direct solution. There is no need to rely on fileManager.
This has a problem in Swift land, in that checkResourceIsReachable() throws an exception (!) if the item is not reachable. So you have to go to all the trouble of catching an exception rather than checking a return result...
@KendallHelmstetterGelner Actually you have not. See my answer here
Thanks, I took a look and commented on it. I like the idea of the try? wrapper but I really don't like calling something I know will mostly be throwing exceptions as I don't want that overhead.
@KendallHelmstetterGelner Swift exceptions have no more overhead than 'if / then / else'. That why they must be dealt with in the same scope they are thrown. They are really still just return codes. See the 'Note:' in the swift book error handling section -> ... error handling in Swift does not involve unwinding the call stack, a process that can be computationally expensive. As such, the performance characteristics of a throw statement are comparable to those of a return statement.
M
Mickaël
if (![fileManager fileExistsAtPath:[storeURL path]]) 

is ok, but be carful : for an url like :

..../Documents/1158a3c96ca22c41b8e731b1d1af0e1e?d=mm&s=50

[storeURL path] will give you that path (it apply to [storeURL lastPathComponent] :

..../Documents/1158a3c96ca22c41b8e731b1d1af0e1e

but if you use lastPathComponent on a string like /var/mobile/Applications/DB92F4DC-49E4-4B4A-8271-6A9DAE6963BC/Documents/1158a3c96ca22c41b8e731b1d1af0e1e?d=mm&s=50, it will give you 1158a3c96ca22c41b8e731b1d1af0e1e?d=mm&s=50

And that's good, since in a url, '?' is used for GET parameters, but if you mix with string, you might have troubles.


关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now