1. 程式人生 > >iOS10跳轉系統設定、WIFI、藍芽...

iOS10跳轉系統設定、WIFI、藍芽...

iOS10跳轉系統設定、WIFI、藍芽…

iOS自我們熟悉以來,就一直與Android有著不一樣的體驗,
系統更加流暢,使用更加舒適,
同時較高與Android的價格也導致了它的特殊性,
iOS系統的封閉和很多許可權的限制導致了我們在開發的時候經常會遇到很多無法條件無法實現
就比如iOS10以前,我們開發的應用想要跳轉到系統設定,跳轉到藍芽,跳轉到WIFI…
iOS開發工程師們都很熟悉,系統給我們提供了一套URL,我們只要使用這一套就OK了
在iOS10以前,
可能會用到的這些

蜂窩網路:prefs:root=MOBILE_DATA_SETTINGS_ID
Wi-Fi:prefs:root=WIFI
定位服務:prefs:root=LOCATION_SERVICES
個人熱點:prefs:root=INTERNET_TETHERING
關於本機:prefs:root=General
&path=About 輔助功能:prefs:root=General&path=ACCESSIBILITY 飛航模式:prefs:root=AIRPLANE_MODE 鎖定:prefs:root=General&path=AUTOLOCK 亮度:prefs:root=Brightness 藍芽:prefs:root=Bluetooth 時間設定:prefs:root=General&path=DATE_AND_TIME FaceTime:prefs:root=FACETIME 設定:prefs:root=General 設定 prefs:root=SETTING 定位服務 prefs:root=LOCATION_SERVICES 鍵盤設定:prefs:root=General
&path=Keyboard iCloud:prefs:root=CASTLE iCloud備份:prefs:root=CASTLE&path=STORAGE_AND_BACKUP 語言:prefs:root=General&path=INTERNATIONAL 定位:prefs:root=LOCATION_SERVICES 音樂:prefs:root=MUSIC


我們在想要跳轉的時候只要簡單的幾行程式碼

NSURL *url = [NSURL URLWithString:@"prefs:root=Bluetooth"];
if ([[UIApplication
sharedApplication]canOpenURL:url]) { [[UIApplication sharedApplication]openURL:url]; }

但是萬惡的iOS10來了,就一切都變了
以上的全部都失效了,一切都沒有用了
無論是prefs:root=Bluetooth 還是 Prefs:root=Bluetooth 都沒有用
那麼怎麼跳轉呢?
但是網上面又有說Prefs:root=Bluetooth 這種是可以的?
後來經測試這個只在Widge裡有效,App中無效!

於是有大神想到了私有的API

NSURL*url=[NSURL URLWithString:@"Prefs:root=Bluetooth"];
Class LSApplicationWorkspace = NSClassFromString(@"LSApplicationWorkspace");
[[LSApplicationWorkspace performSelector:@selector(defaultWorkspace)] performSelector:@selector(openSensitiveURL:withOptions:) withObject:url withObject:nil];

因為是私有的API,可能會過不了稽核,於是又有了下面的變種
利用ASCII值進行拼裝組合方法。這樣可繞過稽核。

SignedByte classOneByte[] = {0x4c,0x53,0x41,0x70,0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x57,0x6f,0x72,0x6b,0x73,0x70,0x61,0x63,0x65};
NSString *classOneString = [[NSString alloc] initWithData:[NSData dataWithBytes:classOneByte length:sizeof(classOneByte)] encoding:NSASCIIStringEncoding];
Class classOne = NSClassFromString(classOneString);

SignedByte selectOneByte[] = {0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x57,0x6f,0x72,0x6b,0x73,0x70,0x61,0x63,0x65};
NSString *selectOneString = [[NSString alloc] initWithData:[NSData dataWithBytes:selectOneByte length:sizeof(selectOneByte)] encoding:NSASCIIStringEncoding];
SEL selectOne = NSSelectorFromString(selectOneString);

if ([classOne respondsToSelector:selectOne]) {
     Class classTwo = [classOne performSelector:selectOne];

     SignedByte selectTwoByte[] = {0x6f,0x70,0x65,0x6e,0x53,0x65,0x6e,0x73,0x69,0x74,0x69,0x76,0x65,0x55,0x52,0x4c,0x3a,0x77,0x69,0x74,0x68,0x4f,0x70,0x74,0x69,0x6f,0x6e,0x73,0x3a};
     NSString *selectTwoString = [[NSString alloc] initWithData:[NSData dataWithBytes:selectTwoByte length:sizeof(selectTwoByte)] encoding:NSASCIIStringEncoding];
     SEL selectTwo = NSSelectorFromString(selectTwoString);

     SignedByte urlByte[] = {0x50,0x72,0x65,0x66,0x73,0x3a,0x72,0x6f,0x6f,0x74,0x3d,0x42,0x6c,0x75,0x65,0x74,0x6f,0x6f,0x74,0x68};
     NSString *urlString = [[NSString alloc] initWithData:[NSData dataWithBytes:urlByte length:sizeof(urlByte)] encoding:NSASCIIStringEncoding];
      NSURL *url = [NSURL URLWithString:urlString];

      if ([classTwo respondsToSelector:selectTwo]) {
          [classTwo performSelector:selectTwo withObject:url withObject:nil];
      }
}

是不是完全看不懂?其實就是把那些字串,那些類,那些方法都使用ASCII進行了轉換而已…

但是熱更新事件來的很突然,稽核系統開始對於respondsToSelector:和performSelector:有了一點關注,擔心上面的方法會失效,畢竟是私有,不靠譜,
那麼有沒有靠譜的不是私有的?

答案是有!
千百次嘗試,終於找到了!!

Wi-Fi: App-Prefs:root=WIFI
藍芽: App-Prefs:root=Bluetooth
蜂窩行動網路: App-Prefs:root=MOBILE_DATA_SETTINGS_ID
個人熱點: App-Prefs:root=INTERNET_TETHERING
運營商: App-Prefs:root=Carrier
通知: App-Prefs:root=NOTIFICATIONS_ID
通用: App-Prefs:root=General
通用-關於本機: App-Prefs:root=General&path=About
通用-鍵盤: App-Prefs:root=General&path=Keyboard
通用-輔助功能: App-Prefs:root=General&path=ACCESSIBILITY
通用-語言與地區: App-Prefs:root=General&path=INTERNATIONAL
通用-還原: App-Prefs:root=Reset
牆紙: App-Prefs:root=Wallpaper
Siri: App-Prefs:root=SIRI
隱私: App-Prefs:root=Privacy
定位: App-Prefs:root=LOCATION_SERVICES
Safari: App-Prefs:root=SAFARI
音樂: App-Prefs:root=MUSIC
音樂-均衡器: App-Prefs:root=MUSIC&path=com.apple.Music:EQ
照片與相機: App-Prefs:root=Photos
FaceTime: App-Prefs:root=FACETIME
...

之前的prefs或者Prefs 替換成最新的 App-Prefs
當前iOS10全部支援!親測!不是私有方法!不是私有方法!不是私有方法!
過稽核不是問題!全部支援!
其他的不用說啦!炫耀去吧……

再補充一個跳轉到應用設定

NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication]canOpenURL:url]) {
    [[UIApplication sharedApplication]openURL:url];
}