Notice
Recent Posts
Recent Comments
Link
투케이2K
31. (TWOK/UTIL) [Ios/Swift] A_Main - 웹뷰 로드 화면 관련 클래스 정리 본문
[설 명]
프로그램 : Ios / Swift
설 명 : 웹뷰 로드 화면 관련 클래스 정리
[소스 코드]
import UIKit
import SafariServices
import WebKit
import AVFoundation
class A_Main: UIViewController, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate {
// MARK: - [클래스 설명]
/*
// -----------------------------------------
1. 메인 웹뷰 화면 호출 액티비티 화면
2. 사용하는 스토리보드 : Main
3. 웹뷰 호출 실시 및 자바스크립트 통신 처리
// -----------------------------------------
*/
// MARK: - [빠른 로직 찾기 : 주석 로직 찾기]
// -----------------------------------------
// [SEARCH FAST] : [인트로 화면 처리]
// [SEARCH FAST] : [메인 웹뷰 포그라운드 푸시 알림 JS 전달]
// [SEARCH FAST] : [저장된 프리퍼런스 데이터 확인]
// [SEARCH FAST] : [네트워크 활성 상태 체크]
// [SEARCH FAST] : [웹뷰 로드 수행 실시]
// [SEARCH FAST] : [포그라운드 및 백그라운드 상태 확인]
// [SEARCH FAST] : [프리퍼런스 값 초기화 실시]
// [SEARCH FAST] : [웹뷰 리로드 상태 확인]
// [SEARCH FAST] : [자바스크립트 통신 수행]
// [SEARCH FAST] : [웹뷰 에러 코드 감지]
// -----------------------------------------
// MARK: - [웹뷰 전역 변수 선언 부분]
private var main_webview: WKWebView? = nil // [동적으로 웹뷰 생성]
var javascriptController = WKUserContentController() // [자바스크립트 통신 사용]
let javascriptConfig = WKWebViewConfiguration() // [자바스크립트 통신 사용]
let kwebviewPreference = WKPreferences() // [웹뷰에 대한 기본 속성 설정을 캡슐화]
// MARK: - [뷰 컨트롤러 종료 시 호출되는 함수]
deinit {
// [WKWebView Progress 퍼센트 가져오기 이벤트 제거]
if self.main_webview != nil {
self.main_webview?.removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress))
}
// [브로드 캐스트 알림 해제]
}
// MARK: - [뷰 화면 관련 전역 변수]
@IBOutlet weak var introBg: UIImageView!
// MARK: - [일반 전역 변수]
let ACTIVITY_NAME = "A_Main"
// MARK: - [뷰 로드 실시]
override func viewDidLoad() {
super.viewDidLoad()
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> viewDidLoad() :: 뷰 로드 실시]")
print("====================================")
print("")
// -----------------------------------------
// [뷰 컨트롤러 배경 색상 지정]
self.view.backgroundColor = UIColor.init(rgb: 0xffffff).withAlphaComponent(1.0)
// -----------------------------------------
// -----------------------------------------
// [SEARCH FAST] : [메인 웹뷰 포그라운드 푸시 알림 JS 전달]
S_Preference().setString(_sKey: S_FinalData.PRE_ROOT_ACTIVITY, _sValue: "RUN")
// -----------------------------------------
// -----------------------------------------
// [SEARCH FAST] : [저장된 프리퍼런스 데이터 확인]
S_Preference().setString(_sKey: S_FinalData.PRE_MOBILE_MOCO, _sValue: S_DeviceID().getDeviceID()) // [디바이스 고유값 저장]
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> viewDidLoad() :: 사전 저장된 프리퍼런스 데이터 확인]")
print("-------------------------------")
print("univ :: [학교 구분] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_USER_UNIV))
print("-------------------------------")
print("uid :: [사용자 학번] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_USER_UID))
print("-------------------------------")
print("upw :: [사용자 비번] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_USER_UPW))
print("-------------------------------")
print("iddi :: [사용자 신분] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_USER_IDDI))
print("-------------------------------")
print("autoLogin :: [자동 로그인] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_AUTO_LOGIN))
print("-------------------------------")
print("picture :: [사용자 사진 표시] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_USER_PICTURE))
print("-------------------------------")
print("shake :: [흔들기 이벤트] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_MOBILE_SHAKE))
print("-------------------------------")
print("plat :: [플랫폼] :: ", S_FinalData.PRE_MOBILE_PLAT)
print("-------------------------------")
print("moco :: [디바이스 고유값] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_MOBILE_MOCO))
print("-------------------------------")
print("version :: [앱 버전] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_MOBILE_VERSION))
print("-------------------------------")
print("code :: [앱 코드] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_MOBILE_CODE))
print("-------------------------------")
print("token :: [푸시 토큰] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_PUSH_TOKEN))
print("-------------------------------")
print("loginScheme :: [로그인 스키마 데이터] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_SCHEME_DATA_LOGIN))
print("-------------------------------")
print("callScheme :: [일반 스키마 데이터] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_SCHEME_DATA_CALL))
print("-------------------------------")
print("PRE_APP_UPDT_TIME :: [앱 재구동 시간 [분 단위]] :: ", S_Preference().getString(_sKey: S_FinalData.PRE_APP_UPDT_TIME))
print("====================================")
print("")
/*
// MARK: [스키마 데이터 확인]
self.showAlert(type: 0,
tittle: "[스키마 및 숏컷 접속 확인]",
content: "로그인 스키마 데이터 : " + S_Preference().getString(_sKey: S_FinalData.PRE_SCHEME_DATA_LOGIN) + "\n"
+ "일반 스키마 데이터 : " + S_Preference().getString(_sKey: S_FinalData.PRE_SCHEME_DATA_CALL) + "\n",
okBtb: "확인",
noBtn: "")
// */
// -----------------------------------------
// -----------------------------------------
// [뷰 컨트롤러 상태 업데이트 수행 실시 >> 퍼미션 권한 체크]
self.permissionState()
// -----------------------------------------
// -----------------------------------------
// [SEARCH FAST] : [네트워크 활성 상태 체크]
if C_StateCheck().getWhatOfNetwork() == true { // SceneDelegate 저장된 데이터 확인
// [SEARCH FAST] : [웹뷰 로드 수행 실시]
self.init_WebView(_loadUrl: S_FinalData.WV_LOAD_MAIN_ENZ_URL)
}
else {
// [알림 팝업창 호출]
self.showAlert(
type:0,
tittle: S_FinalData.AL_TITLE,
content: S_FinalData.AL_NET + " (\(self.ACTIVITY_NAME))",
okBtb: S_FinalData.AL_OK,
noBtn: ""
)
}
// -----------------------------------------
}
// MARK: - [뷰 컨트롤러 파일에서 설정 : 상태바 콘텐츠 색상 변경]
override var preferredStatusBarStyle: UIStatusBarStyle {
if #available(iOS 13, *) {
//return .lightContent // [흰 색상 콘텐츠 표시]
return .darkContent // [검은 색상 콘텐츠 표시]
//return .default // [검은 색상 콘텐츠 표시]
} else {
return .default
}
}
// MARK: - [뷰 로드 완료]
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> viewWillAppear() :: 뷰 로드 완료]")
print("====================================")
print("")
}
// MARK: - [뷰 화면 표시]
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> viewDidAppear() :: 뷰 화면 표시]")
print("====================================")
print("")
// -----------------------------------------
// [SEARCH FAST] : [포그라운드 및 백그라운드 상태 확인]
NotificationCenter.default.addObserver( // [포그라운드]
self,
selector: #selector(self.checkForeground),
name: UIApplication.willEnterForegroundNotification,
object: nil
)
NotificationCenter.default.addObserver( // [백그라운드]
self,
selector: #selector(self.checkBackground),
name: UIApplication.didEnterBackgroundNotification,
object: nil
)
// -----------------------------------------
// -----------------------------------------
// [포그라운드 처리 실시]
self.checkForeground()
// -----------------------------------------
}
// MARK: - [뷰 정지 상태]
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> viewWillDisappear() :: 뷰 정지 상태]")
print("====================================")
print("")
}
// MARK: - [뷰 종료 상태]
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> viewDidDisappear() :: 뷰 종료 상태]")
print("====================================")
print("")
// -----------------------------------------
// [SEARCH FAST] : [포그라운드 및 백그라운드 상태 확인]
NotificationCenter.default.removeObserver( // [포그라운드]
self,
name: UIApplication.willEnterForegroundNotification,
object: nil
)
NotificationCenter.default.removeObserver( // [백그라운드]
self,
name: UIApplication.didEnterBackgroundNotification,
object: nil
)
// -----------------------------------------
// -----------------------------------------
// [SEARCH FAST] : [프리퍼런스 값 초기화 실시]
S_Preference().mainFinishClear()
// -----------------------------------------
}
// MARK: - [포그라운드 상태 처리 메소드 작성]
@objc func checkForeground() {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> checkForeground() :: 뷰 컨트롤러 포그라운드]")
print("====================================")
print("")
// -----------------------------------------
// [SEARCH FAST] : [웹뷰 리로드 상태 확인]
// -----------------------------------------
// -----------------------------------------
// [뷰 컨트롤러 상태 업데이트 수행 실시]
self.permissionState()
// -----------------------------------------
}
// MARK: - [백그라운드 상태 처리 메소드 작성]
@objc func checkBackground() {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> checkBackground() :: 뷰 컨트롤러 백그라운드]")
print("====================================")
print("")
}
// MARK: - [퍼미션 상태 값 갱신 메소드 : 포그라운드 상태로 올라올때 마다 체크 수행 : 사용자가 강제로 변경한 상태 체크]
func permissionState(){
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> permissionState() :: 뷰 컨트롤러 퍼미션 상태 업데이트 수행 실시]")
print("====================================")
print("")
// -----------------------------------------
// [위치 권한 활성 상태 체크 메소드 호출]
// -----------------------------------------
// -----------------------------------------
// [블루투스 권한 설정 퍼미션 확인 실시]
// -----------------------------------------
}
// MARK: - [웹뷰 초기 설정 값 정의 실시 및 웹뷰 로드 수행]
func init_WebView(_loadUrl:String){
// [사용자 모바일 상태바 높이 확인]
let statusBarHeight = UIApplication.shared.statusBarFrame.height
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> permissionState() :: 웹뷰 초기 설정 및 웹뷰 로드 수행]")
print("-------------------------------")
print("url :: \(_loadUrl)")
print("-------------------------------")
print("width :: ", self.view.frame.size.width)
print("-------------------------------")
print("height :: ", self.view.frame.size.height)
print("-------------------------------")
print("statusBarHeight :: ", statusBarHeight)
print("====================================")
print("")
// -----------------------------------------
// [SEARCH FAST] : [웹뷰 로드 수행 실시]
// [SEARCH FAST] : [웹뷰 세션 및 캐시 삭제 수행]
// -----------------------------------------
// -----------------------------------------
// [전체 방문 데이터 지우기]
/*
WKWebsiteDataStore.default().fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), completionHandler: {
(records) -> Void in
for record in records{
WKWebsiteDataStore.default().removeData(ofTypes: record.dataTypes, for: [record], completionHandler: {})
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> init_WebView() :: 사전 전체 방문 데이터 삭제 수행]")
print("-------------------------------")
print("type :: removeData")
print("====================================")
print("")
}
})
// */
// -----------------------------------------
// -----------------------------------------
// [원하는 캐시 데이터만 골라서 삭제]
///*
let websiteDataTypes = NSSet(array:
[WKWebsiteDataTypeDiskCache, // 디스크 캐시
WKWebsiteDataTypeMemoryCache, // 메모리 캐시
WKWebsiteDataTypeCookies, // 웹 쿠키,
WKWebsiteDataTypeOfflineWebApplicationCache, // 앱 캐시
WKWebsiteDataTypeWebSQLDatabases, // 웹 SQL 데이터 베이스
WKWebsiteDataTypeIndexedDBDatabases // 데이터 베이스 정보
//WKWebsiteDataTypeLocalStorage // 로컬 스토리지
//WKWebsiteDataTypeSessionStorage // 세션 스토리지
])
let date = NSDate(timeIntervalSince1970: 0)
WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes as! Set, modifiedSince: date as Date, completionHandler:{
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> init_WebView() :: 사전 캐시 및 세션 데이터 삭제 수행]")
print("-------------------------------")
print("type :: removeData")
print("====================================")
print("")
})
// */
// -----------------------------------------
// -----------------------------------------
// [URL 요청 후 잔여 캐시 데이터 삭제]
URLCache.shared.removeAllCachedResponses()
// -----------------------------------------
// -----------------------------------------
// [설치된 날짜 가져오는 코드]
let urlToDocumentsFolder: URL? = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last
let installDate = try? FileManager.default.attributesOfItem(atPath: (urlToDocumentsFolder?.path)!)[.creationDate] as! Date
// [설치된 날짜부터 지금까지의 cookie all clear]
URLSession.shared.configuration.httpCookieStorage?.removeCookies(since: installDate!)
// [로그 출력 실시]
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> init_WebView() :: 사전 캐시 및 세션 데이터 삭제 수행]")
print("-------------------------------")
print("type :: URLSession removeCookies")
print("====================================")
print("")
// -----------------------------------------
// -----------------------------------------
// [웹 보기에 대한 쿠키, 디스크 및 메모리 캐시, 기타 유형의 데이터를 관리하는 개체]
self.javascriptConfig.websiteDataStore = WKWebsiteDataStore.default() // [디폴트]
//self.javascriptConfig.websiteDataStore = WKWebsiteDataStore.nonPersistent() // [쿠키 셋팅]
// -----------------------------------------
// -----------------------------------------
// [SEARCH FAST] : [자바스크립트 통신 수행]
/*
[브릿지 경로 지정]
1. JS >> IOS 호출 시 사전 브릿지 경로 등록 필요
*/
self.addJavaScriptBridge()
// -----------------------------------------
// -----------------------------------------
// [웹뷰 전체 화면 설정 실시]
self.main_webview = WKWebView.init(
frame: CGRect.init(
x: 0,
y: statusBarHeight,
width: self.view.frame.width, // [전체 가로 지정]
height: self.view.frame.height - statusBarHeight // [전체 높이 - 상태바 세로 지정]
),
configuration: self.javascriptConfig
)
// -----------------------------------------
// -----------------------------------------
// [웹뷰 캐시 삭제 실시]
WKWebsiteDataStore.default().removeData(ofTypes:
[
WKWebsiteDataTypeDiskCache,
WKWebsiteDataTypeMemoryCache
],
modifiedSince: Date(timeIntervalSince1970: 0), completionHandler:{ })
// -----------------------------------------
// -----------------------------------------
// [웹뷰 옵션값 지정]
self.main_webview?.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true // 자바스크립트 활성화
self.main_webview?.navigationDelegate = self // 웹뷰 변경 상태 감지 위함
//self.main_webview?.allowsBackForwardNavigationGestures = true // 웹뷰 뒤로가기, 앞으로 가기 제스처 사용
self.main_webview?.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil) // 웹뷰 로드 상태 퍼센트 확인
self.main_webview?.uiDelegate = self // alert 팝업창 이벤트 받기 위함
// -----------------------------------------
// -----------------------------------------
// [웹뷰 스크롤 바운스 방지]
self.main_webview?.scrollView.alwaysBounceVertical = false
self.main_webview?.scrollView.bounces = false
// -----------------------------------------
// -----------------------------------------
// [메인 뷰에 웹뷰 추가 실시]
self.view.addSubview(self.main_webview!)
// -----------------------------------------
// -----------------------------------------
// [실제 웹뷰 주소 로드]
let url = URL (string: _loadUrl) // 웹뷰 로드 주소
let request = URLRequest(url: url! as URL)
self.main_webview!.load(request)
// -----------------------------------------
// -----------------------------------------
// [테스트 html 파일 로드]
/*
guard let localFilePath = Bundle.main.path(forResource: "javaScriptTest", ofType: "html")
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> init_WebView() :: 웹뷰 로드 수행]")
print("-------------------------------")
print("error :: file path is nil")
print("====================================")
print("")
return
}
let urlFile = URL(fileURLWithPath: localFilePath)
let request = URLRequest(url: urlFile)
self.main_webview!.load(request as URLRequest)
// */
// -----------------------------------------
// -----------------------------------------
// [SEARCH FAST] : [인트로 화면 처리]
self.main_webview?.isHidden = true // [사전 웹뷰 숨김 처리]
// -----------------------------------------
}
// MARK: - [자바스크립트 통신을 위한 초기화 부분]
// [SEARCH FAST] : [자바스크립트 통신]
func addJavaScriptBridge(){
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> addJavaScriptBridge() :: 자바스크립트 통신 브릿지 추가]")
print("-------------------------------")
print("Bridge :: system")
print("-------------------------------")
print("Bridge :: setMarket")
print("====================================")
print("")
// -----------------------------------------
// [SEARCH FAST] : [자바스크립트 통신 수행]
// -----------------------------------------
// -----------------------------------------
// [브릿지 경로 추가 : 데이터 받을 경로 : 자바스크립트 >> IOS]
// [userContentController 부분에서 message.name 정의]
self.javascriptController.add(self, name: "system")
self.javascriptController.add(self, name: "setMarket")
// -----------------------------------------
// -----------------------------------------
self.javascriptConfig.userContentController = self.javascriptController
//self.main_webview = WKWebView(frame: self.view.bounds, configuration: javascriptConfig)
// -----------------------------------------
}
// MARK: - [자바스크립트 >> IOS 통신 부분]
@available(iOS 8.0, *)
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
// -----------------------------------------
// [SEARCH FAST] : [자바스크립트 통신 수행]
// -----------------------------------------
// -----------------------------------------
// [웹 코드] window.webkit.messageHandlers.system.postMessage("");
// -----------------------------------------
if message.name == "system" {
guard let checkType = message.body as? String // [전달 받은 메시지 확인]
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> userContentController :: system() :: JS >> IOS]")
print("-------------------------------")
print("error :: [type] :: ", type(of: message.body))
print("====================================")
print("")
// [에러 팝업창 알림 표시]
self.showAlert(
type: 0,
tittle: S_FinalData.AL_TITLE,
content: S_FinalData.ERROR_DATA_NULL + " [system]",
okBtb: S_FinalData.AL_OK,
noBtn: ""
)
// [리턴 종료]
return
}
// -----------------------------------------
// [자바스크립트에서 전달 받은 데이터 저장]
let receiveData = message.body as! String
// -----------------------------------------
// [로그 출력 실시]
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> userContentController :: system() :: JS >> IOS]")
print("-------------------------------")
print("전달받은 데이터 :: ", receiveData)
print("-------------------------------")
print("설 명 :: ", "사용자 전체 계정 정보 요청")
print("-------------------------------")
print("로 직 :: ", "setSystem() 메소드 호출 수행 실시")
print("====================================")
print("")
// -----------------------------------------
// [로그인 스키마 데이터 딕셔너리 변환 실시]
var loginDic : Dictionary<String, Any> = [String : Any]()
var loginFlag = false
let loginData = S_Preference().getString(_sKey: S_FinalData.PRE_SCHEME_DATA_LOGIN)
if C_Util().stringNotNull(str: loginData) == true { // [널 값이 아닌 경우]
// [jsonObject to Dictionary 변환 실시]
loginDic = C_Util().jsonObject_To_Dic(jsonString: loginData)
if loginDic != nil && loginDic.count>0 && loginDic.isEmpty == false { // [널 값이 아닌 경우]
// [플래그값 변경]
loginFlag = true
}
}
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> userContentController :: system() :: JS >> IOS]")
print("-------------------------------")
print("설 명 :: ", "[사전] 로그인 스키마 데이터 값 체크 실시]")
print("-------------------------------")
print("스키마 데이터 :: ", loginDic.description)
print("====================================")
print("")
// -----------------------------------------
// [일반 스키마 데이터 딕셔너리 변환 실시]
var callDic : Dictionary<String, Any> = [String : Any]()
var callFlag = false
let callData = S_Preference().getString(_sKey: S_FinalData.PRE_SCHEME_DATA_CALL)
if C_Util().stringNotNull(str: callData) == true { // [널 값이 아닌 경우]
// [jsonObject to Dictionary 변환 실시]
callDic = C_Util().jsonObject_To_Dic(jsonString: callData)
if callDic != nil && callDic.count>0 && callDic.isEmpty == false { // [널 값이 아닌 경우]
// [플래그값 변경]
callFlag = true
}
}
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> userContentController :: system() :: JS >> IOS]")
print("-------------------------------")
print("설 명 :: ", "[사전] 일반 스키마 데이터 값 체크 실시]")
print("-------------------------------")
print("스키마 데이터 :: ", callDic.description)
print("====================================")
print("")
// -----------------------------------------
// [전체 자바스크립트로 전송할 데이터 생성 실시]
var jsonDic : [String: Any] = [
"moco" : S_DeviceID().getDeviceID(), // [디바이스 고유값]
"version" : S_Preference().getString(_sKey: S_FinalData.PRE_MOBILE_VERSION), // [앱 버전 (ex : 1.0.0)]
"code" : S_Preference().getString(_sKey: S_FinalData.PRE_MOBILE_CODE), // [앱 버전 코드 (ex : 1)]
"plat" : S_FinalData.PRE_MOBILE_PLAT, // [모바일 플랫폼]
"token" : S_Preference().getString(_sKey: S_FinalData.PRE_PUSH_TOKEN) // [파이어베이스 푸시 토큰]
] as Dictionary
// [로그인 스키마 데이터]
if loginFlag == true {
jsonDic["loginScheme"] = loginDic // [딕셔너리 삽입]
}
else {
jsonDic["loginScheme"] = "" // [널 데이터 삽입]
}
// [일반 스키마 데이터]
if callFlag == true {
jsonDic["callScheme"] = callDic // [딕셔너리 삽입]
}
else {
jsonDic["callScheme"] = "" // [널 데이터 삽입]
}
// -----------------------------------------
// [전체 Dictionary 데이터를 json으로 변환 실시]
let jsonObj = C_Util().dic_To_JsonObject_String(_dicData: jsonDic)
// -----------------------------------------
// [IOS >> JS 호출 수행 실시]
self.iosToJs_setSystem(_jsonData: jsonObj)
}
// -----------------------------------------
// -----------------------------------------
// [웹 코드] window.webkit.messageHandlers.setMarket.postMessage(jsonString);
// -----------------------------------------
if message.name == "setMarket" {
guard let checkType = message.body as? String // [전달 받은 메시지 확인]
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> userContentController :: setMarket() :: JS >> IOS]")
print("-------------------------------")
print("error :: [type] :: ", type(of: message.body))
print("====================================")
print("")
// [에러 팝업창 알림 표시]
self.showAlert(
type: 0,
tittle: S_FinalData.AL_TITLE,
content: S_FinalData.ERROR_DATA_NULL + " [setMarket]",
okBtb: S_FinalData.AL_OK,
noBtn: ""
)
// [리턴 종료]
return
}
// -----------------------------------------
// [자바스크립트에서 전달 받은 데이터 저장]
let receiveData = message.body as! String
// -----------------------------------------
// [자바스크립트 데이터 방어 로직 추가 실시 : 데이터 널 체크]
if C_Util().stringNotNull(str: receiveData) == true { // [널 값이 아닌 경우]
}
else { // [널 값인 경우]
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> userContentController :: setMarket() :: JS >> IOS]")
print("-------------------------------")
print("전달받은 데이터 :: ", receiveData)
print("-------------------------------")
print("error :: [msg] :: ", S_FinalData.ERROR_DATA_NULL)
print("====================================")
print("")
// [에러 팝업창 알림 표시]
self.showAlert(
type: 0,
tittle: S_FinalData.AL_TITLE,
content: S_FinalData.ERROR_DATA_NULL + " [setMarket]",
okBtb: S_FinalData.AL_OK,
noBtn: ""
)
// [리턴 종료]
return
}
// -----------------------------------------
// [자바스크립트 데이터 방어 로직 추가 실시 : key 값 체크]
if C_Util().stringMultiContains(str: receiveData.lowercased(), array: ["ios", "id"]) == true {
}
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> userContentController :: setMarket() :: JS >> IOS]")
print("-------------------------------")
print("전달받은 데이터 :: ", receiveData)
print("-------------------------------")
print("error :: [msg] :: ", S_FinalData.ERROR_PARSING_KEY)
print("====================================")
print("")
// [에러 팝업창 알림 표시]
self.showAlert(
type: 0,
tittle: S_FinalData.AL_TITLE,
content: S_FinalData.ERROR_PARSING_KEY + " [setMarket]",
okBtb: S_FinalData.AL_OK,
noBtn: ""
)
// [리턴 종료]
return
}
// -----------------------------------------
// [자바스크립트 데이터 방어 로직 추가 실시 : json 데이터 형식 체크 실시]
if C_Util().stringJsonObjectEnable(str: receiveData) == true {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> userContentController :: setMarket() :: JS >> IOS]")
print("-------------------------------")
print("전달받은 데이터 :: ", receiveData)
print("-------------------------------")
print("설 명 :: ", "마켓 이동 정보 전달 받음")
print("-------------------------------")
print("로 직 :: ", "마켓 수행 실시")
print("====================================")
print("")
// [json 형식 문자열을 딕셔너리로 변환 실시]
let jsonDic = C_Util().jsonObject_To_Dic(jsonString: receiveData)
// [세부 json 데이터 받기 실시]
if jsonDic.keys.contains("ios") == true { // [키값이 존재할 경우]
do {
// -----------------------------------------
// [딕셔너리에 세부 데이터 저장 실시]
var dicData : Dictionary<String, Any> = jsonDic["ios"] as! Dictionary<String, Any>
// -----------------------------------------
// [패키지명 및 앱 아이디 확인 실시]
let appId = dicData["id"] as! String // [앱 스토어 이동 아이디]
// -----------------------------------------
// [자바스크립트 전달 받은 데이터 확인 방어 로직 추가 : 에러 체크]
if C_Util().stringNotNull(str: appId) == true
&& appId.hasPrefix("id") == true { // [널 데이터 아님]
// [마켓 이동 수행 실시]
self.goMarketRun(_id: appId)
}
// -----------------------------------------
else { // [널 데이터]
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> userContentController :: setMarket() :: JS >> IOS]")
print("-------------------------------")
print("전달받은 데이터 :: ", receiveData)
print("-------------------------------")
print("error :: [msg] :: ", S_FinalData.ERROR_PARSING_DATA)
print("====================================")
print("")
// [에러 팝업창 알림 표시]
self.showAlert(
type: 0,
tittle: S_FinalData.AL_TITLE,
content: S_FinalData.ERROR_PARSING_DATA + " [setMarket]",
okBtb: S_FinalData.AL_OK,
noBtn: ""
)
// [리턴 종료]
return
}
// -----------------------------------------
}
catch {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> userContentController :: setMarket() :: JS >> IOS]")
print("-------------------------------")
print("전달받은 데이터 :: ", receiveData)
print("-------------------------------")
print("catch :: ", error.localizedDescription)
print("====================================")
print("")
}
}
}
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> userContentController :: setMarket() :: JS >> IOS]")
print("-------------------------------")
print("전달받은 데이터 :: ", receiveData)
print("-------------------------------")
print("error :: [msg] :: ", S_FinalData.ERROR_JSON_PARSING)
print("====================================")
print("")
// [에러 팝업창 알림 표시]
self.showAlert(
type: 0,
tittle: S_FinalData.AL_TITLE,
content: S_FinalData.ERROR_JSON_PARSING + " [setMarket]",
okBtb: S_FinalData.AL_OK,
noBtn: ""
)
// [리턴 종료]
return
}
}
// -----------------------------------------
}
// MARK: - [IOS >> 자바스크립트 통신 부분]
// -----------------------------------------
// [SEARCH FAST] : [자바스크립트 통신]
// -----------------------------------------
func iosToJs_setSystem(_jsonData:String){
// [인풋 데이터 널 체크 수행 실시]
if C_Util().stringNotNull(str: _jsonData) == true {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> iosToJs_setSystem() :: IOS >> JS]")
print("-------------------------------")
print("JS 함수 :: setSystem")
print("-------------------------------")
print("전달할 데이터 :: ", _jsonData)
print("-------------------------------")
print("설 명 :: ", "사용자 전체 계정 정보 전송")
print("====================================")
print("")
// MARK: [json 전송 : 자바스크립트 에서는 object 형식으로 받는다]
self.main_webview!.evaluateJavaScript("setSystem(\(_jsonData))") { (success, error) in
if error != nil {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> iosToJs_setSystem() :: IOS >> JS]")
print("-------------------------------")
print("JS 함수 :: setSystem")
print("-------------------------------")
print("설 명 :: ", "사용자 전체 계정 정보 전송")
print("-------------------------------")
print("전송 결과 [error] :: ", error)
print("====================================")
print("")
}
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> iosToJs_setSystem() :: IOS >> JS]")
print("-------------------------------")
print("JS 함수 :: setSystem")
print("-------------------------------")
print("설 명 :: ", "사용자 전체 계정 정보 전송")
print("-------------------------------")
print("전송 결과 [success] :: ", "OK")
print("====================================")
print("")
}
}
}
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> iosToJs_setSystem() :: IOS >> JS]")
print("-------------------------------")
print("JS 함수 :: setSystem")
print("-------------------------------")
print("설 명 :: ", "사용자 전체 계정 정보 전송")
print("-------------------------------")
print("error :: [msg] :: ", S_FinalData.ERROR_DATA_NULL)
print("====================================")
print("")
// [에러 팝업창 알림 표시]
self.showAlert(
type: 0,
tittle: S_FinalData.AL_TITLE,
content: S_FinalData.ERROR_DATA_NULL + " [setSystem]",
okBtb: S_FinalData.AL_OK,
noBtn: ""
)
// [리턴 종료]
return
}
}
// -----------------------------------------
// [SEARCH FAST] : [자바스크립트 통신]
// -----------------------------------------
func iosToJs_checkResult(_string:String){
// [인풋 데이터 널 체크 수행 실시]
if C_Util().stringNotNull(str: _string) == true {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> iosToJs_checkResult() :: IOS >> JS]")
print("-------------------------------")
print("JS 함수 :: checkResult")
print("-------------------------------")
print("전달할 데이터 :: ", _string)
print("-------------------------------")
print("설 명 :: ", "인증 번호 전송")
print("====================================")
print("")
// MARK: [string 전송 : 36^1]
self.main_webview!.evaluateJavaScript("checkResult('\(_string)')") { (success, error) in
if error != nil {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> iosToJs_checkResult() :: IOS >> JS]")
print("-------------------------------")
print("JS 함수 :: checkResult")
print("-------------------------------")
print("설 명 :: ", "인증 번호 전송")
print("-------------------------------")
print("전송 결과 [error] :: ", error)
print("====================================")
print("")
}
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> iosToJs_checkResult() :: IOS >> JS]")
print("-------------------------------")
print("JS 함수 :: checkResult")
print("-------------------------------")
print("설 명 :: ", "인증 번호 전송")
print("-------------------------------")
print("전송 결과 [success] :: ", "OK")
print("====================================")
print("")
}
}
}
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> iosToJs_checkResult() :: IOS >> JS]")
print("-------------------------------")
print("JS 함수 :: checkResult")
print("-------------------------------")
print("설 명 :: ", "인증 번호 전송")
print("-------------------------------")
print("error :: [msg] :: ", S_FinalData.ERROR_DATA_NULL)
print("====================================")
print("")
// [에러 팝업창 알림 표시]
self.showAlert(
type: 0,
tittle: S_FinalData.AL_TITLE,
content: S_FinalData.ERROR_DATA_NULL + " [checkResult]",
okBtb: S_FinalData.AL_OK,
noBtn: ""
)
// [리턴 종료]
return
}
}
// -----------------------------------------
// [SEARCH FAST] : [자바스크립트 통신]
// -----------------------------------------
func iosToJs_shakeResult(){
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> iosToJs_shakeResult() :: IOS >> JS]")
print("-------------------------------")
print("JS 함수 :: shakeResult")
print("-------------------------------")
print("설 명 :: ", "디바이스 흔들기 이벤트 발생 전달")
print("====================================")
print("")
// MARK: [함수 호출]
self.main_webview!.evaluateJavaScript("shakeResult('\("")')") { (success, error) in
if error != nil {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> iosToJs_shakeResult() :: IOS >> JS]")
print("-------------------------------")
print("JS 함수 :: shakeResult")
print("-------------------------------")
print("설 명 :: ", "디바이스 흔들기 이벤트 발생 전달")
print("-------------------------------")
print("전송 결과 [error] :: ", error)
print("====================================")
print("")
}
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> iosToJs_shakeResult() :: IOS >> JS]")
print("-------------------------------")
print("JS 함수 :: shakeResult")
print("-------------------------------")
print("설 명 :: ", "디바이스 흔들기 이벤트 발생 전달")
print("-------------------------------")
print("전송 결과 [success] :: ", "OK")
print("====================================")
print("")
}
}
}
// -----------------------------------------
// MARK: - [웹뷰 로드 수행 시작 부분]
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
let _startUrl = String(describing: webView.url?.description ?? "")
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> didStartProvisionalNavigation() :: 웹뷰 로드 수행 시작]")
print("-------------------------------")
print("주 소 :: \(_startUrl)")
print("====================================")
print("")
}
// MARK: - [실시간 웹뷰 로드 상태 퍼센트 확인 부분 : 0.1 ~ 1.0]
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
// [0 ~ 1 사이의 실수형으로 결과값이 출력된다 [0 : 로딩 시작, 1 : 로딩 완료]]
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> observeValue() :: 실시간 웹뷰 로드 상태 확인]")
print("-------------------------------")
print("원 본 :: \(Float((self.main_webview?.estimatedProgress)!))")
print("-------------------------------")
print("퍼센트 :: \(Float((self.main_webview?.estimatedProgress)!)*100)")
print("====================================")
print("")
if Float((self.main_webview?.estimatedProgress)!) >= 1.0 { // 0.5 / 0.9 / 1.0
//DispatchQueue.main.asyncAfter(deadline: .now() + 1.3) { // [특정 시간 이후 수행]
DispatchQueue.main.async { // [즉시 수행]
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> observeValue() :: 인트로 화면 닫기 수행 실시]")
print("-------------------------------")
print("퍼센트 :: \(Float((self.main_webview?.estimatedProgress)!)*100)")
print("====================================")
print("")
// -----------------------------------------
// [SEARCH FAST] : [인트로 화면 처리]
self.main_webview?.isHidden = false // [웹뷰 활성]
self.introBg.isHidden = true // [로딩 이미지 비활성]
// -----------------------------------------
// -----------------------------------------
// [쿠키매니저에 저장된 쿠키 확인]
if self.main_webview != nil {
if #available(iOS 11.0, *) {
self.main_webview!.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in
// for cookie in cookies { }
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> observeValue() :: 자바스크립트에 저장된 [개별] 쿠키값 확인 실시]")
print("-------------------------------")
//print("key :: \(cookie.name)")
//print("value :: \(cookie.value)")
print("쿠키 개수 :: ", cookies.count)
print("-------------------------------")
print("쿠키 정보 :: ", cookies)
print("====================================")
print("")
}
}
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> observeValue() :: 자바스크립트에 저장된 [개별] 쿠키값 확인 실시]")
print("-------------------------------")
print("error [에러] :: iOS 11.0 미만 디바이스")
print("====================================")
print("")
}
}
// -----------------------------------------
}
}
}
// MARK: - [웹뷰 로드 수행 완료 부분]
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
let _endUrl = String(describing: webView.url?.description ?? "")
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> didFinish() :: 웹뷰 로드 수행 완료]")
print("-------------------------------")
print("주 소 :: \(_endUrl)")
print("====================================")
print("")
// -----------------------------------------
// [퍼미션 상태 업데이트 체크 수행 실시]
self.permissionState()
// -----------------------------------------
}
// MARK: - [웹뷰 로드 수행 에러 확인]
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
// -----------------------------------------
// [SEARCH FAST] : [웹뷰 에러 코드 감지]
let _nsError = (error as NSError).code
let _errorUrl = String(describing: webView.url?.description ?? "")
// -----------------------------------------
// -----------------------------------------
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> didFail() :: 웹뷰 로드 수행 에러]")
print("-------------------------------")
print("에러 주소 :: \(_errorUrl)")
print("-------------------------------")
print("에러 코드 :: \(_nsError)")
print("-------------------------------")
print("에러 메시지 :: \(S_WebViewErrorCode().checkError(_errorCode: _nsError))")
print("====================================")
print("")
// -----------------------------------------
}
// MARK: - [웹뷰 실시간 url 변경 감지 실시]
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
// -----------------------------------------
// [실시간 웹뷰 주소 변경 감지]
let _shouldUrl = String(describing: webView.url?.description ?? "")
var action: WKNavigationActionPolicy?
defer {
decisionHandler(action ?? .allow)
}
guard let url = navigationAction.request.url else { return }
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> decidePolicyFor() :: 웹뷰 실시간 url 변경 감지]")
print("-------------------------------")
print("주 소 :: \(url)")
print("====================================")
print("")
// -----------------------------------------
// -----------------------------------------
// [전화 이동 실시]
if "\(url)".hasPrefix("tel:") {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> decidePolicyFor() :: 웹뷰 실시간 url 변경 감지]")
print("-------------------------------")
print("주 소 :: \(url)")
print("-------------------------------")
print("로 직 :: 전화 걸기 이동 실시")
print("====================================")
print("")
self.goTelIntent(_url: "\(url)")
}
// -----------------------------------------
// -----------------------------------------
// [이메일 이동 실시]
if "\(url)".hasPrefix("mailto:") {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> decidePolicyFor() :: 웹뷰 실시간 url 변경 감지]")
print("-------------------------------")
print("주 소 :: \(url)")
print("-------------------------------")
print("로 직 :: 메일 보내기 이동 실시")
print("====================================")
print("")
self.goMailIntent(_url: "\(url)")
}
// -----------------------------------------
// -----------------------------------------
// [문자 이동 실시]
if "\(url)".hasPrefix("sms:") {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> decidePolicyFor() :: 웹뷰 실시간 url 변경 감지]")
print("-------------------------------")
print("주 소 :: \(url)")
print("-------------------------------")
print("로 직 :: 문자 보내기 실시")
print("====================================")
print("")
self.goSmsIntent(_url: "\(url)")
}
// -----------------------------------------
// -----------------------------------------
// [하이퍼링크 이동 실시]
if "\(url)".hasPrefix("l:") {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> decidePolicyFor() :: 웹뷰 실시간 url 변경 감지]")
print("-------------------------------")
print("주 소 :: \(url)")
print("-------------------------------")
print("로 직 :: 하이퍼링크 이동 실시")
print("====================================")
print("")
self.goLinkIntent(_url: "\(url)")
}
// -----------------------------------------
}
// MARK: - [웹뷰 실시간 url status 상태 코드 감지 실시]
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse,
decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
// -----------------------------------------
// [SEARCH FAST] : [웹뷰 에러 코드 감지]
// -----------------------------------------
// [핸들러 처리 실시]
defer {
decisionHandler(.allow)
}
var _url = ""
// -----------------------------------------
if let url = navigationResponse.response.url {
_url = url.description
}
else {
_url = ""
}
// -----------------------------------------
// [응답 상태 값 확인 실시]
if let response = navigationResponse.response as? HTTPURLResponse {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> WKNavigationResponse() :: 웹뷰 실시간 url status 상태 코드 감지]")
print("-------------------------------")
print("주 소 :: \(_url)")
print("-------------------------------")
print("상태 코드 :: \(response.statusCode)")
print("====================================")
print("")
// MARK: [에러 응답 코드 인 경우]
///*
// -----------------------------------------
if response.statusCode >= 400 {
// [무한 루프 방지 위해 기존에 저장된 에러 값 체크 실시]
let errorCheck = String(describing:S_Preference().getString(_sKey: S_FinalData.PRE_WEBVIEW_RELOAD))
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> WKNavigationResponse() :: 웹뷰 실시간 url status 상태 코드 감지]")
print("-------------------------------")
print("로 직 :: 에러 발생 로직 처리 실시")
print("-------------------------------")
print("[기존] 저장된 에러 발생 여부 :: \(errorCheck)")
print("====================================")
print("")
// -----------------------------------------
// MARK: [에러가 중복 실행된 경우 >> 에러 팝업창 표시]
if errorCheck != nil
&& errorCheck.count>0
&& errorCheck.trim().equals(_string: "") == false
&& errorCheck.trim().equals(_string: "1") == true { // MARK: [에러 팝업창]
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> WKNavigationResponse() :: 웹뷰 실시간 url status 상태 코드 감지]")
print("-------------------------------")
print("로 직 :: 재시도 최종 실패 >> [에러 팝업창] 웹뷰 로드 에러 표시 실시")
print("====================================")
print("")
// MARK: [실시간으로 웹뷰 에러가 발생한 경우 >> 에러 팝업창 표시]
// MARK: [사용자가 다시 접속 시 에러 발생한 경우 >> SceneDelegate >> sceneWillEnterForeground >> 앱 재기동]
// [에러 팝업창 표시]
///*
self.showAlertWebview(
tittle:S_FinalData.AL_TITLE,
content:"URL : " + "\(_url)" + "\n" + "\n" +
"Error : " + S_FinalData.ERROR_WEBVIEW_LOAD + "\n" + "\n" +
"HTTPURLResponse : " + "\(response.statusCode)" + "\n" + "\n" +
"TIME : " + String(describing: C_Util().getNowDateTime24()) + "",
//_url:_url, // [에러 주소]
_url: S_FinalData.WV_LOAD_MAIN_ENZ_URL, // [메인 주소]
okBtb:S_FinalData.AL_OK,
noBtn:""
)
// */
}
// -----------------------------------------
// MARK: [처음으로 에러가 발생한 경우 >> 프리퍼런스 데이터 널 인 경우 :: 재시도 기회 제공]
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> WKNavigationResponse() :: 웹뷰 실시간 url status 상태 코드 감지]")
print("-------------------------------")
print("로 직 :: 에러 최초 발생 >> [재시도] 웹 페이지 다시 로드 수행 실시")
print("====================================")
print("")
// -----------------------------------------
// MARK: [웹뷰 재호출 프리퍼런스 값 지정 실시]
S_Preference().setString(_sKey: S_FinalData.PRE_WEBVIEW_RELOAD, _sValue: "1")
// -----------------------------------------
// -----------------------------------------
// [SEARCH FAST] : [웹뷰 세션 및 캐시 삭제 수행]
self.clearWebViewChahe()
// -----------------------------------------
// -----------------------------------------
// [웹뷰 객체 지우기 실시]
if self.main_webview != nil {
// [웹뷰 제거 실시]
self.main_webview?.removeFromSuperview()
self.main_webview = nil
// [자바스크립트 통신 사용 초기화]
self.javascriptController = WKUserContentController()
}
// -----------------------------------------
// -----------------------------------------
// [SEARCH FAST] : [인트로 화면 처리]
self.introBg.isHidden = false // [로딩 이미지 활성]
// -----------------------------------------
// -----------------------------------------
// [SEARCH FAST] : [웹뷰 로드 수행 실시]
self.init_WebView(_loadUrl: S_FinalData.WV_LOAD_MAIN_ENZ_URL)
// -----------------------------------------
}
}
// -----------------------------------------
else { // MARK: [정상 응답 코드 인 경우]
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> WKNavigationResponse() :: 웹뷰 실시간 url status 상태 코드 감지]")
print("-------------------------------")
print("로 직 :: [정상] 웹뷰 이동 로직 처리 실시")
print("====================================")
print("")
// MARK: [웹뷰 재호출 프리퍼런스 값 지정 실시]
S_Preference().setString(_sKey: S_FinalData.PRE_WEBVIEW_RELOAD, _sValue: "")
}
// -----------------------------------------
}
}
// MARK: - [웹뷰 모달창 닫힐때 앱 종료현상 방지]
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - [웹뷰 alert 팝업창 처리]
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String,
initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void){
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> runJavaScriptAlertPanelWithMessage() :: 웹뷰 alert 팝업창 처리]")
print("-------------------------------")
print("message :: \(message)")
print("====================================")
print("")
// [팝업창 정의 실시]
let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "확인", style: .default, handler: { (action) in completionHandler() }))
self.present(alertController, animated: true, completion: nil)
}
// MARK: - [웹뷰 confirm 팝업창 처리]
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> runJavaScriptConfirmPanelWithMessage() :: 웹뷰 confirm 팝업창 처리]")
print("-------------------------------")
print("message :: \(message)")
print("====================================")
print("")
// [팝업창 정의 실시]
let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "취소", style: .default, handler: { (action) in completionHandler(false) }))
alertController.addAction(UIAlertAction(title: "확인", style: .default, handler: { (action) in completionHandler(true) }))
self.present(alertController, animated: true, completion: nil)
}
// MARK: [웹뷰 에러 발생 시 표시 팝업창]
var webviewAlert : UIAlertController? = nil
func showAlertWebview(tittle:String, content:String, _url:String, okBtb:String, noBtn:String) {
// [메인 큐에서 비동기 방식 실행 : UI 동작 실시]
DispatchQueue.main.async {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> showAlertWebview() :: 웹뷰 에러 발생 팝업창 표시 실시]")
print("-------------------------------")
print("제 목 :: \(tittle)")
print("-------------------------------")
print("내 용 :: \(content)")
print("-------------------------------")
print("주 소 :: \(_url)")
print("====================================")
print("")
// [UIAlertController 객체 정의 실시]
self.webviewAlert = UIAlertController(
title: tittle + "\n",
message: content + "\n",
preferredStyle: UIAlertController.Style.alert
)
// [인풋으로 들어온 확인 버튼이 nil 아닌 경우]
if(okBtb != "" && okBtb.count>0){
let okAction = UIAlertAction(title: okBtb, style: .default) { (action) in
//----------------------------------
// MARK: [확인 버튼 클릭 이벤트 내용 정의 실시]
if self.main_webview != nil {
// ----------------------------------
// [SEARCH FAST] : [프리퍼런스 값 초기화 실시]
S_Preference().webViewReloadClear()
// ----------------------------------
// [SEARCH FAST] : [웹뷰 세션 및 캐시 삭제 수행]
self.clearWebViewChahe()
// ----------------------------------
// [SEARCH FAST] : [인트로 화면 처리]
self.main_webview?.isHidden = true // [웹뷰 비활성]
self.introBg.isHidden = false // [로딩 이미지 활성]
// ----------------------------------
let url = URL (string: _url) // [웹뷰 로드 주소]
let request = URLRequest(url: url! as URL)
self.main_webview!.load(request)
// ----------------------------------
}
// ----------------------------------
// [팝업창 초기화 실시]
self.webviewAlert = nil
//----------------------------------
return
//----------------------------------
}
self.webviewAlert!.addAction(okAction) // 버튼 클릭 이벤트 객체 연결
}
// [인풋으로 들어온 취소 버튼이 nil 아닌 경우]
if(noBtn != "" && noBtn.count>0){
let noAction = UIAlertAction(title: noBtn, style: .default) { (action) in
// -----------------------------------------
// [취소 버튼 클릭 이벤트 내용 정의 실시]
// -----------------------------------------
// [팝업창 초기화 실시]
self.webviewAlert = nil
// -----------------------------------------
return
// -----------------------------------------
}
self.webviewAlert!.addAction(noAction) // 버튼 클릭 이벤트 객체 연결
}
// [alert 팝업창 활성 실시]
self.present(self.webviewAlert!, animated: false, completion: nil)
}
}
// MARK: - [웹뷰 쿠키 및 캐시 데이터 초기화 메소드]
func clearWebViewChahe(){
// -----------------------------------------
// [SEARCH FAST] : [웹뷰 세션 및 캐시 삭제 수행]
// -----------------------------------------
// ---------------------------------------------
if self.main_webview != nil { // [웹뷰가 널이 아닌 경우]
// -----------------------------------------
// [전체 방문 데이터 지우기]
/*
WKWebsiteDataStore.default().fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), completionHandler: {
(records) -> Void in
for record in records{
WKWebsiteDataStore.default().removeData(ofTypes: record.dataTypes, for: [record], completionHandler: {})
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> clearWebViewChahe() :: 웹뷰 전체 방문 데이터 삭제 수행]")
print("-------------------------------")
print("type :: removeData")
print("====================================")
print("")
}
})
// */
// -----------------------------------------
// -----------------------------------------
// [원하는 캐시 데이터만 골라서 삭제]
///*
let websiteDataTypes = NSSet(array:
[WKWebsiteDataTypeDiskCache, // 디스크 캐시
WKWebsiteDataTypeMemoryCache, // 메모리 캐시
WKWebsiteDataTypeCookies, // 웹 쿠키,
WKWebsiteDataTypeOfflineWebApplicationCache, // 앱 캐시
WKWebsiteDataTypeWebSQLDatabases, // 웹 SQL 데이터 베이스
WKWebsiteDataTypeIndexedDBDatabases // 데이터 베이스 정보
//WKWebsiteDataTypeLocalStorage // 로컬 스토리지
//WKWebsiteDataTypeSessionStorage // 세션 스토리지
])
let date = NSDate(timeIntervalSince1970: 0)
WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes as! Set, modifiedSince: date as Date, completionHandler:{
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> clearWebViewChahe() :: 웹뷰 쿠키 및 세션 데이터 삭제 수행]")
print("-------------------------------")
print("type :: removeData")
print("====================================")
print("")
})
// */
// -----------------------------------------
// -----------------------------------------
// [설치된 날짜 가져오는 코드]
let urlToDocumentsFolder: URL? = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last
let installDate = try? FileManager.default.attributesOfItem(atPath: (urlToDocumentsFolder?.path)!)[.creationDate] as! Date
// [설치된 날짜부터 지금까지의 cookie all clear]
URLSession.shared.configuration.httpCookieStorage?.removeCookies(since: installDate!)
// [로그 출력 실시]
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> clearWebViewChahe() :: 웹뷰 쿠키 및 세션 데이터 삭제 수행]")
print("-------------------------------")
print("type :: URLSession removeCookies")
print("====================================")
print("")
// -----------------------------------------
// -----------------------------------------
// [웹뷰에 저장된 쿠키 데이터 확인 실시]
if #available(iOS 11.0, *) {
self.main_webview!.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in
if cookies.count>0 { // [저장된 쿠키가 있는 경우]
for cookie in cookies {
self.main_webview!.configuration.websiteDataStore.httpCookieStore.delete(cookie, completionHandler: {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> clearWebViewChahe() :: 웹뷰 쿠키 및 세션 데이터 삭제 수행]")
print("-------------------------------")
print("설 명 :: ", "자바스크립트에 저장된 [개별] 쿠키 값 제거 실시")
print("-------------------------------")
print("key :: \(cookie.name)")
print("-------------------------------")
print("value :: \(cookie.value)")
print("====================================")
print("")
})
}
}
else { // [저장된 쿠키가 없는 경우]
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> clearWebViewChahe() :: 웹뷰 쿠키 및 세션 데이터 삭제 수행]")
print("-------------------------------")
print("결 과 :: 저장된 쿠키 없음")
print("====================================")
print("")
}
}
}
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> clearWebViewChahe() :: 웹뷰 쿠키 및 세션 데이터 삭제 실패]")
print("-------------------------------")
print("error [에러] :: iOS 11.0 미만 디바이스")
print("====================================")
print("")
}
// -----------------------------------------
}
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> clearWebViewChahe() :: 웹뷰 쿠키 및 세션 데이터 삭제 실패]")
print("-------------------------------")
print("error [에러] :: main_webview 웹뷰 객체 널 (NULL) 임")
print("====================================")
print("")
}
// -----------------------------------------
}
} // [클래스 종료]
반응형
'투케이2K 유틸파일' 카테고리의 다른 글
Comments