투케이2K

46. (ios/swift) 애플리케이션 바로 가기 메뉴 만들기 실시 - UIApplicationShortcutItem 본문

IOS

46. (ios/swift) 애플리케이션 바로 가기 메뉴 만들기 실시 - UIApplicationShortcutItem

투케이2K 2021. 11. 7. 21:11
반응형

[개발 환경 설정]

개발 툴 : XCODE

개발 언어 : SWIFT


[필요 설정]


[소스 코드 : SceneDelegate]

import UIKit
import SafariServices

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    
    // [윈도우 객체 전역 변수]
    var window: UIWindow?

    
    // [shortCut 아이템 확인 전역 변수]
    var savedShortCutItem: UIApplicationShortcutItem!
    
    
    // [shortCut type 정의]
    let googleWebsiteShortcutId = "googleWebsiteShortcutId"

    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        print("")
        print("===============================")
        print("[SceneDelegate >> willConnectTo]")
        print("[설명 :: UI창 선택적 구성 및 제공된 UI창에 Scene 연결]")
        print("===============================")
        print("")

        guard let _ = (scene as? UIWindowScene) else { return }
        
        // [ShortCut 접속 여부 확인 실시]
        if let shortcutItem = connectionOptions.shortcutItem {
            self.savedShortCutItem = shortcutItem
        }
    }

    
    
    func sceneDidDisconnect(_ scene: UIScene) {
        print("")
        print("===============================")
        print("[SceneDelegate >> sceneDidDisconnect]")
        print("[설명 :: 시스템에 의해서 Scene 해제 : background 상태 및 session 삭제]")
        print("===============================")
        print("")
    }

    
    
    func sceneDidBecomeActive(_ scene: UIScene) {
        print("")
        print("===============================")
        print("[SceneDelegate >> sceneDidBecomeActive]")
        print("[설명 :: Scene 활성화 및 사용자 이벤트에 응답 실시]")
        print("===============================")
        print("")
        
        // [ShortCut 접속한 경우 핸들러 전송]
        if self.savedShortCutItem != nil {
            _ = self.handleShortCutItem(shortcutItem: self.savedShortCutItem)
        }
    }

    
    
    func sceneWillResignActive(_ scene: UIScene) {
        print("")
        print("===============================")
        print("[SceneDelegate >> sceneWillResignActive]")
        print("[설명 :: Scene 활성 상태 해제 및 사용자 이벤트에 대한 응답 중지]")
        print("[상태 :: 사용자 앱 백그라운드 전환 실시]")
        print("===============================")
        print("")
        
        
        /*
        [UIApplicationShortcutItem 메뉴 설명 실시]
        1. localizedTitle : 홈 화면 동적 빠른 작업에 필요한 사용자에게 표시되는 제목
        2. localizedSubtitle : 홈 화면 동적 퀵 액션에 대한 사용자가 볼 수 있는 선택적 자막
        3. type : 수행할 빠른 작업 유형을 식별하는 데 사용하는 필수 앱별 문자열
        4. icon : 홈 화면 동적 빠른 작업에 대한 선택적 아이콘
        5. userInfo : 앱이 홈 화면 빠른 작업을 수행할 때 사용하기 위해 제공할 수 있는 선택적 앱별 정보
        */
        
        
        // [바로 가기 메뉴 추가 실시 : 구글 웹사이트 이동]
        let googleWebsiteShortcut = UIApplicationShortcutItem(
            type: googleWebsiteShortcutId,
            localizedTitle: "Google Website",
            localizedSubtitle: "Open Google Website",
            icon: UIApplicationShortcutIcon(type: .search),
            userInfo: nil)

        
        // [UIApplicationShortcutItem 추가 실시]
        UIApplication.shared.shortcutItems = [googleWebsiteShortcut]
        
        
        // [UIApplicationShortcutItem 삭제 실시]
        //UIApplication.shared.shortcutItems = []
    }

    
    
    func sceneWillEnterForeground(_ scene: UIScene) {
        print("")
        print("===============================")
        print("[SceneDelegate >> sceneWillEnterForeground]")
        print("[설명 : Scene 포그라운드 실행]")
        print("===============================")
        print("")
    }

    
    
    func sceneDidEnterBackground(_ scene: UIScene) {
        print("")
        print("===============================")
        print("[SceneDelegate >> sceneDidEnterBackground]")
        print("[설명 : Scene 백그라운드 실행]")
        print("===============================")
        print("")
    }
    
    
    
    func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
        print("")
        print("===============================")
        print("[SceneDelegate >> windowScene UIApplicationShortcutItem]")
        print("[설명 : ShortCuts 접속 확인]")
        print("[shortcut : \(shortcutItem.type)]")
        print("===============================")
        print("")
        // [로직 처리 핸들러 지정]
        let handled = self.handleShortCutItem(shortcutItem: shortcutItem)
        completionHandler(handled)
    }
    
    
    
    func handleShortCutItem(shortcutItem: UIApplicationShortcutItem) -> Bool {
        switch shortcutItem.type {
        case self.googleWebsiteShortcutId :
            print("")
            print("===============================")
            print("[SceneDelegate >> handleShortCutItem]")
            print("[shortcut : \(self.googleWebsiteShortcutId)]")
            print("[로직 : 구글 웹 사이트 이동 실시]")
            print("===============================")
            print("")
            self.A_IntentGoogle(url: "https://www.google.com")
            break
            
        default:
            print("")
            print("===============================")
            print("[SceneDelegate >> handleShortCutItem]")
            print("[shortcut : default]")
            print("[로직 : ShortCuts 접속 확인]")
            print("===============================")
            print("")
            break
        }
        return true
    }
    
    
    
    func A_IntentGoogle (url : String){
        print("")
        print("===============================")
        print("[SceneDelegate >> A_IntentGoogle]")
        print("[설명 : 구글 웹브라우저 이동 실시]")
        print("[url : \(url)]")
        print("===============================")
        print("")
        
        // [Main 스토리보드 지정 실시]
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        
        // [Main 스토리보드에 포함된 개별 스토리보드 id 및 컨트롤러 지정]
        guard let rootVC = storyboard.instantiateViewController(identifier: "A_IntentGoogleVC") as? A_IntentGoogle
        else {
            print("")
            print("==============================")
            print("SceneDelegate >> A_IntentGoogle() :: 뷰 컨트롤러 확인 실패")
            print("==============================")
            print("")
            return
        }
        print("")
        print("==============================")
        print("SceneDelegate >> A_IntentGoogle() :: 뷰 컨트롤러 연결 실시")
        print("뷰 컨트롤러 : ", "A_IntentGoogle")
        print("==============================")
        print("")
        let rootNC = UINavigationController(rootViewController: rootVC)
        self.window?.rootViewController = rootNC
        self.window?.makeKeyAndVisible()
        
        let topViewController = self.window?.rootViewController as? UINavigationController
        let currentVC = topViewController?.topViewController as? A_IntentGoogle
        
        // 뷰 컨트롤러 : url 스키마로 접속을 체크하는 곳으로 데이터 전송
        currentVC?.intentWebSiteLink(_url: url)
    }

} // [클래스 종료]

