카카오 공유하기 - iOS 하이브리드 앱(웹뷰) 카카오톡이 없는 경우 마켓으로 이동하지 않는 현상에 대해 문의사항이 있습니다.
1. 개발환경
-
iOS
- 하이브리드 앱(웹뷰)
- 아이폰 - iOS version - 16.0.2.
- xcode - iOS Deployment target - 16.0
- swift UI
-
JavaScript
-
코드 저장소
2. 상황
iOS 하이브리드 앱(웹뷰)에서 카카오톡이 설치되어 있지 않은 경우 다운로드 버튼을 눌러도 App Store로 이동하지 않습니다.

itms-appss://apps.apple.com/kr/app/kakaotog-kakaotalk/id362057947
3. 로그
다운로드 버튼을 눌렀을때 xcode에서는 다음과 같은 로그가 발생합니다.
2022-09-25 13:39:00.625336+0900 KakaoShare[1325:102023] [ProcessSwapping] 0x1050025e0 - [pageProxyID=6, webPageID=22, PID=1331, navigationID=3] ProvisionalPageProxy::didFailProvisionalLoadForFrame: frameID=3
2022-09-25 13:39:00.625532+0900 KakaoShare[1325:102023] [Process] 0x109030018 - [pageProxyID=6, webPageID=16, PID=1330] WebPageProxy::didFailProvisionalLoadForFrame: frameID=3, isMainFrame=1, domain=WebKitErrorDomain, code=102, isMainFrame=1
2022-09-25 13:39:00.630855+0900 KakaoShare[1325:102046] [assertion] Error acquiring assertion: <Error Domain=RBSServiceErrorDomain Code=1 "target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit" UserInfo={NSLocalizedFailureReason=target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit}>
2022-09-25 13:39:00.630961+0900 KakaoShare[1325:102046] [ProcessSuspension] 0x10401c8a0 - ProcessAssertion::acquireSync Failed to acquire RBS assertion 'ConnectionTerminationWatchdog' for process with PID=1331, error: Error Domain=RBSServiceErrorDomain Code=1 "target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit" UserInfo={NSLocalizedFailureReason=target is not running or doesn't have entitlement com.apple.runningboard.assertions.webkit}
2022-09-25 13:39:00.632425+0900 KakaoShare[1325:102172] [assertion] Error acquiring assertion: <Error Domain=RBSAssertionErrorDomain Code=2 "Specified target process does not exist" UserInfo={NSLocalizedFailureReason=Specified target process does not exist}>
2022-09-25 13:39:00.632532+0900 KakaoShare[1325:102172] [ProcessSuspension] 0x10401c900 - ProcessAssertion::acquireSync Failed to acquire RBS assertion 'WebProcess Background Assertion' for process with PID=1331, error: Error Domain=RBSAssertionErrorDomain Code=2 "Specified target process does not exist" UserInfo={NSLocalizedFailureReason=Specified target process does not exist}
4. 질문 정리
swfit, iOS 개발환경에 미숙해서, 제가 설정을 잘못한것 같은데요 혹시, 코드 보시고
iOS 하이브리드 앱(웹뷰)에서 카카오톡이 설치되어 있지 않은 경우 다운로드를 눌렀을때 카카오톡 App Store로 이동하려면 어떻게 해야하는지 알려주실 수 있으신가요?
제가 swift 개발자가 아니고, 마음이 급하다 보니 코드를 잘못 작성한것 같습니다.
ios swift(story board) 코드 저장소: GitHub - skyepodium/kakaoshare-storyboard
카카오톡이 없는 경우에 App Store로 이동함을 확인했습니다.
다음 코드에서 tms-appss 을 추가했고, URL 스킴으로 호출했을때 App Store로 이동함을 확인했습니다.
// 카카오 SDK가 호출하는 커스텀 URL 스킴인 경우 open(_ url:) 메서드를 호출합니다.
if let url = navigationAction.request.url , ["kakaolink", "itms-appss"].contains(url.scheme) {
전체코드
import UIKit
import WebKit
@objcMembers class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
// 웹뷰 목록 관리
var webViews = [WKWebView]()
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(didRecieveTestNotification(_:)), name: NSNotification.Name("TestNotification"), object: nil)
let screenSize: CGRect = UIScreen.main.bounds
webView = createWebView(frame: screenSize, configuration: WKWebViewConfiguration())
// Do any additional setup after loading the view.
let myRequest = URLRequest(url: Var.myURL!)
webView.load(myRequest)
}
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.uiDelegate = self
view = webView
}
@objc func didRecieveTestNotification(_ notification: Notification) {
print("Test Notification")
let myRequest = URLRequest(url: Var.myURL!)
webView.load(myRequest)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void ) {
print("!!! webView method - string", navigationAction.request.url?.absoluteString ?? "")
// 카카오 SDK가 호출하는 커스텀 URL 스킴인 경우 open(_ url:) 메서드를 호출합니다.
if let url = navigationAction.request.url , ["kakaolink", "itms-appss"].contains(url.scheme) {
// 카카오톡 실행 가능 여부 확인 후 실행
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
decisionHandler(.cancel); return
}
// 서비스에 필요한 나머지 로직을 구현합니다.
decisionHandler(.allow)
}
/// ---------- 팝업 열기 ----------
/// - 카카오 JavaScript SDK의 로그인 기능은 popup을 이용합니다.
/// - window.open() 호출 시 별도 팝업 webview가 생성되어야 합니다.
///
func webView(_ webView: WKWebView,
createWebViewWith configuration: WKWebViewConfiguration,
for navigationAction: WKNavigationAction,
windowFeatures: WKWindowFeatures
) -> WKWebView? {
guard let frame = self.webViews.last?.frame else {
return nil
}
return createWebView(frame: frame, configuration: configuration) // 웹뷰를 생성하여 리턴하면 현재 웹뷰와 parent 관계가 형성됩니다.
}
/// ---------- 팝업 닫기 ----------
/// - window.close()가 호출되면 앞에서 생성한 팝업 webview를 닫아야 합니다.
///
func webViewDidClose(_ webView: WKWebView) {
destroyCurrentWebView()
}
// 웹뷰 생성 메소드 예제
func createWebView(frame: CGRect, configuration: WKWebViewConfiguration) -> WKWebView {
let webView = WKWebView(frame: frame, configuration: configuration)
webView.uiDelegate = self // set delegate
webView.navigationDelegate = self
self.view.addSubview(webView) // 화면에 추가
self.webViews.append(webView) // 웹뷰 목록에 추가
return webView // 그 외 서비스 환경에 최적화된 뷰 설정하기
}
// 웹뷰 삭제 메소드 예제
func destroyCurrentWebView() {
self.webViews.popLast()?.removeFromSuperview() // 웹뷰 목록과 화면에서 제거하기
}
}
//Var.swift
import Foundation
class Var{
public static var myURL = URL(string:"http://kakao-share.s3-website.ap-northeast-2.amazonaws.com/")
// public static var myURL = URL(string:"https://developers.kakao.com/tool/demo/message/kakaolink?method=button")
}