토스 인증 SwiftUI

성민·2023년 7월 25일
0

swift

목록 보기
5/6
  1. 웹뷰 띄우기

import SwiftUI
import WebKit

struct CustomWebView: UIViewRepresentable {
    
    @Binding var isShowingModal: Bool
    @Binding var isSuccess: Bool
    
    let request: URLRequest
    let contentController = WKUserContentController()

    func makeUIView(context: Context) -> WKWebView {
        contentController.add(context.coordinator, name: "tossAuthWebView")
        
        let configuration = WKWebViewConfiguration()
        configuration.userContentController = contentController

        let webView = WKWebView(frame: .zero, configuration: configuration)
        webView.navigationDelegate = context.coordinator

        return webView
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.load(request)
    }

    func makeCoordinator() -> Coordinator {
        Coordinator($isShowingModal, $isSuccess)
    }

    class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
        
        @Binding var isShowingModal: Bool
        @Binding var isSuccess: Bool
        
        init(_ isShowingModal: Binding<Bool>, _ isSuccess: Binding<Bool>) {
            _isShowingModal = isShowingModal
            _isSuccess = isSuccess
        }
        
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            guard let body = message.body as? String else { return }

            switch body {
            case "TOSS_AUTH_POPUP_ONLOAD": // 표준창 로드 완료
                print("TOSS_AUTH_POPUP_ONLOAD")

            case "TOSS_AUTH_SUCCESS": // 표준창 완료
                print("TOSS_AUTH_SUCCESS")
                isShowingModal = false
                isSuccess = true

            case "TOSS_AUTH_FAIL": // 표준창 에러
                print("TOSS_AUTH_FAIL")

            case "TOSS_AUTH_CLICK_NAVBAR_CLOSE": // 취소
                print("TOSS_AUTH_CLICK_NAVBAR_CLOSE")

            default:
                break
            }
        }
    }
}
  1. 리퀘스트 생성
func makeRequest() -> URLRequest {
        let txID = "txID"
        let authURLString = "https://auth.cert.toss.im/start?serviceType=SIGN_USER_AUTH"
        guard let url = URL(string: authURLString) else { fatalError("Invalid URL") }

        var request = URLRequest(url: url)
        request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"
        request.httpBody = "txId=\(txID)".data(using: .utf8)

        return request
    }
  1. 뷰에서 처리
.onChange(of: isSuccess) { newValue in
	if newValue {
		navigationCoordinator.path.append(.login)
	}
}
.sheet(isPresented: $isShowTossAuth) {
	CustomWebView(isShowingModal: $isShowTossAuth, isSuccess:$isSuccess, request: makeRequest())
}

0개의 댓글