module NoirMobileLinker::IosHandlers

Overview

Scans .swift files once for the central deep-link dispatch handlers and groups their callees/params by kind. URL handlers process custom schemes; userActivity handlers process universal links.

Defined in:

mobile/linker.cr

Constant Summary

ACTIVITY_HANDLER_RES = [/\bfunc\s+application\s*\(.*\bcontinue\s+userActivity\s*:/, /\bfunc\s+scene\s*\(.*\bcontinue\s+userActivity\s*:/, /\.onContinueUserActivity\s*\(/]
IOS_CALLEE_NOISE = Set {"URL", "URLRequest", "URLComponents", "NSURLComponents", "componentsWithURL", "isEqualToString", "host", "shared", "URLContexts.first", "print", "Task", "UIApplication.shared.canOpenURL", "Notification.Name", "NotificationCenter.default.post", "UserDefaults.standard.bool", "AppContainer.shared.resolve", "routeBuilder.configure"}
MAX_FORWARDED_ACTIONS = 8
MAX_FORWARDED_CASES = 24
OBJC_ACTIVITY_HANDLER_RES = [/\bapplication:.*\bcontinueUserActivity:/, /\bscene:.*\bcontinueUserActivity:/]
OBJC_HANDLER_HINTS = ["openURL:", "openURLContexts:", "continueUserActivity:"]
OBJC_QUERY_ITEM_RE = /\bqueryItemWithName:\s*@"([^"]+)"/
OBJC_QUERY_NAME_RE = /(?:\.name|\bname\])\s+isEqualToString:\s*@"([^"]+)"/

Objective-C query reads. The dominant idiom is iterating components.queryItems and comparing the item's name against a literal — [item.name isEqualToString:@"token"] (e.g. VLC reads plexToken / payment_intent this way). Anchored to .name / name] (not a bare isEqualToString:) so a [host isEqualToString:@"new"] check can't become a phantom param. Also the explicit query-item constructor.

OBJC_SIGNATURE_START_RE = /^\s*[+-]\s*\([^)]*\)\s*(?:application|scene):/
OBJC_URL_HANDLER_RES = [/\bapplication:.*\bopenURL:/, /\bscene:.*\bopenURLContexts:/]

Objective-C counterparts. The same delegate methods are written as message-style declarations: - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:…. Matched on the folded signature, so a wrapped parameter list still classifies.

QUERY_ITEM_RE = /URLQueryItem\(\s*name:\s*"([^"]+)"/
QUERY_NAME_RE = /\$\d+\.name\s*==\s*"([^"]+)"/

URLQueryItem name comparisons inside a handler — the iOS analog of Android's getQueryParameter. Anchored to the closure-shorthand form ($0.name == "x") and an explicit URLQueryItem(name: "x") so a plain user.name == "admin" comparison can't become a phantom query param.

SIGNATURE_START_RE = /\bfunc\s+(?:application|scene)\s*\(/

Opening of an application(...) / scene(...) delegate method whose parameter list may wrap across lines; used to fold the signature before classifying it against the handler patterns above.

SWIFT_HANDLER_HINTS = ["openURLContexts", "open url:", "continue userActivity:", ".onOpenURL", ".onContinueUserActivity"]
URL_HANDLER_RES = [/\.onOpenURL\s*\{/, /\bfunc\s+application\s*\(.*\bopen\s+url\s*:/, /\bfunc\s+scene\s*\(.*\bopenURLContexts\b/]

Same-line markers for the brace that opens a handler body.

XCODE_PROJECT_SEARCH_DEPTH = 6

Class Method Summary

Class Method Detail

def self.discover(scope_root : String | Nil = nil) : Hash(Symbol, NoirMobileLinker::HandlerInfo) #

[View source]
def self.nearest_handler_source_root(path : String) : String | Nil #

[View source]
def self.xcode_project_root(path : String) : String | Nil #

[View source]