Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to construct url in swift 3/4 using URL(string: , relativeTo:)

Tags:

I'm trying to construct a url in swift 3 but I don't understand why it doesn't append the string to the baseURL properly the output is not what I expected. In swift 2 it worked fine.

let token = "12token34"

let baseURL = URL(string: "https://api.mysite.net/map/\(token)/")

let desiredURL = URL(string: "37.8267,-122.4233", relativeTo: baseURL as URL?)

result

37.8267,-122.4233 -- https://api.mysite.net/map/12token34/

I was expecting the following:

https://api.mysite.net/map/12token34/37.8267,-122.4233
like image 912
Benjamin Avatar asked Nov 15 '16 04:11

Benjamin


1 Answers

The initializer is doing what you think it ought to; it's the string representation of URL that's confusing. In the REPL:

1> import Foundation
2> let token = "12token34"
token: String = "12token34"
3> let baseURL = URL(string: "https://api.mysite.net/map/\(token)/")
baseURL: URL? = "https://api.mysite.net/map/12token34/"

So far so good; now comes the confusing part:

4> let desiredURL = URL(string: "37.8267,-122.4233", relativeTo: baseURL as URL?)
desiredURL: URL? = "37.8267,-122.4233 -- ttps://api.mysite.net/map/12token34/"

This is a relative URL object, but it does actually represent the URL you expect it to:

5> desiredURL!.absoluteString
$R0: String = "https://api.mysite.net/map/12token34/37.8267,-122.4233"

If you want it in absolute form, you can get it with absoluteURL:

6> desiredURL!.absoluteURL
$R1: URL = "https://api.mysite.net/map/12token34/37.8267,-122.4233"

Note that this works for more cases as well:

1> import Foundation
2> let base = URL(string: "http://example.org/foo/bar/baz.txt")
base: URL? = "http://example.org/foo/bar/baz.txt"

Siblings in the same directory:

3> let sib = URL(string: "./qux.txt", relativeTo: base!)
sib: URL? = "./qux.txt -- ttp://example.org/foo/bar/baz.txt"
4> sib!.absoluteURL
$R0: URL = "http://example.org/foo/bar/qux.txt"

Up the directory tree and back down:

5> let cousin = URL(string: "../corge/garply.txt", relativeTo: base!)
cousin: URL? = "../corge/garply.txt -- ttp://example.org/foo/bar/baz.txt"
6> cousin!.absoluteURL 
$R1: URL = "http://example.org/foo/corge/garply.txt"

All the way to the root and back down:

7> let fromRoot = URL(string: "/waldo/fred.txt", relativeTo: base!)
fromRoot: URL? = "/waldo/fred.txt -- ttp://example.org/foo/bar/baz.txt"
8> fromRoot!.absoluteURL
$R2: URL = "http://example.org/waldo/fred.txt"
like image 129
David Moles Avatar answered Sep 25 '22 16:09

David Moles