블로그와 함께 업로드 할 예정입니다!
naver blog: https://blog.naver.com/0_0yeggy
: Product -> Test 돌렸더니 해결
Main Thread Checker: UI API called on a background thread 혹은 Exception: "Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread."
Product -> Scheme -> Edit Scheme
Diagnotics -> Main Thread Checker에 체크!
다시 한번 run 해서 Main Tread 에러나는 곳 찾기!
에러에 해당하는 기능 DispatchQueue.main.async()로 감싸주기
publicfunc startCount(){DispatchQueue.main.async{self.countLabel.text ="\(self.count)번"self.count =self.count +1}}Attempt to present UIAlertController whose view is not in the window hierarchy with localnotification
: 로그인 창에서 로그인 실패 시 UIAlertController 띄우고, 로그인을 성공할 시 main 페이지로 이동하려다가 오류 생성
: 로그인 버튼을 누를 때, 화면 이동을 먼저하고 UIAlertController를 띄워서
: 기능을 함수로 분리한 뒤, 각각에 맞는 함수 호출 (이때 main thread 에러를 방지하기 위해 DispatchQueue.main.async로 기능을 감싸주어야함.)
// 코드 일부 발췌
if myResponse.statusCode ==200{letuser=tryJSONDecoder().decode(LoginInfo.self, from: data)print(user.userInfo.id)self.idText = user.userInfo.id
self.nameText = user.userInfo.name
self.majorText = user.userInfo.major
self.moveToMain()}elseif myResponse.statusCode ==404 || myResponse.statusCode ==500{self.alert()}func moveToMain(){DispatchQueue.main.async{letvc=self.storyboard?.instantiateViewController(identifier:"main")as!MainViewController
vc.modalPresentationStyle =.fullScreen
vc.idText =self.idText
vc.nameText =self.nameText
vc.majorText =self.majorText
self.present(vc, animated:true)}}func alert(){DispatchQueue.main.async{letalert=UIAlertController(title:"경고", message:"아이디 또는 비밀번호를 잘못 입력하셨습니다.", preferredStyle:.alert)
alert.addAction(UIAlertAction(title:"확인", style:.cancel, handler:nil))self.present(alert, animated:true, completion:nil)}}typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))
==> type 오류
letexam=tryJSONDecoder().decode([ExamInfo].self, from: data)letexam=tryJSONDecoder().decode(ExamInfo.self, from: data)=> ?을 생략해서 발생하는 문제였다....
structExamInfo:Codable{letowner:OwnerInfolettitle:StringletcourseName:StringletcourseCode:StringletstartTime:StringletendTime:String}structExamInfo:Codable{letowner:OwnerInfo?lettitle:String?letcourseName:String?letcourseCode:String?letstartTime:String?letendTime:String?}=> cell의 스타일을 변경하라
letcell=UITableViewCell(style:.default, reuseIdentifier:nil)letcell=UITableViewCell(style:.subtitle, reuseIdentifier:nil)=> complete() 추가!
DispatchQueue.main.async{completed()}==> 변수 타입 뒤에 '!' 붙혔더니 해결
=> 첫번째 코드를 두번째 코드로 변경
guardlet httpBody =try?JSONSerialization.data(withJSONObject: parameter, options:[])else{return}lethttpBody=try!JSONEncoder().encode(parameter)pod deintegrate 입력
sudo gem install cocoapods-clean 입력
pod clean 입력
pod setup 입력
pod install 입력
후에 자신의 프로젝트 이름.xcworkspace를 open 후 command + b로 프로젝트 빌드
=> shift + command + k 입력시 해결
=> View Controller에 Class 이름 확인
- 아래의 링크와 같이 Privacy 추가하기
해당 작업을 진행하였는데도 안되면?
- 수동으로 입력하기
plist.info 를 source code로 연 다음, 수동으로 추가하자
먼저 plist.info에 오른쪽 마우스 버튼을 클릭한 뒤, OpenAs 에서 Source Code를 선택한다. 그 후
<key>NSCalendarsUsageDescription</key>
<string>This app need to access your calendar events</string>
<key>NSCameraUsageDescription</key>
<string>This app need to access your camera events</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app need to access your photo library events</string>
이렇게 수동으로 추가해주자.
Project -> Build Setting -> Other Linker Flag -> "$(OTHER_LDFLAGS) -ObjC" 삽입