번개애비의 라이프스톼일
Swift 5.x UIAlertController를 이용하여 앱 설정 화면으로 전환시키기 본문
Swift 로 iOS 개발을 하다보면, 알림권한을 받아와 푸시메시지를 보내거나 내부적인 처리를 위해서 사용하는 경우가 많다.
알림 권한을 피치못한 사정으로 인해 반드시 사용해야하는 경우 UIAlert을 통해 앱 설정화면으로 이동시켜 사용자에게 보다 친화적인 서비스개발이 가능하다.
아래 스크린샷은 앱 초기 실행 혹은 포그라운드로 되돌아올때 나타나는 화면예시다.
알림권한 뿐만 아니라 블루투스, 위치권한등도 응용이 충분히 가능하다.


아래는 알림설정을 할 수 있도록 유도하는 UIAlert 소스코드이다.
참고로 싱글톤으로 사용되거나, 부득이하게 ViewController가 아닌 Delegate에 넣어서 사용할 수 있도록, Alert 메시지의 present 처리를 조금 다르게 작성되어 있다.
(원래는 present(alert, animated: false, completion: nil) 이런식으로 아주 간단하게 쓸수 있는데 말이다.)
let NOTIalert: UIAlertController = UIAlertController(title: "알림설정이 필요합니다", message: "알림을 '허용'해야 서비스이용이 가능합니다.", preferredStyle: .alert)
let NOTIaction: UIAlertAction = UIAlertAction(title: "설정 변경", style: .default, handler: { (ACTION) in
    //앱 강제 종료
    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1), execute: {exit(0)})
    //앱 설정 이동
    let NOTIurl = NSURL(string:"App-prefs:root=NOTIFICATIONS_ID")! as URL
    UIApplication.shared.open(NOTIurl)
})
NOTIalert.addAction(NOTIaction)
DispatchQueue.main.async{
    if #available(iOS 13, *) {
        UIApplication.shared.windows.first { $0.isKeyWindow }?.rootViewController?.present(NOTIalert, animated: true, completion: nil)
    } else {
        UIApplication.shared.keyWindow?.rootViewController?.present(NOTIalert, animated: true, completion: nil)
    }
}
사용자가 Alert 메시지를 보고 설정 변경을 누르면, 자동으로 앱 설정화면으로 이동된다.
코드 중간에 아주아주 괴랄한 방법으로 앱 강제종료 기능이 존재한다. 이러한 조치는 반드시 알림권한이 설정되어야 하는것이기도 하며, 사용자가 설정화면으로 전환되었다가 다시 앱의 포그라운드로 돌아올때 중간에 시작되는 로직의 구분을 하기 귀찮(?)기 때문에 강제종료를 예약해둔것이다.
앱 설정화면에 대한 URL 정보들은 아래와 같다.
| 설정 화면 종류 | 오래된 Swift 혹은 Obj-C | Swift 3 | 
| About | prefs:root=General&path=About | App-prefs:root=General&path=About | 
| Accessibility | prefs:root=General&path=ACCESSIBILITY | App-prefs:root=General&path=ACCESSIBILITY | 
| Account Settings | prefs:root=ACCOUNT_SETTINGS | App-prefs:root=ACCOUNT_SETTINGS | 
| Airplane Mode | prefs:root=AIRPLANE_MODE | App-prefs:root=AIRPLANE_MODE | 
| Autolock iOS < 10 | prefs:root=General&path=AUTOLOCK | App-prefs:root=General&path=AUTOLOCK | 
| Auto-Lock iOS > 10 | prefs:root=DISPLAY&path=AUTOLOCK | App-prefs:root=DISPLAY&path=AUTOLOCK | 
| Apple Pay / Wallet | shoebox://url-scheme | shoebox://url-scheme | 
| Battery | prefs:root=BATTERY_USAGE | App-prefs:root=BATTERY_USAGE | 
| Brightness | prefs:root=Brightness | App-prefs:root=Brightness | 
| Bluetooth iOS < 9 | prefs:root=General&path=Bluetooth | App-prefs:root=General&path=Bluetooth | 
| Bluetooth iOS > 9 | prefs:root=Bluetooth | App-prefs:root=Bluetooth | 
| Castle | prefs:root=CASTLE | App-prefs:root=CASTLE | 
| Cellular Usage | prefs:root=General&path=USAGE/CELLULAR_USAGE | App-prefs:root=General&path=USAGE/CELLULAR_USAGE | 
| Configuration List | prefs:root=General&path=ManagedConfigurationList | App-prefs:root=General&path=ManagedConfigurationList | 
| Date and Time | prefs:root=General&path=DATE_AND_TIME | App-prefs:root=General&path=DATE_AND_TIME | 
| Do not disturb | prefs:root=General&path=DO_NOT_DISTURB | App-prefs:root=General&path=DO_NOT_DISTURB | 
| Facetime | prefs:root=FACETIME | App-prefs:root=FACETIME | 
| General | prefs:root=General | App-prefs:root=General | 
| Internet Tethering | prefs:root=INTERNET_TETHERING | App-prefs:root=INTERNET_TETHERING | 
| iTunes | prefs:root=MUSIC | App-prefs:root=MUSIC | 
| iTunes Equalizer | prefs:root=MUSIC&path=EQ | App-prefs:root=MUSIC&path=EQ | 
| iTunes Volume | prefs:root=MUSIC&path=VolumeLimit | App-prefs:root=MUSIC&path=VolumeLimit | 
| Keyboard | prefs:root=General&path=Keyboard | App-prefs:root=General&path=Keyboard | 
| Deeper in Keyboard | prefs:root=General&path=Keyboard/KEYBOARDS | App-prefs:root=General&path=Keyboard/KEYBOARDS | 
| Lang International | prefs:root=General&path=INTERNATIONAL | App-prefs:root=General&path=INTERNATIONAL | 
| Location Services | prefs:root=Privacy&path=LOCATION | App-Prefs:root=Privacy&path=LOCATION | 
| Mobile Data | prefs:root=MOBILE_DATA_SETTINGS_ID | |
| Network | prefs:root=General&path=Network | App-prefs:root=General&path=Network | 
| Nike iPod | prefs:root=NIKE_PLUS_IPOD | App-prefs:root=NIKE_PLUS_IPOD | 
| Notes | prefs:root=NOTES | App-prefs:root=NOTES | 
| Notifications ID | prefs:root=NOTIFICATIONS_ID | App-prefs:root=NOTIFICATIONS_ID | 
| Passcode / Touch ID | prefs:root=TOUCHID_PASSCODE | App-prefs:root=TOUCHID_PASSCODE | 
| Passbook | prefs:root=PASSBOOK | App-prefs:root=PASSBOOK | 
| Phone | prefs:root=Phone | App-prefs:root=Phone | 
| Photo Camera Roll | prefs:root=Photos | App-prefs:root=Photos | 
| Privacy | Prefs:root=Privacy | App-prefs:root=Privacy | 
| Profiles & Device Management | Prefs:root=General&path=ManagedConfigurationList | App-prefs:root=General&path=ManagedConfigurationList | 
| Reset | prefs:root=General&path=Reset | App-prefs:root=General&path=Reset | 
| Ringtone | prefs:root=Sounds&path=Ringtone | App-prefs:root=Sounds&path=Ringtone | 
| Siri | prefs:root=SIRI | App-prefs:root=SIRI | 
| Safari | prefs:root=Safari | App-prefs:root=Safari | 
| Siri iOS < 10? | prefs:root=General&path=Assistant | App-prefs:root=General&path=Assistant | 
| Siri iOS > 10? | prefs:root=SIRI | App-prefs:root=SIRI | 
| Sounds | prefs:root=Sounds | App-prefs:root=Sounds | 
| Software Update | prefs:root=General&path=SOFTWARE_UPDATE_LINK | App-prefs:root=General&path=SOFTWARE_UPDATE_LINK | 
| Storage & Backup | prefs:root=CASTLE&path=STORAGE_AND_BACKUP | App-prefs:root=CASTLE&path=STORAGE_AND_BACKUP | 
| Store | prefs:root=STORE | App-pref:root=STORE | 
| prefs:root=TWITTER | App-prefs:root=TWITTER | |
| Usage | prefs:root=General&path=USAGE | App-prefs:root=General&path=USAGE | 
| Video | prefs:root=VIDEO | App-prefs:root=VIDEO | 
| VPN | prefs:root=General&path=Network/VPN | App-prefs:root=General&path=Network/VPN | 
| Wallpaper | prefs:root=Wallpaper | App-prefs:root=Wallpaper | 
| WIFI | prefs:root=WIFI | App-prefs:root=WIFI | 
위 방식으로 아주 다양한 전환이 가능한데, 조금만 더 응용하자면, 자신의 앱이외에 다른앱의 설정화면으로도 이동이 가능하다.
다른앱의 Bundle Identifier를 이용하면 된다. 아래 예시는 인스타그램의 앱 설정화면으로 이동하는 예시이다.
// For iOS 13.* 
UIApplication.shared.openURL(NSURL(string:"App-prefs:root=NOTIFICATIONS_ID&path=com.burbn.instagram")! as URL)
애플에서 권한설정을 묻는 이유는 당연히 사용자가 결정할 수 있는 권리를 제공한것이기 때문에,
부득이한 상황이 아니라면 이런 괴랄한 방법은 지양하는것이 좋다.
'IT' 카테고리의 다른 글
| GoLang 과 Javascript 를 이용해서 데이터베이스를 실시간 트리거(감시?) 하기 (0) | 2021.09.29 | 
|---|---|
| Swift에서 멀티스레드로 함수를 실행하고 완료시 다른함수 호출하기 (0) | 2021.09.16 | 
| ArduinoBLE ibeacon의 uuid 와 major, minor, RSSI 스캔하기 (0) | 2021.09.09 | 
| 아이폰 in-app browser(인앱브라우저)별 user agent (0) | 2021.07.05 | 
| MariaDB의 디렉토리를 수정하여 설치 (CentOS 7.x 기준) (0) | 2021.06.24 | 
 
													 
													 
													