URLNavigator

repository·master·Indexed 25 days ago

https://github.com/devxoul/urlnavigator

A 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.

Tokens
1.4K
Snippets
5
Records
8
Agent score
36%

What's inside URLNavigator

  1. Test a Deeplink using the `navigator://` scheme

    master
    You can test the deeplink functionality by using Safari on an iPhone Simulator or a physical iOS device. Enter a URL using the navigator:// scheme and press 'Go'. This will trigger the example application to launch with the specified deeplink.
  2. Understand URL Patterns and Placeholders

    master

    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)
    • int
    • float
    • path

    Example: myapp://user/<int:id> matches myapp://user/123 but fails if the ID is not an integer or if the URL structure differs.

  3. Build the URLNavigator Example project

    master

    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.xcworkspace
  4. Handle App Launch and Open URL in AppDelegate

    master

    To 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
    }
  5. Push, Present, and Open URLs

    master

    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.

  6. Define Custom URL Value Converters

    master

    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:_>
  7. Register View Controllers and URL Open Handlers

    master

    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
    }