Summary
OMApi (Obj-C) and OrganicMaps (Swift) currently round-trip data through custom URL schemes (OMApiExampleCapitals://pin?…). Every time Organic Maps hands control back, iOS shows an "Open in ?" confirmation dialog. Universal Links (https://yourdomain.com/…) would skip that dialog and feel native. The library has no support for them today.
This is an additive enhancement — custom URL schemes should remain supported for small/hobbyist callers without their own domain.
Current state
+[OMApi detectBackUrlScheme] (and the Swift equivalent) reads the first CFBundleURLScheme from CFBundleURLTypes and passes it as backurl=.
- Callbacks arrive in
application(_:open:options:) and are parsed by +[OMApi pinFromUrl:] / OrganicMaps.pin(from:).
Universal Links use a different delegate hook (application(_:continue:restorationHandler:) with NSUserActivity of type NSUserActivityTypeBrowsingWeb) and a different discovery mechanism (applinks: entitlement + apple-app-site-association file).
Required changes
Library API additions
Obj-C:
@interface OMApi (UniversalLinks)
/// Opt-in universal-link prefix. Example: @"https://example.com/om-callback".
/// When set, this is passed as `backurl=` instead of the auto-detected custom scheme.
+ (void)setCallbackUniversalLinkPrefix:(nullable NSString *)urlPrefix;
+ (nullable OMPin *)pinFromUserActivity:(nonnull NSUserActivity *)userActivity;
@end
Swift:
extension OrganicMaps {
/// Opt-in universal-link prefix; nil → fall back to custom URL scheme.
static var callbackUniversalLinkPrefix: String? { get set }
static func pin(from userActivity: NSUserActivity) -> OMPin?
}
When callbackUniversalLinkPrefix is set, backurl=https://example.com/om-callback is sent to Organic Maps. When unset, behaviour is identical to today.
Documentation
The README needs a new section explaining:
- Caller must add
com.apple.developer.associated-domains entitlement with applinks:example.com.
- Caller must serve a valid AASA file at
https://example.com/.well-known/apple-app-site-association with the right team-prefixed app ID.
- iOS's failure mode is "open the URL in Safari", so the page at the callback prefix should at minimum redirect to the App Store listing for the calling app.
- The custom URL scheme path remains the default for callers without a domain.
Example app
Add a third example, or a build flag in the existing one, that demonstrates the universal-link flow.
Dependency on Organic Maps
A small change is required on the Organic Maps iOS side for HTTPS callbacks to actually go to the caller's app instead of Safari: MapViewController.goBack (iphone/Maps/UI/Map/MapViewController.mm:1068-1073) currently calls openURL:options:@{} — needs to pass UIApplicationOpenURLOptionUniversalLinksOnly: @YES with a fallback when routing fails.
Filed separately on organicmaps/organicmaps if needed (covered as part of the API round-trip issue: organicmaps/organicmaps#12802).
Why bother
- No "Open in ?" system dialog on the return trip — matches the friction-free MAPS.ME-era UX.
- Custom URL schemes are increasingly restricted on iOS (declared queries, prompts on
openURL); Universal Links are Apple's recommended approach for app-to-app handoff.
Out of scope
- Removing custom URL scheme support. Many callers don't have a domain — the two should coexist.
Summary
OMApi(Obj-C) andOrganicMaps(Swift) currently round-trip data through custom URL schemes (OMApiExampleCapitals://pin?…). Every time Organic Maps hands control back, iOS shows an "Open in ?" confirmation dialog. Universal Links (https://yourdomain.com/…) would skip that dialog and feel native. The library has no support for them today.This is an additive enhancement — custom URL schemes should remain supported for small/hobbyist callers without their own domain.
Current state
+[OMApi detectBackUrlScheme](and the Swift equivalent) reads the firstCFBundleURLSchemefromCFBundleURLTypesand passes it asbackurl=.application(_:open:options:)and are parsed by+[OMApi pinFromUrl:]/OrganicMaps.pin(from:).Universal Links use a different delegate hook (
application(_:continue:restorationHandler:)withNSUserActivityof typeNSUserActivityTypeBrowsingWeb) and a different discovery mechanism (applinks:entitlement +apple-app-site-associationfile).Required changes
Library API additions
Obj-C:
Swift:
When
callbackUniversalLinkPrefixis set,backurl=https://example.com/om-callbackis sent to Organic Maps. When unset, behaviour is identical to today.Documentation
The README needs a new section explaining:
com.apple.developer.associated-domainsentitlement withapplinks:example.com.https://example.com/.well-known/apple-app-site-associationwith the right team-prefixed app ID.Example app
Add a third example, or a build flag in the existing one, that demonstrates the universal-link flow.
Dependency on Organic Maps
A small change is required on the Organic Maps iOS side for HTTPS callbacks to actually go to the caller's app instead of Safari:
MapViewController.goBack(iphone/Maps/UI/Map/MapViewController.mm:1068-1073) currently callsopenURL:options:@{}— needs to passUIApplicationOpenURLOptionUniversalLinksOnly: @YESwith a fallback when routing fails.Filed separately on
organicmaps/organicmapsif needed (covered as part of the API round-trip issue: organicmaps/organicmaps#12802).Why bother
openURL); Universal Links are Apple's recommended approach for app-to-app handoff.Out of scope