Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I interrogate the current app's URL scheme programmatically?

My iOS app has 50+ targets, each with their own custom URL scheme. I need to detect if a request from a webview matches the scheme of the currently running app. In order to do this, I need to be able to interrogate the current app's URL scheme(s) from code.

Similar questions deal with attempting to interrogate other apps to discover their URL schemes, which seems like it is not possible. I need to find the scheme out for my own app, from within my app.

I would like to avoid having to set another plist value to the URL scheme and including that with the target.

Is there any way to get the URL scheme of the current app?

like image 468
Crake Avatar asked Apr 05 '16 18:04

Crake


3 Answers

In Swift 4 : Working version of getting the custom url scheme from Info.plist programmatically

func externalURLScheme() -> String? {
        guard let urlTypes = Bundle.main.infoDictionary?["CFBundleURLTypes"] as? [AnyObject],
            let urlTypeDictionary = urlTypes.first as? [String: AnyObject],
            let urlSchemes = urlTypeDictionary["CFBundleURLSchemes"] as? [AnyObject],
            let externalURLScheme = urlSchemes.first as? String else { return nil }

        return externalURLScheme
    }

(with the assumption that there is only 1 element in the urlTypes and urlSchemes array, hence taking the first element). Here is my plist entry of URL Scheme

enter image description here

like image 107
Naishta Avatar answered Sep 20 '22 10:09

Naishta


Extension for Bundle swift 4 syntax

extension Bundle {

    static let externalURLSchemes: [String] = {
        guard let urlTypes = main.infoDictionary?["CFBundleURLTypes"] as? [[String: Any]] else {
            return []
        }

        var result: [String] = []
        for urlTypeDictionary in urlTypes {
            guard let urlSchemes = urlTypeDictionary["CFBundleURLSchemes"] as? [String] else { continue }
            guard let externalURLScheme = urlSchemes.first else { continue }
            result.append(externalURLScheme)
        }

        return result
    }()

}
like image 33
Evgeny Karev Avatar answered Sep 24 '22 10:09

Evgeny Karev


This is the function I came up with to accomplish this.

- (BOOL)doesMatchURLScheme:(NSString *)scheme {
  if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"]) {
    NSArray *urlTypes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"];
    for(NSDictionary *urlType in urlTypes)
    {
      if(urlType[@"CFBundleURLSchemes"])
      {
        NSArray *urlSchemes = urlType[@"CFBundleURLSchemes"];
        for(NSString *urlScheme in urlSchemes)
          if([urlScheme caseInsensitiveCompare:scheme] == NSOrderedSame)
            return YES;
      }

    }
  }
  return NO;
}
like image 30
Crake Avatar answered Sep 22 '22 10:09

Crake