번개애비의 라이프스톼일
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 |