I can't make a URL object from a valid URL string

Hello!

I've been trying to use URLComponents().url to get a URL object from some predefined URL pieces, but every time, URLComponents.url returns nil. I spent a bit figuring that I had gotten my URLComponent pieces wrong, but I eventually output the URLComponents.string value to my debugging console and got the URL string that I was looking for. When I output each piece of the URLComponents object, those are correct as well.


Once I figured out that the pieces were getting put together successfully, I decided to see if I could manually create a URL object with the URL string that was output by URLComponents().string by passing it into the URL(string:) initializer, but again, I was getting nil when I printed the output in my debugger.


From there, I figured that maybe the URL that I was giving the URL(string:) intializer was just a bad URL string, so I substituted it with "https://google.com", but once again, I was getting nil when I tried to initialize the URL.

I don't know what is going on here, but we just migrated this application from Swift 4.0 to Swift 5, so maybe that might have something to do with it? I'll post my code below to see if there are any glaring issues, but at the moment, it seems like I can't get anywhere with URLs.


func generateUrl(path: String, queryParams: String?) -> URL {
        var urlComponents = URLComponents()
        urlComponents.scheme = self.networkProtocol // "https"
        urlComponents.host = self.url // "1d9fbe45.ngrok.io"
        urlComponents.path = "/api/mobile" + path // "/api/mobile/user-logged-in"
        
        if let queryParams = queryParams { // queryParams is nil in this case
            urlComponents.query = queryParams
        }
        
        guard let fullUrl: URL = urlComponents.url else { // No error is present because fullUrl = {}
            fatalError("Could not create URL from the given URL components.")
        }
        
        return fullUrl
    }

Replies

Can you tell more for testing.


What is self here ?

How do you call generateUrl ? What is path parameter : /user-logged-in or user-logged-in?

Note: you write

        urlComponents.path = "/api/mobile" + path // "/api/mobile/user-logged-in"


and not with /

        urlComponents.path = "/api/mobile/" + path // "/api/mobile/user-logged-in"


Is it on purpose ?


I must miss something here.

I tried in playground:

func generateUrl(path: String, queryParams: String?) -> URL {
    var urlComponents = URLComponents()
    urlComponents.scheme = "https" //self.networkProtocol // "https"
    urlComponents.host = "1d9fbe45.ngrok.io" // self.url // "1d9fbe45.ngrok.io"
    urlComponents.path = "/api/mobile" + path // "/api/mobile/user-logged-in"
     
    if let queryParams = queryParams { // queryParams is nil in this case
        urlComponents.query = queryParams
    }
     
    guard let fullUrl: URL = urlComponents.url else { // No error is present because fullUrl = {}
        fatalError("Could not create URL from the given URL components.")
    }
     
    return fullUrl
}

let result = generateUrl(path: "/user-logged-in", queryParams: nil)
print(result)


and got (I edited as h ttps for moderation):

h ttps://1d9fbe45.ngrok.io/api/mobile/user-logged-in

I cannot reproduce the same issue.


Have you really printed the result URL with `print` function ? Or just you have watched the variables pane of the debugger?


Xcode some times shows false values for some types, and you need to write an actual `print` statement to inspect such values.