3

The result of this code is that url is null

NSString* home = [NSHomeDirectory() stringByAppendingPathComponent:@"/Library/Application Support/"];
NSURL *url = [NSURL URLWithString:home];

and so is this:

NSString* home = [NSHomeDirectory() stringByAppendingPathComponent:@"/Library/Application Support/"];
home = [home stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:home];
Gruntcakes
  • 37,738
  • 44
  • 184
  • 378

5 Answers5

12

Your question is not about creating an URL from a string containing spaces, but from a path string containing spaces.

For a path, you should not use URLWithString. Mac OS X and iOS include convenience functions for building NSURLs for file paths that handle this and more for you automatically. Use one of them instead.

Apple's documentation for [NSURL fileURLWithPath: path] says:

This method assumes that path is a directory if it ends with a slash. If path does not end with a slash, the method examines the file system to determine if path is a file or a directory. If path exists in the file system and is a directory, the method appends a trailing slash. If path does not exist in the file system, the method assumes that it represents a file and does not append a trailing slash.

As an alternative, consider using fileURLWithPath:isDirectory:, which allows you to explicitly specify whether the returned NSURL object represents a file or directory.

Also, you should be using NSSearchPathForDirectoriesInDomains to find the Application Support directory.

Putting this all together, you'd end up with something like this:

NSArray *paths = NSSearchPathForDirectoriesInDomains(
                     NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *applicationSupportDirectory = [paths objectAtIndex:0];
NSURL *url = [NSURL fileURLWithPath: applicationSupportDirectory isDirectory: YES];

Source:

Community
  • 1
  • 1
Steven Fisher
  • 44,462
  • 20
  • 138
  • 192
4

You actually need to add percent escapes, not remove them:

NSString* home = [NSHomeDirectory() stringByAppendingPathComponent:@"/Library/Application Support/"];
    NSURL *url = [NSURL URLWithString:[home stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    NSLog(@"%@", url);

which prints:

2012-07-18 13:44:54.738 Test[1456:907] /var/mobile/Applications/FF6E6881-1D1B-4B74-88DF-06A2B62CCFE6/Library/Application%20Support
CodaFi
  • 43,043
  • 8
  • 107
  • 153
4

Swift 2.0 version:

let encodedPath = path?.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
KorinW
  • 279
  • 4
  • 10
1

First, if you're actually trying to get the application support directory for your application, use the appropriate method for the job (in this case, on NSFileManager) and work on the URL directly:

NSURL* appSupport = [[NSFileManager defaultManager] URLForDirectory: NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL];

If you really want to build a path, then use the appropriate initializer, in this case, tell the URL that it's a file path URL so that it will deal with spaces naturally and you can probably build up the URL path (this example is more like your code above):

NSString* home = [NSHomeDirectory() stringByAppendingPathComponent:@"/Library/Application Support/"];
// Here, use the appropriate initializer for NSURL
NSURL *url = [NSURL fileURLWithPath:home];

Now, URL will be properly percent encoded and you won't have any problem (it will not be nil when returned).

Jason Coco
  • 77,985
  • 20
  • 184
  • 180
  • If the URL created via URLForDirectory: is fed into NSFileManger:enumeratorAtPath: (after first converting it to a string using absoluteString) then the returned NSDirectoryEnumerator is empty. I was originally using URLForDirectory in combination with enumeratorAtURL: but could not get things to work with what I was doing so switched to enumeratorAtPath, but that will not work with URLForDirectory it seems. See http://stackoverflow.com/questions/11546974/nsfilemanagerenumeratoraturl-returns-a-different-form-of-url-to-nsfilemanager – Gruntcakes Jul 18 '12 at 20:55
  • @ChrisP.Bacon Again, it's an issue of using the correct API. If you have a file URL, you should not convert it to a path by calling `-absoluteString`, you *should* convert it to a path by calling the `-path` method. – Jason Coco Jul 18 '12 at 21:15
0

Swift 5.0 version:

let urlStrWithSpace = "path/test url"

guard let formattedUrl = urlStrWithSpace
.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return }

let sharePath = NSURL(string: formattedUrl)
tanmoy
  • 1,276
  • 1
  • 10
  • 28