투케이2K

21. (TWOK/UTIL) [Ios/Swift] C_MoveApp - 외부 앱 실행 , 스키마 실행 , 앱 설치 여부 , 마켓 이동 , 사파리 기반 외부 링크 이동 본문

투케이2K 유틸파일

21. (TWOK/UTIL) [Ios/Swift] C_MoveApp - 외부 앱 실행 , 스키마 실행 , 앱 설치 여부 , 마켓 이동 , 사파리 기반 외부 링크 이동

투케이2K 2022. 3. 25. 22:23

[설 명]

프로그램 : Ios / Swift

설 명 : 외부 앱 실행 , 스키마 실행 , 앱 설치 여부 , 마켓 이동 , 사파리 기반 외부 링크 이동

 

[소스 코드]

 

import Foundation
import UIKit
import SafariServices


// MARK: [extension 정의 실시 : 뷰 컨트롤러]
extension UIViewController {
    
    
    // MARK: - [클래스 설명]
    /*
    // -----------------------------------------
    1. 외부 링크 및 외부 앱 이동 클래스
    2. 외부 앱 실행 , 스키마 실행 , 앱 설치 여부 , 마켓 이동 , 사파리 기반 외부 링크 이동
    // -----------------------------------------
    */
    
    
    
    
    
    // MARK: - [사파리 기반 : 외부 브라우저 링크 이동 실시]
    func goSafariBrowserOuter(_url : String){
        
        /*
        // -----------------------------------------
        [goSafariBrowserOuter 메소드 설명]
        // -----------------------------------------
        1. 필요 info plist : App Transport Security Settings >> Allow Arbitrary Loads >> YES
        // -----------------------------------------
        2. 필요 import : import SafariServices
        // -----------------------------------------
        3. 호출 방법 : self.goSafariBrowserOuter(_url: "https://www.naver.com")
        // -----------------------------------------
        */
        
        // [주소 널 체크 및 http 주소를 포함하는지 확인]
        if _url != nil && _url.count>0 && _url != ""
            && _url.hasPrefix("http") == true || _url.hasPrefix("https") == true {
            print("")
            print("====================================")
            print("[C_MoveApp >> goSafariBrowserOuter() :: [외부 이동] 사파리 기반 브라우저 링크 이동 실시]")
            print("-------------------------------")
            print("url :: ", _url)
            print("====================================")
            print("")
            
            // [방어 로직 추가 실시]
            if C_Util().stringIsUrlParsing(string: _url) == false {
                print("")
                print("====================================")
                print("[C_MoveApp >> goSafariBrowserOuter() :: [외부 이동] 사파리 기반 브라우저 링크 이동 실패]")
                print("error :: URL 주소 형식 아님 >> 한글 인코딩 , 이스케이프 문자 체크 필요")
                print("====================================")
                print("")

                // [종료 실시]
                return
            }
            
            // [외부로 사파리 기반 브라우저 링크 열기 실시]
            DispatchQueue.main.async{
                UIApplication.shared.open(URL(string: _url)!, options: [:])
            }
        }
        else {
            print("")
            print("====================================")
            print("[C_MoveApp >> goSafariBrowserOuter() :: [외부 이동] 사파리 기반 브라우저 링크 이동 실패]")
            print("-------------------------------")
            print("설명 :: 접속 주소를 다시 확인해주세요")
            print("-------------------------------")
            print("url :: ", _url)
            print("====================================")
            print("")
        }
    }
    
    
    
    
    
