0
votes

I'm trying to check which default apps are installed on users phone.

I add to LSApplicationQueriesSchemes array strings with apps schemes names (for example "calc" for calculator), then I use this function to check:

func isAppInstalled(_ appName:String) -> Bool{

    let appScheme = "\(appName)://app"
    let appUrl = URL(string: appScheme)


    if UIApplication.shared.canOpenURL(appUrl! as URL){
        return true
    } else {
        return false
    }

}

and use it like

let result = isAppInstalled("calc")

but receive this error in console

-canOpenURL: failed for URL: "calc://app" - error: "The operation couldn’t be completed. (OSStatus error -10814.)"

which mean app is not installed. This code work for appstore app, books, apple tv, facetime, messages etc but not working with calculator, time app, compass, contacts, tips.

What is wrong with my code? Or maybe Apple changed this apps schemes? Tested on iOS 14 device.

2
Do you now that that URL is valid? Entering it in Safari just gives an error. Not all apps have a URL scheme. - Paulw11
@Paulw11 URL is valid.I try "calc://app" url in safari and on ios 14 it works perfect. - JustJunior

2 Answers

0
votes

This apps urls are not public, so you can't use them for opening this default apps from your own app and you can't check them with UIApplication.shared.canOpenURL

0
votes

This code work for appstore app, books, apple tv, facetime, messages etc but not working with calculator, time app, compass, contacts, tips.

From the -canOpenURL: docs:

...you must declare the URL schemes you pass to this method by adding the LSApplicationQueriesSchemes key to your app's Info.plist file. This method always returns false for undeclared schemes, whether or not an appropriate app is installed.

So, one possibility is that you haven't declared the failing apps in your Info.plist.

Also, Apple has long prevented apps from trying to query the device for too many installed apps because doing so is a sign that you're trying to create a "fingerprint" to track the device, or otherwise learn more than you should about the user, so your failures may simply be a matter of exceeding the current limit on calls to canOpenURL: with distinct URLs.