URLs in Swift: Common scenarios explained in-depth – onlinecode

URLs in Swift: Common scenarios explained in-depth – onlinecode

In this post we will give you information about URLs in Swift: Common scenarios explained in-depth – onlinecode. Hear we will give you detail about URLs in Swift: Common scenarios explained in-depth – onlinecodeAnd how to use it also give you demo for it if it is necessary.

URLs are everywhere in an app we built. We reference local files using bundle paths, we fetch data from a path pointing to our API, and we fetch images to display visuals. While working with URLs we often need to verify things like making sure that it’s pointing to a file or that certain query property is set.

Some of those operations might be easy to remember and don’t require an intensive guide like this. However, I find myself often searching for that one stack overflow question that explains how to build a URL with a given set of query parameters. As a blogger, this is often the moment where I decide to write a manual for myself and share it with you!

Architecting SwiftUI apps with MVC and MVVMAlthough you can create an app simply by throwing some code together, without best practices and a robust architecture, you’ll soon end up with unmanageable spaghetti code. Learn how to create solid and maintainable apps with fewer bugs using this free guide.

Basic URL Operations

It all starts with basic operations to create and work with links. For example, you can convert a String value into a URL as follows:

let url = URL(string: "https://www.onlinecode.org")!

The downside of this default initializer is the force unwrap we likely have to copy over throughout our codebase. A simple extension helps us to prevent this by using a custom initializer:

extension URL {
    init(_ string: StaticString) {
        self.init(string: "(string)")!
    }
}

var unwrappedURL = URL("https://www.onlinecode.org")

That looks a lot more swiftly and allows us to keep our implementation code clean from unwraps!

Converting a URL into a String

A URL can also be converted into a String by using the absoluteString property:

print(unwrappedURL.absoluteString) // Prints: https://www.onlinecode.org

Making a URL relative to a base URL

A scenario that’s often used when building an API in Swift is to construct a link by using a base URL. For example, we could build up a blog post category page as follows:

let category = "swift"
let baseURL = URL(string: "https://www.onlinecode.org")!
let blogURL = URL(string: category, relativeTo: baseURL)!
print(blogURL) // Prints: swift -- https://www.onlinecode.org
print(blogURL.absoluteString) // Prints: https://www.onlinecode.org/swift

At the same time, you can get the base for a certain link if the URL itself is not absolute:

let absoluteURL = URL(string: "https://www.onlinecode.org")!
let relativeURL = URL(string: "swift", relativeTo: baseURL)!
print(absoluteURL.baseURL) // Prints: nil
print(relativeURL.baseURL!) // Prints: https://www.onlinecode.org

A base URL is often confused with getting the host of a link that prints out the domain without its scheme. You can get the scheme by using the scheme parameter:

let swiftLeeURL = URL(string: "https://www.onlinecode.org")!
print(absoluteURL.host!) // Prints: www.onlinecode.org
print(absoluteURL.scheme!) // Prints: https

Working with URL Components

A link is basically built up out of several components. We’ve seen a few already in the print statements before but there are a lot more components to cover:

let twitterAvatarURL = URL(string: "https://twitter.com/twannl/photo.png?width=200&height=200")!
print(twitterAvatarURL.path) // Prints: /twannl/photo.png
print(twitterAvatarURL.pathComponents) // Prints: ["/", "twannl", "photo.png"]
print(twitterAvatarURL.pathExtension) // Prints: png
print(twitterAvatarURL.lastPathComponent) // Prints: photo.png

These properties are great for a lot of cases like getting the file name or extension but they don’t give us the query items. This is where URLComponents come into place.

Get the value of query parameters

The above Twitter avatar link contains two query parameters that describe the width and the height of the image. This is important information to fetch so we make sure that the image is displayed in the correct ratio. Therefore, we need to be able to get those query parameters and their values.

We can do this by using a URLComponents instance initialized with the link. It gives us access to a new collection of properties. You can basically see it as a URL parser that gives us access to, for example, the query items:

let components = URLComponents(string: "https://twitter.com/twannl/photo.png?width=200&height=200")!
print(components.query!) // width=200&height=200
print(components.queryItems!) // [width=200, height=200]

Note that the URLComponents structure parses and constructs URLs according to RFC 3986. Its behavior differs subtly from that of the URL structure, which conforms to older RFCs. However, you can easily obtain a URL value based on the contents of a URLComponents value or vice versa.

This allows us to directly access the values by going over the query items array:

let width = components.queryItems!.first(where: { queryItem -> Bool in
    queryItem.name == "width"
})!.value!
let height = components.queryItems!.first(where: { queryItem -> Bool in
    queryItem.name == "height"
})!.value!
let imageSize = CGSize(width: Int(width)!, height: Int(height)!)
print(imageSize) // Prints: (200.0, 200.0)

However, this is still not the most beautiful piece of code. We use a lot of unwraps and the code is not really readable as well. Therefore, we can make use of a custom subscript that allows us to make this code look a lot nicer:

extension Collection where Element == URLQueryItem {
    subscript(_ name: String) -> String? {
        first(where: { $0.name == name })?.value
    }
}
let imageWidth = Int(components.queryItems!["width"]!)!
let imageHeight = Int(components.queryItems!["height"]!)!
let size = CGSize(width: imageWidth, height: imageHeight)

New to custom subscripts? Check out my blog post Custom subscripts in Swift explained with code examples.

Yes, these are still a lot of unwraps. I’ll leave it up to you to make this look nicer by using guards for unwrapping. At least, we can access the query items a lot easier.

Constructing a URL with parameters

The other way around is building a URL with query parameters from a dictionary. This is often used when building an API framework.

For example, if we want to fetch an avatar with a certain width and height, we can build it up as follows:

let parameters = [
    "width": 500,
    "height": 500
]
var avatarURLComponents = URLComponents(string: "https://twitter.com/twannl/photo.png")!
avatarURLComponents.queryItems = parameters.map({ (key, value) -> URLQueryItem in
    URLQueryItem(name: key, value: String(value))
})
print(avatarURLComponents.url!) // Prints: https://twitter.com/twannl/photo.png?width=500&height=500

It might be valuable to write an extension here as well to make it easier to convert a dictionary into an array of query items:

extension Array where Element == URLQueryItem {
    init<T: LosslessStringConvertible>(_ dictionary: [String: T]) {
        self = dictionary.map({ (key, value) -> Element in
            URLQueryItem(name: key, value: String(value))
        })
    }
}
let pagingParameters = [
    "offset": 2,
    "limit": 50
]
var twitterFeedURLComponents = URLComponents(string: "https://twitter.com/feed")!
twitterFeedURLComponents.queryItems = .init(pagingParameters)
print(twitterFeedURLComponents.url!) // Prints: https://twitter.com/feed?offset=2&limit=50

Working with file URLs

When building apps we often reference local or remote files. You can download a certain image from a remote location or you can fetch an image from your local bundle.

It’s good to understand the difference between a remote URL and a local one. Only the latter is considered a file URL when using the isFileURL parameter:

var remoteFileURL = URL(string: "https://www.twitter.com/avatar.jpg")!
var fileURL = URL(string: "file:///users/antoine/avatar.jpg")!
print(remoteFileURL.isFileURL) // Prints: false
print(fileURL.isFileURL) // Prints: true

This property basically only returns true when the URL scheme is file:.

Getting the file extensions from a file path

When working with files you often want to know the file extension to determine the file type. You can do this by using the path extension parameter:

print(fileURL.pathExtension) // Prints: jpg

How to get the filename from a file path in Swift

To get the file name from a file URL we can use the lastPathComponent and extract the filename by removing the file extension:

print(fileURL.deletingPathExtension().lastPathComponent) // Prints: avatar

Isn’t that simple? This is great if you want to display the file name in your UI.

Architecting SwiftUI apps with MVC and MVVMAlthough you can create an app simply by throwing some code together, without best practices and a robust architecture, you’ll soon end up with unmanageable spaghetti code. Learn how to create solid and maintainable apps with fewer bugs using this free guide.

Conclusion

URLs in Swift are used in a lot of ways. We fetch data using an API, images to visualize our app, and we often work with local files from our bundle. The Foundation framework allows us to access a lot of URL components easily with default parameters. If we need access to URL components like query items, we can make use of the URLComponents type.

Do you think that I missed an essential part of working with URLs? Please, let me know!

If you like to improve your Swift knowledge, even more, check out the Swift category page. Feel free to contact me or tweet to me on Twitter if you have any additional tips or feedback.

Thanks!

 

Hope this code and post will helped you for implement URLs in Swift: Common scenarios explained in-depth – onlinecode. if you need any help or any feedback give it in comment section or you have good idea about this post you can give it comment section. Your comment will help us for help you more and improve us. we will give you this type of more interesting post in featured also so, For more interesting post and code Keep reading our blogs

For More Info See :: laravel And github

We're accepting well-written guest posts and this is a great opportunity to collaborate : Contact US