    // MARK: - [사파리 기반 : 내부 브라우저 링크 이동 실시]
    func goSafariBrowserInner(_url : String){
        
        /*
        // -----------------------------------------
        [goSafariBrowserInner 메소드 설명]
        // -----------------------------------------
        1. 필요 info plist : App Transport Security Settings >> Allow Arbitrary Loads >> YES
        // -----------------------------------------
        2. 필요 import : import SafariServices
        // -----------------------------------------
        3. 호출 방법 : self.goSafariBrowserInner(_url: "https://www.naver.com")
        // -----------------------------------------
        */
        
        // [주소 널 체크 및 http 주소를 포함하는지 확인]
        if _url != nil && _url.count>0 && _url != ""
            && _url.hasPrefix("http") == true || _url.hasPrefix("https") == true {
            print("")
            print("====================================")
            print("[C_MoveApp >> goSafariBrowserInner() :: [내부 이동] 사파리 기반 브라우저 링크 이동 실시]")
            print("-------------------------------")
            print("url :: ", _url)
            print("====================================")
            print("")
            
            // [앱 내부로 사파리 기반 브라우저 링크 열기 실시]
            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("[C_MoveApp >> goSafariBrowserInner() :: [내부 이동] 사파리 기반 브라우저 링크 이동 실패]")
            print("-------------------------------")
            print("설명 :: 접속 주소를 다시 확인해주세요")
            print("-------------------------------")
            print("url :: ", _url)
            print("====================================")
            print("")
        }
    }
    
    
    
    
    
