2011-08-30 11 views
7

Prima di fare un openUrl: per avviare un'app che dovrebbe richiamare la mia app (come un'app che agisce in base alla specifica), come posso controllare a livello di codice che la mia callback dell'applicazione funzioni, prima di chiamare l'altra app?la mia app risponderà a uno schema di URL?

risposta

12

Questa è la mia soluzione attuale:

- (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; 
} 

La limitazione è che stiamo verificando che questa applicazione registrato per il programma e alcuni applicazione risponde a tale URL.

AFAIK ciò non garantisce che l'applicazione sia il rispondente effettivo per tale schema (nel caso in cui un'altra app sia stata registrata per tale schema).

Da quello che ho provato, sembra che iOS apra la prima app installata per ogni schema di URL unico.

+0

Ah, ora ho capito un po 'meglio. Non c'è modo di sapere con certezza prima di aprire un URL cosa succederà quando apri quell'URL. Non esiste un'interfaccia LaunchServices su iOS per la query. –

+0

Ho deciso di accettare la mia risposta poiché sembra che questo sia il miglior metodo disponibile (anche se non è affidabile al 100%). –

0

Ecco come ho risolto a 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) 
0

Una soluzione più semplice:

+ (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]; 
} 
Problemi correlati