Agent skills for iOS, iPadOS, Swift, SwiftUI, and modern Apple framework development.
71
89%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Advisory
Suggest reviewing before use
Route external URLs into in-app destinations while falling back to system handling when needed.
handle(url:), handleDeepLink(url:)).OpenURLAction handler that delegates to the router..onOpenURL for app scheme links and convert them to web URLs if needed.@MainActor
final class RouterPath {
var path: [Route] = []
var urlHandler: ((URL) -> OpenURLAction.Result)?
func handle(url: URL) -> OpenURLAction.Result {
if isInternal(url) {
navigate(to: .status(id: url.lastPathComponent))
return .handled
}
return urlHandler?(url) ?? .systemAction
}
func handleDeepLink(url: URL) -> OpenURLAction.Result {
// Resolve federated URLs, then navigate.
navigate(to: .status(id: url.lastPathComponent))
return .handled
}
}extension View {
func withLinkRouter(_ router: RouterPath) -> some View {
self
.environment(
\.openURL,
OpenURLAction { url in
router.handle(url: url)
}
)
.onOpenURL { url in
router.handleDeepLink(url: url)
}
}
}@Environment(\.openURL) via OpenURLAction.Task.Universal links let iOS open your app when a user taps a standard HTTPS URL, with no custom scheme required. They require server-side configuration and an Associated Domains entitlement.
Host a JSON file at https://example.com/.well-known/apple-app-site-association (no file extension, served with Content-Type: application/json):
{
"applinks": {
"details": [
{
"appIDs": ["TEAMID.com.example.app"],
"components": [
{ "/": "/items/*", "comment": "Match item detail paths" },
{ "/": "/profile/*" }
]
}
]
}
}Key rules:
https://app-site-association.cdn-apple.com/a/v1/example.com to verify the cached version.components (modern) over the legacy paths array.In your app's .entitlements file (or Signing & Capabilities in Xcode), add:
com.apple.developer.associated-domains = [
"applinks:example.com",
"applinks:www.example.com"
]For development/testing, prefix with applinks:example.com?mode=developer to bypass the CDN cache.
Use .onOpenURL for link-based launches and onContinueUserActivity for NSUserActivity-based handoff:
@main
struct MyApp: App {
@State private var router = Router()
var body: some Scene {
WindowGroup {
ContentView()
.environment(router)
.onOpenURL { url in
router.handle(url: url)
}
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { activity in
guard let url = activity.webpageURL else { return }
router.handle(url: url)
}
}
}
}Custom URL schemes (e.g., myapp://) let other apps or websites open your app. They do not require server configuration but offer no fallback if the app is not installed.
Add CFBundleURLTypes to your target's Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
<key>CFBundleURLName</key>
<string>com.example.myapp</string>
</dict>
</array>.onOpenURL { url in
// url.scheme == "myapp"
// url.host == "items", url.pathComponents for routing
guard url.scheme == "myapp" else { return }
router.handle(url: url)
}Prefer universal links over custom schemes for publicly shared links — they provide a better UX (web fallback) and are more secure (domain-verified).
Handoff lets users start an activity on one device and continue it on another. SwiftUI provides .onContinueUserActivity and .userActivity modifiers.
struct ItemDetailView: View {
let item: Item
var body: some View {
ScrollView { /* content */ }
.userActivity("com.example.viewItem") { activity in
activity.title = item.title
activity.isEligibleForHandoff = true
activity.isEligibleForSearch = true
activity.targetContentIdentifier = item.id.uuidString
activity.webpageURL = URL(string: "https://example.com/items/\(item.id)")
}
}
}.onContinueUserActivity("com.example.viewItem") { activity in
guard let id = activity.targetContentIdentifier else { return }
router.navigate(to: .item(id: id))
}Key rules:
Info.plist under NSUserActivityTypes.isEligibleForHandoff = true and optionally isEligibleForSearch / isEligibleForPrediction.webpageURL as fallback when the app is not installed on the receiving device.skills
accessorysetupkit
references
activitykit
references
adattributionkit
references
alarmkit
references
app-clips
app-intents
references
app-store-optimization
app-store-review
apple-on-device-ai
appmigrationkit
references
audioaccessorykit
references
authentication
references
avkit
references
background-processing
references
browserenginekit
references
callkit
references
carplay
references
cloudkit
references
contacts-framework
references
core-bluetooth
references
core-data
core-motion
references
core-nfc
references
coreml
references
cryptokit
references
cryptotokenkit
references
debugging-instruments
device-integrity
references
dockkit
references
energykit
references
eventkit
references
financekit
references
focus-engine
gamekit
references
healthkit
references
homekit
references
ios-accessibility
ios-localization
ios-networking
ios-simulator
references
mapkit
metrickit
references
musickit
references
natural-language
references
paperkit
references
passkit
references
pdfkit
references
pencilkit
references
permissionkit
references
photokit
push-notifications
realitykit
references
relevancekit
references
scenekit
references
sensorkit
references
speech-recognition
spritekit
references
storekit
swift-api-design-guidelines
swift-architecture
swift-charts
references
swift-codable
swift-concurrency
swift-formatstyle
swift-language
swift-security
references
swift-testing
swiftdata
swiftlint
swiftui-animation
swiftui-gestures
references
swiftui-layout-components
swiftui-liquid-glass
references
swiftui-patterns
swiftui-performance
swiftui-uikit-interop
swiftui-webkit
tabletopkit
references
tipkit
references
vision-framework
weatherkit
references
widgetkit
references