    // MARK: - [외부 앱 , 스키마 앱 외부 열기 수행 실시]
    func goAppRun(_scheme : String, _id : String) {
        
        /*
        // -----------------------------------------
        [goAppRun 메소드 설명]
        // -----------------------------------------
        1. https://www.apple.com/kr/ 사이트에 접속해서 특정 앱 주소를 확인합니다
        // -----------------------------------------
        2. 크롬 앱 id 확인 : https://apps.apple.com/kr/app/google-chrome/id535886823
           - id535886823 부분을 사용해서 마켓 이동을 실행합니다
        // -----------------------------------------
        3. 크롬 스키마 확인 : googlechrome://
        // -----------------------------------------
        4. 로직 : 스키마 이동 외부앱이 설치되어 있을 경우 >> 외부 앱 실행 (스키마) / 외부 앱이 설치되지 않은 경우 앱 스토어 이동 (앱 id)
        // -----------------------------------------
        5. 호출 예시 : self.goAppRun(_scheme: "googlechrome://", _id: "id535886823")
        // -----------------------------------------
        */
        
        // [메인 큐에서 비동기 방식 실행 : UI 동작 실시]
        DispatchQueue.main.async {
            
            // [인풋 데이터 로그 출력 실시]
            print("")
            print("====================================")
            print("[C_MoveApp >> goAppRun() :: 외부 앱 및 스키마 이동 [수행]]")
            print("-------------------------------")
            print("_appSchme :: ", _scheme)
            print("-------------------------------")
            print("_storeUrl :: ", _id)
            print("====================================")
            print("")
            
            
            // [사전 인풋값 데이터 널 체크 수행 실시]
            if _scheme != nil && _scheme.count > 0 && _scheme != ""
                && _id != nil && _id.count > 0 && _id != "" {
            }
            else {
                print("")
                print("====================================")
                print("[C_MoveApp >> goAppRun() :: 외부 앱 및 스키마 이동 [실패]]")
                print("-------------------------------")
                print("error :: 사전 인풋 데이터 체크 NULL 발생")
                print("-------------------------------")
                print("_appSchme :: ", _scheme)
                print("-------------------------------")
                print("_storeUrl :: ", _id)
                print("====================================")
                print("")
                return
            }
            
            
            // [스키마 및 앱 스토어 이동 주소 매핑 실시]
            let _appSchme = _scheme
            let _storeUrl = "itms-apps://itunes.apple.com/app/" + _id
            
            
            // [URL 타입 체크 실시]
            guard let appsUrl = URL(string: _appSchme)
            else {
                print("")
                print("====================================")
                print("[C_MoveApp >> goAppRun() :: 외부 앱 및 스키마 이동 [에러]]")
                print("-------------------------------")
                print("error :: ", "URL 파싱 에러")
                print("====================================")
                print("")
                return
            }

            
            // [외부 앱 실행 실시]
            UIApplication.shared.open(appsUrl, completionHandler: { (success) in
                if (success) {
                    print("")
                    print("====================================")
                    print("[C_MoveApp >> goAppRun() :: 외부 앱 및 스키마 이동 [성공]]")
                    print("-------------------------------")
                    print("_appSchme :: ", _appSchme)
                    print("-------------------------------")
                    print("_storeUrl :: ", _storeUrl)
                    print("====================================")
                    print("")
                }
                else {
                    // [id 값이 널인 경우 체크해서 널이 아닌 경우만 마켓 이동 실시]
                    if _id != nil && _id.count > 0 && _id != "" {
                        
                        // [마켓 이동 로직 처리 실시]
                        print("")
                        print("====================================")
                        print("[C_MoveApp >> goAppRun() :: 외부 앱 및 스키마 이동 [실패]]")
                        print("-------------------------------")
                        print("error :: 외부 앱이 설치 되지 않은 상태 >> 외부 앱 설치 진행 실시")
                        print("-------------------------------")
                        print("_appSchme :: ", _appSchme)
                        print("-------------------------------")
                        print("_storeUrl :: ", _storeUrl)
                        print("====================================")
                        print("")
                        
                        // [버전 별 처리 실시]
                        if #available(iOS 10.0, *) {
                            UIApplication.shared.open(URL(string: _storeUrl)!, options: [:], completionHandler: nil)
                        }
                        else {
                            UIApplication.shared.openURL(URL(string: _storeUrl)!)
                        }
                    }
                    else {
                        print("")
                        print("====================================")
                        print("[C_MoveApp >> goAppRun() :: 외부 앱 및 스키마 이동 [실패]]")
                        print("-------------------------------")
                        print("error :: ", "_id 값 널 임")
                        print("====================================")
                        print("")
                    }
                }
            })
        }
    }
    
    
    
    
    
    // MARK: - [특정 앱 설치 여부 확인]
    func checkInstallApp(_scheme : String) -> String {
        
        /*
        // -----------------------------------------
        [checkInstallApp 메소드 설명]
        // -----------------------------------------
        1. 크롬 앱 스키마 확인 : googlechrome://
        // -----------------------------------------
        2. 호출 예시 : self.checkInstallApp(_scheme: "googlechrome://")
        // -----------------------------------------
        3. 참고 [1] : LSApplicationQueriesSchemes 추가 방법
          - https://blog.naver.com/kkh0977/222627386138
        // -----------------------------------------
        4. 참고 [2] : canOpenURL 사용 시는 LSApplicationQueriesSchemes 에서 스키마 명을 등록해줘야한다 [googlechrome]
        // -----------------------------------------
        5. 참고 [3] : 크롬으로 기본 브라우저 설정 시 추가적으로 LSApplicationQueriesSchemes 에서 http , https 를 등록해줘야한다
        // -----------------------------------------
        */
        
        
        // [결과 반환 변수 선언 실시 : Y , N]
        var returnData = "N"
        
        
        // [로그 출력 실시]
        print("")
        print("====================================")
        print("[C_MoveApp >> checkInstallApp() :: [외부 앱] 설치 여부 확인 수행]")
        print("-------------------------------")
        print("_scheme :: ", _scheme)
        print("====================================")
        print("")
        
        
        // [세마포어 선언 : 프로그램 로직을 동기화 구현]
        let semaphore = DispatchSemaphore(value: 0) // [value 0 값은 대기 상태 선언]
        
        
        // [URL 타입 체크 실시]
        if _scheme != nil && _scheme.count > 0 && _scheme != "" {
            // 외부앱 이동 로직 처리 실시
            if let openStore = URL(string: _scheme), UIApplication.shared.canOpenURL(openStore) {
                print("")
                print("====================================")
                print("[C_MoveApp >> checkInstallApp() :: [외부 앱] 설치 된 상태]")
                print("-------------------------------")
                print("_scheme :: ", _scheme)
                print("====================================")
                print("")
                
                // [리턴 결과 데이터 삽입]
                returnData = "Y"
                
                // [세마 포어 신호 알림]
                semaphore.signal()
            }
            else {
                print("")
                print("====================================")
                print("[C_MoveApp >> checkInstallApp() :: [외부 앱] 설치 안된 상태]")
                print("-------------------------------")
                print("_scheme :: ", _scheme)
                print("====================================")
                print("")
                
                // [리턴 결과 데이터 삽입]
                returnData = "N"
                
                // [세마 포어 신호 알림]
                semaphore.signal()
            }
        }
        else {
            print("")
            print("====================================")
            print("[C_MoveApp >> checkInstallApp() :: [외부 앱] 설치 상태 확인 실패]")
            print("-------------------------------")
            print("error :: ", "_scheme 값 널 임")
            print("-------------------------------")
            print("_scheme :: ", _scheme)
            print("====================================")
            print("")
            
            // [리턴 결과 데이터 삽입]
            returnData = "N"
            
            // [세마 포어 신호 알림]
            semaphore.signal()
        }
        
        
        // [세마포어 확인 대기]
        semaphore.wait()
        
        
        // [로그 출력 실시]
        print("")
        print("====================================")
        print("[C_MoveApp >> checkInstallApp() :: [외부 앱] 설치 상태 결과 반환 값]")
        print("-------------------------------")
        print("_scheme :: ", _scheme)
        print("-------------------------------")
        print("returnData :: ", returnData)
        print("====================================")
        print("")
        
        
        // [리턴 데이터 반환]
        return returnData
    }
    
    
    
    
    
    // MARK: - [마켓 이동 실시]
    func goMarketRun(_id : String) {
        
        /*
        // -----------------------------------------
        [goAppRun 메소드 설명]
        // -----------------------------------------
        1. https://www.apple.com/kr/ 사이트에 접속해서 특정 앱 주소를 확인합니다
        // -----------------------------------------
        2. 크롬 앱 id 확인 : https://apps.apple.com/kr/app/google-chrome/id535886823
          - id535886823 부분을 사용해서 마켓 이동을 실행합니다
        // -----------------------------------------
        3. 호출 예시 : self.goMarketRun(_id: "id535886823")
        // -----------------------------------------
        */
        
        // [메인 큐에서 비동기 방식 실행 : UI 동작 실시]
        DispatchQueue.main.async {
            
            // [인풋 데이터 로그 출력 실시]
            print("")
            print("====================================")
            print("[C_MoveApp >> goMarketRun() :: 앱 스토어 이동 실시 [수행]]")
            print("-------------------------------")
            print("_id :: ", _id)
            print("====================================")
            print("")
            
            
            // [사전 인풋값 데이터 널 체크 수행 실시]
            if _id != nil && _id.count > 0 && _id != "" {
            }
            else {
                print("")
                print("====================================")
                print("[C_MoveApp >> goMarketRun() :: 앱 스토어 이동 실시 [실패]]")
                print("-------------------------------")
                print("error :: 사전 인풋 데이터 체크 NULL 발생")
                print("-------------------------------")
                print("_id :: ", _id)
                print("====================================")
                print("")
                return
            }
            
            
            // [앱 스토어 이동 주소 매핑 실시]
            let _storeUrl = "itms-apps://itunes.apple.com/app/" + _id
            
            
            // [id 값이 널인 경우 체크해서 널이 아닌 경우만 마켓 이동 실시]
            if _id != nil && _id.count > 0 && _id != "" {
                print("")
                print("====================================")
                print("[C_MoveApp >> goMarketRun() :: 앱 스토어 이동 실시 [성공]]")
                print("-------------------------------")
                print("_storeUrl :: ", _storeUrl)
                print("====================================")
                print("")
                
                // [버전별 처리 실시]
                if #available(iOS 10.0, *) {
                    UIApplication.shared.open(URL(string: _storeUrl)!, options: [:], completionHandler: nil)
                }
                else {
                    UIApplication.shared.openURL(URL(string: _storeUrl)!)
                }
                
            }
            else {
                print("")
                print("====================================")
                print("[C_MoveApp >> goMarketRun() :: 앱 스토어 이동 실시 [실패]]")
                print("-------------------------------")
                print("error :: ", "_id 값 널 임")
                print("====================================")
                print("")
            }
        }
    }
    
    
} // [extension 종료]

 

반응형
Comments