【问题标题】:How do I interrogate the current app's URL scheme programmatically?如何以编程方式查询当前应用的 URL 方案?
【发布时间】:2016-07-25 21:23:31
【问题描述】:
我的 iOS 应用有 50 多个目标,每个目标都有自己的自定义 URL 方案。我需要检测来自 webview 的请求是否与当前运行的应用程序的方案匹配。为了做到这一点,我需要能够从代码中查询当前应用程序的 URL 方案。
类似的问题涉及尝试询问其他应用程序以发现其 URL 方案,这似乎是不可能的。我需要在我的应用中为我自己的应用找出方案。
我希望避免为 URL 方案设置另一个 plist 值并将其包含在目标中。
有没有办法获取当前应用的URL scheme?
【问题讨论】:
标签:
ios
objective-c
swift
url
url-scheme
【解决方案1】:
这是我想出的功能。
- (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;
}
【解决方案2】:
在 Swift 4 中:以编程方式从 Info.plist 获取自定义 url 方案的工作版本
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
}
(假设 urlTypes 和 urlSchemes 数组中只有一个元素,因此取第一个元素)。这是我的URL Scheme 的plist 条目
【解决方案3】:
Bundle swift 4 语法的扩展
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
}()
}