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."

Replies

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"
  • the example you gave above is alright let u = URL(fileURLWithPath: "/Users/quinn/Web Staging")

    But if you wanted to add just a string to a url and this convert the string into url taking all the spaces and making them %20 instead.. the solution above does not work.

    let test = URL(fileURLWithPath: "test this")

    then add this to a url url = URL(string: "https://realty-in-us.p.rapidapi.com/locations/auto-complete?input=\(test)") you want to get "https://realty-in-us.p.rapidapi.com/locations/auto-complete?input=test%20this"

    BUT you get this "https://realty-in-us.p.rapidapi.com/locations/auto-complete?input=test%20this -- file:///"

    how can we remove the "-- file:///" part ?

Add a Comment

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.