Skip to content

Instantly share code, notes, and snippets.

@sturdysturge
Last active Jul 10, 2020
Embed
What would you like to do?
RevDoc onOpenURL
import SwiftUI
extension URL {
/// All symbols allowed in a URL
static let allowedCharacters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$-.,+!*()&#=/;@?:"
}
extension Character {
//Check a character is allowed when constructing a URL
var isAllowedInURL: Bool {
return URL.allowedCharacters.contains(self)
}
}
extension String {
/// Remove all characters not allowed in a URL from the string
/// - Precondition: String must not be empty and contain at least one character allowed in a URL
/// - Postcondition: A valid String for creating a URL
var urlString: String {
precondition(self.isEmpty == false, "String cannot be empty")
let returnValue = self.filter { $0.isAllowedInURL }
precondition(URL(string: returnValue) != nil, "urlString \(returnValue) could not be used to make a URL")
return returnValue
}
}
extension URL {
/// Creates a URL from the provided string after removing all illegal characters
/// - Precondition: String must not be empty and contain at least one character allowed in a URL
init(unsafeString: String) {
guard let url = URL(string: unsafeString.urlString) else {
preconditionFailure("Unsafe string \(unsafeString) was not made safe by String.urlString extension")
}
self = url
}
}
struct ContentView: View {
//Whatever scheme you entered in your project settings under URL types
let myURLScheme = "my-scheme://"
@State var text = ""
@State var openedURLs = [String]()
var fullURL: URL {
return URL(unsafeString: myURLScheme + text)
}
var body: some View {
Form {
HStack {
Text(myURLScheme)
TextField("Add text to URL", text: $text)
}
Link(destination: fullURL) {
Text("Open")
}
.onOpenURL { url in
openedURLs.append(url.absoluteString)
}
Section(header: Text("Opened URLs")) {
ForEach(0..<openedURLs.count, id: \.self) {
index in Text(openedURLs[index])
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment