iPhone
URL validation
iOS development
Swift programming
mobile app development

How to validate an url on the iPhone

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Validating a URL on iPhone can mean several different things, and that is why many implementations feel inconsistent. A string can be syntactically valid, acceptable according to your app's business rules, openable by iOS, and reachable on the network, but those are four separate checks.

The cleanest approach is to validate in layers. First parse the string, then apply app-specific rules, then optionally ask iOS whether it can open the URL, and only perform a network request if you truly need to know whether the remote endpoint responds.

Parse the String with URLComponents

For user-entered text, URLComponents is often the best first step because it lets you inspect the scheme, host, path, and query without inventing a regex parser.

swift
1import Foundation
2
3func isValidWebURL(_ text: String) -> Bool {
4    guard let components = URLComponents(string: text),
5          let scheme = components.scheme?.lowercased(),
6          let host = components.host,
7          !host.isEmpty else {
8        return false
9    }
10
11    return scheme == "http" || scheme == "https"
12}
13
14print(isValidWebURL("https://example.com"))
15print(isValidWebURL("ftp://example.com"))
16print(isValidWebURL("example.com"))

This answers a narrow question: does the string look like a web URL your app is willing to accept. It does not tell you whether the server exists or whether iOS can open a non-web scheme.

The main benefit of this style is clarity. If your product accepts only https, write that rule directly. If it accepts custom schemes, whitelist them explicitly rather than pretending everything is a website.

Normalize Input Before Rejecting It

Real users often enter example.com instead of https://example.com. If your product wants to be forgiving, normalize the text before validation instead of marking obviously intended input as invalid.

swift
1import Foundation
2
3func normalizedWebURL(from text: String) -> URL? {
4    let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines)
5    let candidate = trimmed.hasPrefix("http://") || trimmed.hasPrefix("https://")
6        ? trimmed
7        : "https://" + trimmed
8
9    guard isValidWebURL(candidate) else {
10        return nil
11    }
12
13    return URL(string: candidate)
14}
15
16print(normalizedWebURL(from: "example.com") as Any)

Normalization is a product decision, not a correctness rule. For a browser-like input field, this is helpful. For a strict configuration screen, you may want to reject anything that omits the scheme.

Ask iOS Whether the URL Can Be Opened

UIApplication.shared.canOpenURL answers a different question from parsing. It tells you whether the current device and app configuration can handle the URL.

swift
1import UIKit
2
3func canOpenURLString(_ text: String) -> Bool {
4    guard let url = URL(string: text) else {
5        return false
6    }
7
8    return UIApplication.shared.canOpenURL(url)
9}

This is especially useful for tel:, mailto:, sms:, or app-specific deep links. It is not a general "is this a good web URL" validator. For custom schemes, remember that iOS may require entries in LSApplicationQueriesSchemes before canOpenURL gives the answer you expect.

Check Reachability Only When You Really Need It

If the real requirement is "make sure the server responds," parsing is still not enough. At that point you need a network request. A lightweight HEAD request is a common choice:

swift
1import Foundation
2
3func urlResponds(_ url: URL) async -> Bool {
4    var request = URLRequest(url: url)
5    request.httpMethod = "HEAD"
6    request.timeoutInterval = 5
7
8    do {
9        let (_, response) = try await URLSession.shared.data(for: request)
10        guard let http = response as? HTTPURLResponse else {
11            return false
12        }
13        return (200...399).contains(http.statusCode)
14    } catch {
15        return false
16    }
17}

This is a network health check, not URL validation in the structural sense. It can fail because of connectivity, server policy, redirects, or timeouts even when the URL string itself is completely valid.

Common Pitfalls

The biggest pitfall is collapsing all validation into one Boolean. A string can be parseable but not allowed by your product rules. It can be allowed but not openable by iOS. It can be openable and still point to a server that is down.

Another common mistake is using a large regex as the primary validator. URL syntax is subtle, and the platform URL parsers are usually easier to reason about and maintain.

Developers also misuse canOpenURL as though it were a general web validator. It is really an app-and-device capability check.

Finally, be careful with silent normalization. Adding https:// automatically can improve UX, but only if that matches what the product expects. If the field represents a literal configuration value, normalization may hide bad input rather than fixing it.

Summary

  • Decide whether you are validating syntax, app policy, iOS openability, or network reachability.
  • Use URLComponents or URL for structure instead of starting with regex.
  • Normalize incomplete user input only when the product deliberately wants that behavior.
  • Use canOpenURL for scheme handling, not for general web validation.
  • Perform a network request only if you actually need to know whether the endpoint responds.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.