[소스 코드 : A_IntentGoogle]

import UIKit
import SafariServices

class A_IntentGoogle: UIViewController {
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        print("")
        print("===============================")
        print("[A_IntentGoogle >> viewDidLoad() :: 뷰 로드 실시]")
        print("===============================")
        print("")
    }
    
    
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("")
        print("===============================")
        print("[A_IntentGoogle >> viewWillAppear() :: 뷰 로드 완료]")
        print("===============================")
        print("")
    }
        
    
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        print("")
        print("===============================")
        print("[A_IntentGoogle >> viewDidAppear() :: 뷰 화면 표시]")
        print("===============================")
        print("")
        
        // [뷰 컨트롤러 포그라운드, 백그라운드 상태 체크 설정 실시]
        NotificationCenter.default.addObserver(self, selector: #selector(checkForeground), name: UIApplication.willEnterForegroundNotification, object: nil) // [포그라운드]
        NotificationCenter.default.addObserver(self, selector: #selector(checkBackground), name: UIApplication.didEnterBackgroundNotification, object: nil) // [백그라운드]
        
        // [포그라운드 처리 실시]
        checkForeground()
    }
        
    
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        print("")
        print("===============================")
        print("[A_IntentGoogle >> viewWillDisappear() :: 뷰 정지 상태]")
        print("===============================")
        print("")
    }
        
    
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        print("")
        print("===============================")
        print("[A_IntentGoogle >> viewDidDisappear() :: 뷰 종료 상태]")
        print("===============================")
        print("")
        
        // [뷰 컨트롤러 포그라운드, 백그라운드 상태 체크 해제 실시]
        NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil) // [포그라운드]
        NotificationCenter.default.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil) // [백그라운드]
    }
    
    
    
    // [포그라운드 및 백그라운드 상태 처리 메소드 작성]
    @objc func checkForeground() {
        print("")
        print("===============================")
        print("[A_IntentGoogle >> checkForeground() :: 뷰 컨트롤러 포그라운드]")
        print("===============================")
        print("")
    }
    @objc func checkBackground() {
        print("")
        print("===============================")
        print("[A_IntentGoogle >> checkBackground() :: 뷰 컨트롤러 백그라운드]")
        print("===============================")
        print("")
    }
    
    
    
    func intentWebSiteLink(_url : String){
        // [http 주소를 포함한지 확인]
        if _url.hasPrefix("http") == true || _url.hasPrefix("https") == true {
            print("")
            print("===============================")
            print("[A_IntentGoogle >> intentWebSiteLink() :: 웹사이트 이동 실시]")
            print("url : ", _url)
            print("===============================")
            print("")
            // [방법 [1]]
            //UIApplication.shared.open(URL(string: _url)!, options: [:])
            
            
            // [방법 [2]]
            guard let url = URL(string: _url) else { return }
            let safariViewController = SFSafariViewController(url: url)
            DispatchQueue.main.async { [weak self] in
                self?.present(safariViewController, animated: false, completion: nil)
            }
        }
        else {
            print("")
            print("===============================")
            print("[A_IntentGoogle >> intentWebSiteLink() :: 접속 주소를 다시 확인해주세요]")
            print("url : ", _url)
            print("===============================")
            print("")
        }
    }

} // [클래스 종료]

[결과 출력]


 

반응형
Comments