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