URL from string with spaces in it

How do I construct a URL from a string with spaces in it?

For example: http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.quote where symbol in ("AAPL")


let text = "http:// + "query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.quote where symbol in ("AAPL")&format=json&env=http://datatables.org/alltables.env"

let url = NSURL(String: text)

returns url = nil


In related, what must I do re the Apple Transport policy to make this secure?

Just making it https (rather than http) doesn't seem to be sufficient."

You should escape the spaces. To do that, you can either change the spaces to "%20" or "+".

You should look at the NSURLComponents API, which lets you build a URL from its component parts. It will take care of the nightmare that is URL quoting. For example:

import Foundation

let uc = NSURLComponents()
uc.scheme = "http"
uc.host = "query.yahooapis.com"
uc.path = "/v1/public/yql"
uc.queryItems = [
    NSURLQueryItem(name: "q", value: "select * from yahoo.finance.quote where symbol in (\"AAPL\")"),
    NSURLQueryItem(name: "format", value: "json"),
    NSURLQueryItem(name: "env", value: "http://datatables.org/alltables.env")
]
print(uc.URL!.absoluteString)

This prints:

http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quote%20where%20symbol%20in%20(%22AAPL%22)&format=json&env=http://datatables.org/alltables.env

You can shrink the code by starting with a known, good, no-quoting-required URL string:

import Foundation

let uc = NSURLComponents(string: "http://query.yahooapis.com/v1/public/yql")!
uc.queryItems = … continue as above …

In related, what must I do re the Apple Transport policy to make this secure?

That really depends on the service provider; you’ll have to ask them if they vend the service via HTTPS. If they don’t, accessing the service securely is going to be a challenge. The only reasonable secure option is for you to create your own front end to the service that supports HTTPS. Your app can then talk to your front end securely using HTTPS, which can then talk to the original service via HTTP, making sure to not pass along any identifying information.

The insecure alternatively is to add an ATS exception dictionary to your app.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>query.yahooapis.com</key>
        <dict>
            <key>NSAppTransportSecurity</key>
            <true/>
        </dict>
    </dict>
</dict>

WARNING This won’t make your networking secure, it’ll just stop ATS complaining about its insecurity.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Is there any improvement on this? I'm getting errors in a Swift script if a filepath uses spaces. (The filepath gets converted to a URL.)


I've got a workaround:


myURL = NSURL.fileURL(withPath: myString)


(Apple's docs say to use fileURLWithPath, but that's deprecated.)


Then I have to use "myURL as URL" to force a type conversion, even though I thought they are supposed to be "toll-free".


IS there a better way?

IS there a better way?

The droid you’re looking for here is

URL(fileURLWithPath:)
.
let u = URL(fileURLWithPath: "/Users/quinn/Web Staging")
print(u)        // prints "file:///Users/quinn/Web%20Staging/"

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I thought I had tried that, and Xcode told me not to use it. It might be possible I'm confusing NSURL with CFURL and URL, of course!


Thanks.

Apple Swift framework developers should be utterly embarrased that this is still happening in 2023. They have obviously been asleep at the wheel for ages now. None of the answers here works.

URL(string: ) should contain allowance to correct for spaces; the fact that it doesn't is truly and utterly embarrassing and costs devs a LOT of f'g wasted time.

Swift String has a var .addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) amongst other options for allowedCharacters which can tidy-up strings used to creat URLs. The docs mention "Calling this method on strings that are already percent-encoded will cause percent characters in a percent-encoded sequence to be percent-encoded twice", but there is also a .removingPercentEncoding var to manage that

I don't know why this old thread has just popped up on "last updated", but I'm going to reply to this part anyway:

URL(string: ) should contain allowance to correct for spaces

No, you can't do that. You need to do appropriate escaping on the components before you construct the string. Once you've constructed the string by concatenating the components, you can't tell if (for example) an = is something that should be escaped to %3D or whether it's the separator between a key and a value that needs to remain as a literal =.

URL from string with spaces in it
 
 
Q