반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 프로세스 방지
- onsen-ui
- NUXT
- JavaScript
- 동일 프로그램
- electron-nuxt
- Vuetify
- v-text-field height
- error
- Vue
- vuejs
- naver storage bucket error
- Android
- v-select
- c#
- bucket cors
- vuetifyjs
- kotlin
- 동일 프로세스
- sort
- Electron
- bucket max-key
- sequelize
- CSS
- nodejs
- xlsx
- MySQL
- f035d
- onsenui
- naver storage
Archives
- Today
- Total
앙큼한 개발기록
swiftUI 에서 view Controller로 Webview 띄우기 본문
최근 하이브리드 앱을 만들어 달라는 부탁을 받고
매번 story board로 하던 작업을 swift ui로 해보싶어서 swiftui로 프로젝트를 빌드해 보았다.
근데 만들고 보니 swiftui 에서는 storyboard 처럼 viewController가 없어 webview에 권한이나 위치정보, 카메라 정보나
javascript함수 호출과 같은 부분을 어떤식으로 구현하면 좋을지가 막막하다가
해당 내용을 구현한 소스를 정리해 보고자 글을 작성해 본다.
그리고 찾는데 오래걸려서 직접 정리하는 것도 있다....
1. ViewController.swift 를 하나 만든다.
- 이름은 상관 없다.
import SwiftUI
struct ViewController: UIViewControllerRepresentable {
// storyboard와 동일한 controller
let webviewController = WebviewController()
// ContentView에서 최초에 호출되는 override 함수
func makeUIViewController(context: Context) -> some UIViewController {
return webviewController
}
// ContentView 에서 makeUIViewController를 호출하고 나서 업데이트 할때 호출 하는 함수
// 나는 화면이 다 만들어 지고 나서 위치정보를 호출해 보고
// 권한이 있으면 위치정보를 보내주고, 없으면 권한 설정을 표시 한다.
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
let status = webviewController.locationService.getLocationStatus()
print("update ui view controller")
if status != .authorizedAlways && status != .authorizedWhenInUse {
webviewController.requestAndSendLocation()
}
}
}
2. 위에 ViewController에서 사용한 WebviewController.swift 를 만든다.
- 이거 먼저 만들고 위에 1번 만들어도 된다.
- 마찬가지로 이름은 상관 없다.
import UIKit
import WebKit
class WebviewController: UIViewController {
// 팝업을 위해, 결제를 위해 웹뷰를 배열로 만들어서 컨트롤 한다.
var webviews = [WKWebView]()
// 우리가 아는 컨트롤러 호출시 초기에 가장 먼저 실행되는 함수
override func viewDidLoad() {
super.viewDidLoad()
// 호출할 웹뷰 주소
let host = URL(string: Constants.MAIN_URL)
// 웹뷰와 앱이 통신하기 위해 하는 설정
let webConfiguration = WKWebViewConfiguration()
let contentController = WKUserContentController()
contentController.add(self, name: "location")
webConfiguration.userContentController = contentController
webConfiguration.defaultWebpagePreferences.allowsContentJavaScript = true
webConfiguration.preferences.javaScriptCanOpenWindowsAutomatically = true
// 웹뷰 생성
self.createWebView(frame: self.view.frame, config: webConfiguration)
.load(URLRequest(url: host!))
}
// 웹뷰를 만들어 준다.
// uiDelegate, navigationDelegate는 알럿, 컨펌, 혹은 내장함수와 팝업, 그리고 생성 되는 라이프사이클을 간섭할수 있다.
func createWebView(frame: CGRect, config: WKWebViewConfiguration) -> WKWebView {
let webview = WKWebView(frame: frame, configuration: config)
webview.uiDelegate = self
webview.navigationDelegate = self
webview.allowsBackForwardNavigationGestures = true
webview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
webview.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(webview)
self.webviews.append(webview)
return webview
}
// 자바스크립트로 데이터 전달할때 swift객체를 string으로 전환해서 전달하면 javascript에서 object로 받을 수 있다.
func objectToString(object obj: Any) -> String {
let jsonData = try! JSONSerialization.data(withJSONObject: obj, options: [])
return String(data: jsonData, encoding: .utf8)!
}
// 위치 정보를 동의 하였을 경우 해당 정보를 javascript로 전달
func requestAndSendLocation() {
locationService.requestLocation { coordinate in
let lat = coordinate.latitude.description
let lng = coordinate.longitude.description
let position = ["lat": lat, "lng": lng]
let stringData = self.objectToString(object: position)
print("location", stringData)
self.webviews[0].evaluateJavaScript("currentLocation(\(stringData))")
}
}
}
1. ContentView에 ViewController라고 설정하면 웹뷰가 짠 하고 나타난다.
struct ContentView: View {
var body: some View {
ViewController()
}
}
Comments