๋ธ๋ก๊ทธ์ ํจ๊ป ์ ๋ก๋ ํ ์์ ์ ๋๋ค!
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()๋ก ๊ฐ์ธ์ฃผ๊ธฐ
public func 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 {
let user = try JSONDecoder().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()
} else if myResponse.statusCode == 404 || myResponse.statusCode == 500 {
self.alert()
}
func moveToMain(){
DispatchQueue.main.async {
let vc = 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 {
let alert = UIAlertController(title: "๊ฒฝ๊ณ ", message: "์์ด๋ ๋๋ ๋น๋ฐ๋ฒํธ๋ฅผ ์๋ชป ์
๋ ฅํ์
จ์ต๋๋ค.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "ํ์ธ", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}moveToMain() ๊ธฐ๋ฅ์ ํจ์์ ์ง์ด๋ฃ์ผ๋ main ํ์ด์ง์ ๋ฐ์ดํฐ๋ ์ ๋ฌ์ด ์ ๋์๋ค! ( ์ด์ ์๋ ์๋์ )
typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))
==> type ์ค๋ฅ
let exam = try JSONDecoder().decode([ExamInfo].self, from: data)let exam = try JSONDecoder().decode(ExamInfo.self, from: data)=> ?์ ์๋ตํด์ ๋ฐ์ํ๋ ๋ฌธ์ ์๋ค....
struct ExamInfo: Codable{
let owner: OwnerInfo
let title: String
let courseName: String
let courseCode: String
let startTime: String
let endTime: String
}struct ExamInfo: Codable{
let owner: OwnerInfo?
let title: String?
let courseName: String?
let courseCode: String?
let startTime: String?
let endTime: String?
}=> cell์ ์คํ์ผ์ ๋ณ๊ฒฝํ๋ผ
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)=> complete() ์ถ๊ฐ!
DispatchQueue.main.async { completed() }==> ๋ณ์ ํ์ ๋ค์ '!' ๋ถํ๋๋ ํด๊ฒฐ
=> ์ฒซ๋ฒ์งธ ์ฝ๋๋ฅผ ๋๋ฒ์งธ ์ฝ๋๋ก ๋ณ๊ฒฝ
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameter, options: []) else { return }let httpBody = 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" ์ฝ์