As described here to verify if an app is installed "some.bundle.id://" scheme and canOpenURL technique can be used.
However, I've discovered in SwiftUI 5 and iOS 14.1 that it doesn't always work, e.g.
// Works
UIApplication.shared.canOpenURL(URL(string: "com.garmin.connect.mobile://")!)
// Doesn't work
UIApplication.shared.canOpenURL(URL(string: "com.fitbit.FitbitMobile://")!)
I've found the error below in Mac's Console App log connected to iPhone. Looks like Fitbit app is blocking the queries:
default 12:03:34.339735-0700 2fahub -canOpenURL: failed for URL: "FitbitMobile://app" - error: "This app is not allowed to query for scheme fitbitmobile"
While in my Xcode's debug window I can see this:
2021-05-30 12:46:16.416998-0700 2fahub[588:100068] -canOpenURL: failed for URL: "com.fitbit.FitbitMobile://" - error: "The operation couldn’t be completed. (OSStatus error -10814.)"
In my app query permissions are set correctly
<key>LSApplicationQueriesSchemes</key>
<array>
<string>com.garmin.connect.mobile</string>
<string>com.fitbit.FitbitMobile</string>
</array>
What else can be used to make sure that it always works? Is there anything similar to Android's PackageManager API in iOS?
Update #1:
Actually the answer provided by Fitbit forum was correct. The scheme for Fitbit must be "fitbit://" and it's absolutely not clear why, given that bundle ID for this app is com.fitbit.FitbitMobile. 'fitbit' is not the app name, neither it's the whole bundle ID. In Garmin case I must use the whole bundle ID to make it working. Would be good to know what the rules really are here. What should I do if need to add more apps to verify?