Skip to content

Instantly share code, notes, and snippets.

@AndreyAnt
Created October 14, 2021 16:30
Show Gist options
  • Save AndreyAnt/8a10d121b888814aab81184119801db5 to your computer and use it in GitHub Desktop.
Save AndreyAnt/8a10d121b888814aab81184119801db5 to your computer and use it in GitHub Desktop.
//
// VKLoginWebView.swift
// SwiftUI-Course
//
// Created by andrey.antropov on 14.10.2021.
//
import SwiftUI
import WebKit
struct VKLoginWebView: UIViewRepresentable {
fileprivate let navigationDelegate = WebViewNavigationDelegate()
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
webView.navigationDelegate = navigationDelegate
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
if let request = buildAuthRequest() {
uiView.load(request)
}
}
private func buildAuthRequest() -> URLRequest? {
var components = URLComponents()
components.scheme = "https"
components.host = "oauth.vk.com"
components.path = "/authorize"
components.queryItems = [
URLQueryItem(name: "client_id", value: "6704883"),
URLQueryItem(name: "scope", value: "262150"),
URLQueryItem(name: "display", value: "mobile"),
URLQueryItem(name: "redirect_uri", value: "https://oauth.vk.com/blank.html"),
URLQueryItem(name: "response_type", value: "token"),
URLQueryItem(name: "v", value: "5.130")
]
return components.url.map { URLRequest(url: $0) }
}
}
class WebViewNavigationDelegate: NSObject, WKNavigationDelegate {
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
guard let url = navigationResponse.response.url,
url.path == "/blank.html",
let fragment = url.fragment else {
decisionHandler(.allow)
return
}
let params = fragment
.components(separatedBy: "&")
.map { $0.components(separatedBy: "=") }
.reduce([String: String]()) { result, param in
var dict = result
let key = param[0]
let value = param[1]
dict[key] = value
return dict
}
guard let token = params["access_token"],
let userIdString = params["user_id"],
let _ = Int(userIdString)
else {
decisionHandler(.allow)
return
}
UserDefaults.standard.set(token, forKey: "vkToken")
NotificationCenter.default.post(name: NSNotification.Name("vkTokenSaved"), object: self)
decisionHandler(.cancel)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment