iOS 11中canOpenURL返回false时如何屏蔽不必要的错误日志?
解决iOS 11中
canOpenURL返回false时的错误日志问题 我太懂这种被无用日志刷屏的烦躁了!在iOS 11里用canOpenURL检查应用是否安装,哪怕已经把对应Scheme加入LSApplicationQueriesSchemes白名单,只要返回false就会冒出那串OSStatus error -10814的日志,确实很头疼。给你两个靠谱的解决办法:
方法一:改用openURL:options:completionHandler:(推荐)
苹果在iOS 10之后推出的这个API,不仅是官方推荐的打开外部应用的方式,还能彻底避免那个烦人的错误日志。它不需要先调用canOpenURL判断,直接尝试打开目标URL,然后通过回调返回结果:
NSURL *targetAppURL = [NSURL URLWithString:@"XXXX://XXXXXXXXXXXXX"]; [[UIApplication sharedApplication] openURL:targetAppURL options:@{} completionHandler:^(BOOL success) { if (!success) { // 处理应用未安装或无法打开的逻辑 NSLog(@"目标应用未安装或无法打开"); } }];
注意:即使跳过
canOpenURL的前置判断,直接调用openURL:options:completionHandler:,也不会输出那个错误日志,系统会在回调里返回success为false,完全满足你的需求。
方法二:过滤系统日志(兼容老代码场景)
如果你的项目里已经大量使用canOpenURL,不想大规模修改代码,可以通过重定向NSLog来过滤掉特定的错误日志。具体做法是在App启动时替换NSLog的实现,过滤掉包含目标错误信息的日志:
#import <objc/runtime.h> #import <dlfcn.h> // 保存原始NSLog的指针 static void (*originalNSLog)(NSString *format, ...); // 自定义NSLog实现 void customNSLog(NSString *format, ...) { va_list args; va_start(args, format); NSString *logContent = [[NSString alloc] initWithFormat:format arguments:args]; va_end(args); // 过滤掉包含指定错误内容的日志 BOOL isCanOpenURLError = ([logContent containsString:@"-canOpenURL: failed for URL"] && [logContent containsString:@"OSStatus error -10814"]); if (!isCanOpenURLError) { // 不是目标错误日志,调用原始NSLog输出 originalNSLog("%@", logContent); } } // 在AppDelegate的`application:didFinishLaunchingWithOptions:`中添加以下代码 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 替换NSLog的实现 originalNSLog = dlsym(RTLD_DEFAULT, "NSLog"); Method originalMethod = class_getClassMethod([NSObject class], @selector(NSLog:)); Method customMethod = class_getClassMethod([NSObject class], @selector(customNSLog:)); method_exchangeImplementations(originalMethod, customMethod); return YES; }
这个方法的优点是不需要修改原有业务代码,缺点是依赖系统日志的格式,如果苹果后续调整日志内容,可能需要更新过滤条件。
内容的提问来源于stack exchange,提问作者am449
相关产品推荐
相关产品推荐

