Before doing a openUrl:
to开发者_StackOverflow中文版 launch an app that should callback my app (like an app that acts according to the x-callback-url specification), how can I programmatically check that my application callback is working, before calling the other app?
This is my current solution:
- (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;
}
The limitation is that we are checking that this app registered for the scheme and some application responds to that url.
AFAIK this does not guarantee that your application is the actual responder for that scheme (in the case where another app also registered for that scheme).
From what I tried, it seems that iOS opens the first installed app for each unique url scheme.
Here is how I solved it in 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)
A simpler solution:
+ (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];
}
精彩评论