Test a Deeplink using the `navigator://` scheme
masternavigator:// scheme and press 'Go'. This will trigger the example application to launch with the specified deeplink.repository·master·Indexed 25 days ago
https://github.com/devxoul/urlnavigatorA Swift library for view controller navigation using URL patterns. It allows mapping URL schemes and paths to view controller initializers or custom execution handlers, supporting typed placeholders (string, int, float, path) and custom value converters for deep linking in iOS applications.
navigator:// scheme and press 'Go'. This will trigger the example application to launch with the specified deeplink.URL patterns use < and > to define placeholders. Placeholders extract values from the URL and can be typed to ensure strict matching. Supported types include:
string (default)intfloatpathExample: myapp://user/<int:id> matches myapp://user/123 but fails if the ID is not an integer or if the URL structure differs.
URLNavigator officially supports CocoaPods. Add the following to your Podfile:
pod 'URLNavigator'To build and run the provided example project, navigate to the URLNavigator/Example directory, install the necessary CocoaPods dependencies, and open the workspace in Xcode.
$ cd URLNavigator/Example
$ pod install
$ open URLNavigator.xcworkspaceTo support deep linking when the app is launched via a URL, implement application:didFinishLaunchingWithOptions: and application:openURL:sourceApplication:annotation: in your AppDelegate.
In didFinishLaunchingWithOptions, check for the .url launch option to either open or present the URL. In openURL, attempt to open the URL via the navigator, and if that fails, attempt to present it.
// In AppDelegate
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
) -> Bool {
if let url = launchOptions?[.url] as? URL {
if let opened = navigator.open(url) {
// handled
} else {
navigator.present(url)
}
}
return true
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
// Try URLNavigator open handler
if navigator.open(url) {
return true
}
// Try URLNavigator View Controller presentation
if navigator.present(url, wrap: UINavigationController.self) != nil {
return true
}
return false
}Use the Navigator to perform navigation actions:
push(_:from:context:): Pushes a view controller onto a navigation controller. If from is nil, it uses the top-most view controller.present(_:wrap:from:context:): Presents a view controller. The wrap parameter allows you to wrap the new controller in a specific UINavigationController class.open(_:context:): Executes a registered URLOpenHandler.You can pass an optional context dictionary to any of these methods to provide extra data to the handlers.
You can extend the matching logic by adding custom value converters to the navigator.matcher.valueConverters dictionary. This allows you to restrict placeholders to specific allowed values.
navigator.matcher.valueConverters["region"] = { pathComponents, index in
let allowedRegions = ["us-west-1", "ap-northeast-2", "eu-west-3"]
if allowedRegions.contains(pathComponents[index]) {
return pathComponents[index]
} else {
return nil
}
}
// Pattern usage: myapp://region/<region:_>You can map URL patterns to view controllers (using a closure that returns a view controller) or to URL open handlers (using a closure that returns a Bool).
Closures receive three parameters:
url: The URL passed from push(), present(), or open().values: A dictionary containing URL placeholder keys and their extracted values.context: A dictionary containing extra values passed via the context parameter in navigation calls.let navigator = Navigator()
// Register view controllers
navigator.register("myapp://user/<int:id>") { url, values, context in
guard let userID = values["id"] as? Int else { return nil }
return UserViewController(userID: userID)
}
// Register URL open handlers
navigator.handle("myapp://alert") { url, values, context in
let title = url.queryParameters["title"]
let message = url.queryParameters["message"]
presentAlertController(title: title, message: message)
return true
}