안녕하세요.
iOS13 대응을 진행하면서 몇 가지 변경사항 및 급한 불을 끌 수 있는 이슈 방안에 대해서 적어보려고 합니다.
💡KVC 금지
*** Terminating app due to uncaught exception 'NSGenericException',
reason: 'Access to UISearchBar's _searchField ivar is prohibited. This is an application bug'
*** Terminating app due to uncaught exception 'NSGenericException',
reason: 'Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug'
KVC코드가 들어가있는 소스에 Xcode11로 빌드해보면 위와 같은 에러들이 나타나며 앱이 죽어 당황하셨을겁니다.
iOS 13으로 변경됨에 따라 시스템이 KVC를 통한 접근을 금지 하는듯 합니다.
예전엔 placeholder의 색을 변경시키고자할때 해당 객체의 키값을 찾아서 변경 가능했지만,
객체의 키값을 가지고 접근하는 방식을 금지하는 방향으로 바꼈습니다.
또, 아래와 같이 키를 가지고 접근하는 방법으로 작성했다면 iOS13에서는 앱이 죽는 현상이 나타나죠
//textField의 placeholder 색을 변경 방법
[textfield setValue:[UIColor red] forKeyPath:@"_placeholderLabel.textColor"];
//searchbar에서 textfield를 접근하는 방법
searchBar.value(forKey: "_searchField") as? UITextField { ... }
- 해결 방안
textField의 placeholder의 색을 변경 방법
대응 방안은 NSStringAttributedString을 활용.
textfield.attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholer
attributes:@{NSForegroundColorAttributeName: colorGray}];
[textfield setAttributedPlaceholder:textfield.attributedPlaceholder];
searchBar에서 textField를 접근 방법
대응 방안으로는 searchTextField가 iOS13에서 새로 생김으로써 더이상 key를 가지고 접근하지 않아도 됩니다.
let searchField = searchController.searchBar.searchTextField
💡다크모드 막기 (2가지)
다크모드 적용은 애플에서 강력하게 권고하는 사항이기 때문에 다크모드를 막는것은 일시적인 방법입니다.
대체로 2가지 방법이 있습니다.
1. plist에 추가
User Interface Style - Light 추가
2. 코드 삽입
if #available(iOS 13.0, *) {
self.window?.overrideUserInterfaceStyle = .light
}
💡다크모드 Detecting 방법
모드 전환이 된 순간에 호출되는 메서드!
-> unspecified, light, dark
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if #available(iOS 12.0, *) {
let userInterfaceStyle = traitCollection.userInterfaceStyle
print(userInterfaceStyle)
// unspecified, light, dark
}
}
💡StatusBar 접근 방법
이것 또한 아래와 같이 KVC로 접근해서 statusBar를 가져왔다고 하면 앱이 죽어 당황하셨을 겁니다.
//StatusBar를 가져오는 방법
UIApplication.shared.value(forKey: "statusBar") as? UIView
이러한 에러가 뜨죠
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'App called -statusBar or -statusBarWindow on UIApplication: this code must be changed as there's no longer a status bar or status bar window. Use the statusBarManager object on the window scene instead.'
이젠 iOS13부터는 statusBarManager 객체를 사용해서 접근해야 됩니다!
statusBarManager를 이용해서 statusBarFrame에 접근이 가능하므로써 Color를 조작할 수 있습니다.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if #available(iOS 13.0, *) {
let window = UIApplication.shared.windows.first { $0.isKeyWindow }
let statusBarManager = window?.windowScene?.statusBarManager
let statusBarView = UIView(frame: statusBarManager?.statusBarFrame ?? CGRect.zero)
statusBarView.backgroundColor = UIColor.red
window?.addSubview(statusBarView)
} else {
let statusBarView = UIApplication.shared.value(forKey: "statusBar") as? UIView
statusBarView?.backgroundColor = .blue
}
}
추가로 iOS 13에서 keywindow가 deprecated될 예정이기 때문에 windows로 대체 됩니다.
즉 기존에 window를 찾던 코드가 아래와 같이 변경될겁니다.
//before:
let window = UIApplication.shared.keyWindow
//after:
let window = UIApplication.shared.windows.first { $0.isKeyWindow }
💡Modal Presentation Style
iOS13부터 Modal presentation Style의 디폴트 값이 full screen이 아닌 'automaic'으로 변경되었습니다.
XCode11업데이트 후 13.0으로 빌드 해보니 모달 형식이 아래와 같이 'page sheet'형태로 나타나는걸 볼 수 있으셨을 겁니다.
그렇다면 automatic은 무엇일까요?
세로화면에선 page sheet, 가로화면에선 full screen형태의 타입을 나타냅니다!
즉, 디폴드가 automatic으로 바꼈으니 이전 버전의 모달형식처럼 full screen으로 바꿔야한다면 전체를 바꿔야합니다
vc.modalPresentationStyle = .fullScreen
💡Card-Style의 sheet modal 라이프 사이클
FirstVC와 SecondVC 두가지의 뷰컨트롤러가 있고, FirstVC에서 어떠한 버튼을 눌렀을때 SecondVC modal이 나타난다고 가정해보자.
- 기존의 fullscreen style의 모달 라이프 사이클
/* FullScreen Present */
-------------- [SecondVC : viewDidLoad] --------------
-------------- [FirstVC : viewWilldisappear] --------------
-------------- [SecondVC : viewWillAppear] --------------
-------------- [SecondVC : viewDidAppear] --------------
-------------- [FirstVC : viewDidDisappear] --------------
/* FullScreen Dismiss */
-------------- [SecondVC : viewWilldisappear] --------------
-------------- [FirstVC : viewWillAppear] --------------
-------------- [FirstVC : viewDidAppear] --------------
-------------- [SecondVC : viewDidDisappear] --------------
- sheet style의 모달 라이프 사이클
/* Sheet Present */
-------------- [SecondVC : viewDidLoad] --------------
-------------- [SecondVC : viewWillAppear] --------------
-------------- [SecondVC : viewDidAppear] --------------
/* Sheet Dismiss */
-------------- [SecondVC : viewWilldisappear] --------------
-------------- [SecondVC : viewDidDisappear] --------------
위의 그림에 볼 수 있듯이, 기존 fullscreen의 라이프 사이클과 다르게 firstVC에는 전혀 영향을 주지 않고 firstVC앞에 독립적으로 띄워지는 모달형식인걸 볼 수 있습니다.
디폴트값이 automatic인 만큼 가로 세로화면을 구현하는 앱일때 알아두시면 유용할 것 같습니다.
💡UISegmentedControl의 변화
iOS13에서 UIKit 구성요소 중 UISegmentedControl, UISwift, UIStepper, UISlider가 기존과 조금? 다르게 새로운 디자인으로 등장했습니다.
그 중 UISegmentedControl이 iOS13에서 변화가 생겼습니다. iOS7부터 등장한 "tintColor"로는 더 이상 Color를 변경 할 수 없습니다.
"SelectedSegmentTintColor"라는 새로운 속성을 사용하면 슬라이딩 제어의 색상을 변경할 수 있습니다.
segmented.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.white],
for: .selected)
if #available(iOS 13.0, *) {
segmented.selectedSegmentTintColor = .blue
} else {
segmented.tintColor = .blue
}
💡App Store Review Guideline
2020년 4월부터 모든 새로운 앱과 앱 업데이트는 iOS 13 SDK로 구축되어야 하며 아이폰 XS Max 이상의 전체 화면 설계를 지원해야 한다고 보도했습니다.
https://9to5mac.com/2019/09/10/apple-april-2020-ios-13-sdk-deadline/
그 중 iOS13에서 Apple ID를 가지고 계정을 생성할 수 있는 "Sign in with Apple"의 기능이 새로 생겼습니다.
즉, 2020년 4월까지 앱을 업데이트하거나, 배포하기 위해서는 "Sign in with Apple" 로그인 기능이 꼭 들어가야 된다는 뜻이죠.
https://developer.apple.com/news/?id=09122019b
💡NSBluetoothPeripheralUsageDescription 키 값 변경
iOS 13이상 버전부터 블루투스에 접근 하기 위한 권한 키값이 변경되었습니다.
Privacy - Bluetooth Peripheral Usage Description -> Privacy - Bluetooth Always Usage Description
iOS 13 이전 호환성을 위해 2가지를 추가해줘야 합니다.
iOS13이 등장하면서 많은 기능이 나왔듯이 많은 이슈도 생겼네요.
찾은 방법들을 공유하려고 하니, 수정해야될 부분이나 다른 이슈사항 알려주시면 감사하겠습니다. :]
'iOS' 카테고리의 다른 글
[iOS] 개발자 계정 및 인증서 가이드 (0) | 2019.10.31 |
---|---|
[iOS] iOS13 Modal Style 및 Life Cycle (0) | 2019.10.30 |
[iOS] Library를 CocoaPods에 배포하는 방법 (0) | 2019.08.27 |
[iOS] Image Rendering Mode (0) | 2019.08.01 |
[iOS] Build Configuration 설정 방법 (0) | 2019.07.31 |