2022. 11. 11. 16:37ㆍiOS/iOS
원래는..(왜그랬지?)
background에서 푸시를 받고 터치해서 자동으로 앱이 foreground 상태가 될때 viewwillappear가 호출될 거라고 생각하고,
viewwillappear 함수 내부에 (중간생략) 받아온 url을 웹뷰에 로딩하는 로직으로 코드를 짰었는데
테스트할때보니, viewwillappear에 디버깅이 안걸리는 것이었다.......
Why does viewWillAppear not get called when an app comes back from the background?
크크,, 다 나와같은 시기를 겪는군 했지만? 응 11년전 글 ^^...;;분발하자,,
글 내용 답변인 즉슨,
1. viewwillappear 쓰려고한다고? 응 너가 원하는거 willEnterForegroundNotification 이거면 될거야.
2. notification center로도 되잖음 그거쓰셈.
였음.
notificationcenter를 많이 사용하고 싶지 않아서,
userNotificationCenter didreceive(푸시를 터치하면 호출되는 함수)내부에
혹시나 되나..? 싶어서 .background를 추가해봤지만 오,, 디버깅이 안걸렸음........
if UIApplication.shared.applicationState == .active && UIApplication.shared.applicationState == .background {
print("🌼앱상태 = \(UIApplication.shared.applicationState)")
NotificationCenter.default.post(name: NSNotification.Name("uIApplicationDidBecomeActive"), object: nil)
}
그래서 Scenedelegate.swift에 noti를 추가해서 해결했음.
(해당 프로젝트는 iOS13 버전 이상을 타겟으로 하는 프로젝트여서
실행된 앱이 foreground에 표시될때 Scenedelegate에서 호출되는 메서드인 sceneDidBecomeActive를 이용한것임.)
func sceneDidBecomeActive(_ scene: UIScene) {
NotificationCenter.default.post(name: NSNotification.Name("uIApplicationDidBecomeActive"), object: nil)
}
정리.
앱이 켜져있는 background 상태에서 push를 받았을때, push를 터치하면 진행되는 흐름을 정리했습니다.
웹뷰에 url 로딩 완료시 호출되는 함수(한번이라도 로드 된적이 있는지 판별하는 isFirstLoad값을 false로 설정)
//class생략
private var isFirstLoad: Bool = true
//초기에 웹뷰 url로딩 완료시 호출되는 함수
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
if (self.isFirstLoad) {
self.isFirstLoad = false
if let url = URL(string: SmartStoreSharedData.instance.url ?? "url is nil") {
let request: URLRequest = URLRequest(url: url)
webView.load(request)
}
}
}
수신받은 푸시를 터치했을때 호출
Appdelegate.swift - usernotificationCenter didReceive 함수 호출
여기 함수에선 서버에서 받아온 link값을 SmartStoreSharedData.instance.url 여기에 넣어주는 역할만 함
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo //푸시로 오는 데이터
let title = response.notification.request.content.title //알림제목
let body = response.notification.request.content.body //알림내용
if let link = userInfo["link"] {
SmartStoreSharedData.instance.url = link as! String //해당 링크로 이동할때 UrlInfo.shared.url를 이용한다.
}
//foreground 상태에서 푸시를 클릭했을때는 viewwillappear함수가 호출되지 않을테니 푸시를 터치했을때 앱 state가 active상태라면 웹뷰에 전달받은 url로 로딩을 시킴
if UIApplication.shared.applicationState == .active {
NotificationCenter.default.post(name: NSNotification.Name("uIApplicationDidBecomeActive"), object: nil)
}
completionHandler()
}
Scenedelegate.swift - sceneDidBecomeActive 함수 호출
실행된 앱이 foreground에 표시될때 호출되는 메서드
func sceneDidBecomeActive(_ scene: UIScene) {
NotificationCenter.default.post(name: NSNotification.Name("uIApplicationDidBecomeActive"), object: nil)
}
viewwillappear함수 내부에서 추가해줬었던 addObserver(applicationDidBecome함수 호출)
@objc public func applicationDidBecome() {
//푸시 클릭 시 SmartStoreSharedData.instance.url에 저장된 링크로 webView를 이동 시킵니다.
//앱이 한번이라도 구동 된 적이 있다면
if(!self.isFirstLoad) {
if let url = URL(string: SmartStoreSharedData.instance.url ?? "url is nil") {
let request: URLRequest = URLRequest(url: url)
webView.load(request)//전달받은 알림 페이지 웹뷰에 로딩
SmartStoreSharedData.instance.url = ""
}
}
}