мое приложение ответит на схему URL? - PullRequest
7 голосов
/ 30 августа 2011

Прежде чем выполнить openUrl:, чтобы запустить приложение, которое должно вызывать мое приложение (например, приложение, которое работает в соответствии со спецификацией x-callback-url ), как я могу программно проверить, что ответ моего приложения работает, прежде чем вызывать другое приложение?

Ответы [ 3 ]

12 голосов
/ 30 августа 2011

Это мое текущее решение:

- (BOOL) respondsToUrl:url
{
    BOOL schemeIsInPlist = NO; // find out if the sceme is in the plist file.
    NSBundle* mainBundle = [NSBundle mainBundle];
    NSArray* cfBundleURLTypes = [mainBundle objectForInfoDictionaryKey:@"CFBundleURLTypes"];
    if ([cfBundleURLTypes isKindOfClass:[NSArray class]] && [cfBundleURLTypes lastObject]) {
        NSDictionary* cfBundleURLTypes0 = [cfBundleURLTypes objectAtIndex:0];
        if ([cfBundleURLTypes0 isKindOfClass:[NSDictionary class]]) {
            NSArray* cfBundleURLSchemes = [cfBundleURLTypes0 objectForKey:@"CFBundleURLSchemes"];
            if ([cfBundleURLSchemes isKindOfClass:[NSArray class]]) {
                for (NSString* scheme in cfBundleURLSchemes) {
                    if ([scheme isKindOfClass:[NSString class]] && [url hasPrefix:scheme]) {
                        schemeIsInPlist = YES;
                        break;
                    }
                }
            }
        }
    }

    BOOL canOpenUrl = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString: url]];

    return schemeIsInPlist && canOpenUrl;
}

Ограничение заключается в том, что мы проверяем, что это приложение зарегистрировано для схемы, а некоторое приложение отвечает на этот URL.

AFAIK это не гарантирует, что ваше приложение является фактическим ответчиком для этой схемы (в случае, когда другое приложение также зарегистрировано для этой схемы).

Судя по тому, что я пробовал, iOS открывает первое установленное приложение для каждой уникальной схемы URL.

0 голосов
/ 03 июня 2016

Более простое решение:

+ (BOOL)isBundleURL:(NSURL *)url
{
    NSArray *urlTypes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"];
    NSArray *urlSchemes = [urlTypes.firstObject objectForKey:@"CFBundleURLSchemes"];
    return [urlSchemes containsObject:url.scheme];
}

+ (BOOL)respondsToURL:(NSURL *)url
{
    return [self isBundleURL:url] && [[UIApplication sharedApplication] canOpenURL:url];
}
0 голосов
/ 02 сентября 2015

Вот как я решил это в Swift:

var plistPath = NSBundle.mainBundle().pathForResource("Info", ofType: "plist")

var urlStuff = NSMutableDictionary(contentsOfFile: plistPath!)
var urlType = NSDictionary(objectsAndKeys: "com.appprefix.AppName", "CFBundleURLName", NSArray(object: "fb123456789"), "CFBundleURLSchemes")
urlStuff?.setObject(NSArray(object: urlType), forKey: "CFBundleURLTypes")
urlStuff?.writeToFile(plistPath!, atomically: true)
...