iOS10 openURL方法跳轉到設置界面


問題

在iOS10之前,跳轉到系統設置界面的某個指定界面的方式如下:

//打開定位服務界面 NSURL*url=[NSURL URLWithString:@"prefs:root=Privacy&path=LOCATION"]; if ([[UIApplication sharedApplication] canOpenURL:url]) { [[UIApplication sharedApplication] openURL:url]; };

但是在iOS10上,調用canOpenURL:打開系統設置界面時控制台會報如下錯誤,並且無法跳轉:

-canOpenURL: failed for URL: "Prefs:root=Privacy&path=LOCATION" - error: "The operation couldn’t be completed. (OSStatus error -10814.)"

原因是iOS10只允許如下方式跳轉到設置里自己app的界面,對跳轉到其他界面做了限制:

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];

解決方法

可以使用 MobileCoreServices.framework 里的私有API:

- (BOOL)openSensitiveURL:(id)arg1 withOptions:(id)arg2;

頭文件參考: LSApplicationWorkspace.h

使用方法:

//注意首字母改成了大寫,prefs->Prefs NSURL*url=[NSURL URLWithString:@"Prefs:root=Privacy&path=LOCATION"]; Class LSApplicationWorkspace = NSClassFromString(@"LSApplicationWorkspace"); [[LSApplicationWorkspace performSelector:@selector(defaultWorkspace)] performSelector:@selector(openSensitiveURL:withOptions:) withObject:url withObject:nil];

MobileCoreServices.framework 不是私有庫,所以直接使用 performSelector: 即可調用私有API。

注意

  • iOS10的系統URLScheme改成了首字母大寫,使用小寫的方式會無法打開。
  • 使用私有API的app無法通過App Store審核。你也可以嘗試把私有類名和selector字符串混淆一下,繞過審核。例如 這位仁兄 用ASCII混淆的方法:
- (UIView *)statusBarView { UIView *statusBar = nil; NSData *data = [NSData dataWithBytes:(unsigned char []){0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x61, 0x72} length:9]; NSString *key = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; id object = [UIApplication sharedApplication]; if ([object respondsToSelector:NSSelectorFromString(key)]) { statusBar = [object valueForKey:key]; } return statusBar; }

不過,還是不建議使用私有API,因為它是不可靠的。也許某天蘋果就把它移除了。

 

以下是摘抄自GitHub上的一段可以通過Google私有文件


2down vote
+100

Point 1: LSApplicationWorkspace is private api, so if you use this and will upload your app to app store, it will get rejected.

Point 2: If you are having any in-house app and still want to use this in your app, then below is the way to use it.

  1. Add MobileCoreServices Framework in your bundle
  2. Create LSApplicationWorkspace.h file with the code exactly same as the code provided at here "https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/MobileCoreServices.framework/LSApplicationWorkspace.h".
  3. Now add this LSApplicationWorkspace.h file into your bundle
  4. Create bridging header for your swift app
  5. Add #import "LSApplicationWorkspace.h" in your bridging header
  6. Now add import MobileCoreServices in your current file and add your code let test = LSApplicationWorkspace.defaultWorkSpace(), it will work fine.

NOTE: For using any private header, you must have to include its .h file into your code. You can find any private headers by searching "runtime headers" in google. You will get all runtime headers. And to include that header in your swift code, you need to go via bridging-header.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM