달력

42024  이전 다음

  • 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

'deeplink'에 해당되는 글 1건

  1. 2017.12.14 javascript로 웹에서 App 열기

 ios 도 그렇고 android도 그렇고  url 형식으로 앱에 접근이 가능하다. 앱이 설치 되어 있다면 앱을 실행 시키고, 앱이 설치되어 있지 않다면 앱 설치 페이지로 전환 시켜주는게 가능하다. 그리고 앱에 특정 데이터를 전달 해서 원하는 기능을 제공 할 수 있다.


일단 기본 적인 android 와 ios 둘 다 메커니즘은 동일하다. user-action을 통한 이벤트여야지 동작을 한다는 것과, setTimeout을 이용해서 마켓으로 이동을 시켜야 한다는 것. 

소스로 확인 해보자.


    var androidPackage = "my.app.package";
    var appleAppId = ""; // id1401934913 형식으로 itunes url에 나오는 앱아이디.
    var androidMarketUrl = "market//detail?id="+androidPackage;
    var iosMarketUrl = "http://itunes.apple.com/kr/app/" + appleAppID;
    function goStore(){
        var startTime = +new Date();
        setTimeout(
            function() {
                var now = +new Date();
                if ( now - startTime < 1000){
                    var marketUrl = "";
                    if( isAndroid ){
                        marketUrl = androidMarketUrl;
                    }else if( isiOS ){
                        marketUrl = iosMarketUrl;
                    }
                    location.href = marketUrl;
            }
        , 500)
        if ( isAndroid ){
            openAndroid();
        }else if ( isiOS ){
            openiOS();
        }
    }

    function openAndroid(){
        var userAgent = navigator.userAgent.toLowerCase();
        if ( userAgent.match(/chrome/) ){
            location.href = "intent://hostName?param1=someValue1¶m2=someValue2/"
                                        +"#Intent;scheme=schemeName;action=android.intent.action.VIEW;"
                                        +"category=android.Intent.category.BROWSABLE;package="+androidPackage;
        }else{
            var iframe = document.createElement( 'iframe' );
            iframe.style.visivility = 'hidden';
            iframe.src = 'schemeName://hostName?param1=someValue1¶m2=someValue2';
            document.body.appendChild(iframe);
            document.body.removeChild(iframe);
        }
    }

    function openiOS(){
        location.href = "schemeName://hostName?param1=someValue1¶m2=someValue2";
    }

안드로이드는 버전에 따리 분기 처리해줘야 하는데 요즘은 schemeName 을 intent로 고정해서 사용한다고 한다. 이전 버전에서는 iframe을 이용하는게 제일 깔끔하다고 어디서 봐서 iframe으로 사용 했다. 

중요한 부분은 3 함수 모두 사용자 액션 기반으로 발동이 되어야 한다는 것이다. onload나 그런 것이 아닌 dom을 클릭해서 실행 하던지 comfirm() (confirm만으로는 안된다. dom을 클릭해야만 발동되더라..) 을 통해 처리 해야 한다는 것이다.

안드로이드에서는 schemeName 과 hostName은 Manifest파일에 실행 될 activity 안에 아래 내용을 붙여 주면 된다.


<activity android:name="name" android:label="label" android:theme="theme">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"> </action>
        <category android:name="android.intent.category.BROWSABLE"></category>
        <category ........=""> </category>
        <data android:host="hostName" android:scheme="schemeName"></data>
    </intent-filter>
</activity>

이렇게 넣어주면된다. 보면 action과 category도 맞춰줘야하는 건 쉽게 알 실듯 여러분들은 똑똑하니까

iOS 의 경우는 캡쳐로 때움.ㅋ

identifier랑 schemeName이랑 동일하게 하면 된다. 다르게 해도 되는 지는 모르겠다.ㅋ  iOS에서는 hostName은 따로 설정하지 않아도 된다.


자 이제 실행시킨 앱에서 파라미터를 받아서 어떻게 처리 하는지를 보자.

안드로이드 먼저

아까 실행될 acitivity의 onCreate에서 작업하면 된다.

    if( getIntent().getScheme() != null && getIntent.getScheme().equals( "schemeName" ) ){
        String someValue1 = getIntent().getData().getQueryParameter( "param1" );
        String someValue2 = getIntent().getData().getQUeryParameter( "param2" );
        //do....
    }

아래는 iOS 11 기준으로. iOS 는 버전별로 어디어디서 실행되는지는 모르겠다. iOS8 까지는 아래대로 하면 문제없을듯 하다. AppDelegate에 아래 함수를 수정해주자. 없으면 추가해주고.

    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        guard let query = url.query else {return false}
        let querys = query.components(separatedBy: "&")
        var keyValue = Dictionary<string,string>()      
        for q in querys {
            guard let point = q.index(of: "=") else {continue}
            let keyEnd = q.index(before: point)
            let valueStart = q.index(after: point)
            
            let key = String(q[q.startIndex...keyEnd])
            var value = String(q[valueStart..< q.endIndex])  
            keyValue[key] = value
        }
        //dosomethings..
        return true
    }

나의 경우는 http url 을 파라미터로 넘겨서 앱에 있는 webview를 해당 url 로 넘겨주는 것을 구현했는데, iOS에서 병신같은 일이 일어났다.

파라미터로 넘긴 url 이  http://www.someDomain.co.kr/folder1/page.php/ 였다고 가정을 하면 끝에 /를 붙였다고 페이지 로딩 직후 바로 이전 url로 넘겨버리는 엄청난....병신같은...................ㅡㅡ 첨엔 내가 소스를 잘못 짠줄 알았는데 알고보니 / 때문이였다. 안드로이드는 상관없이 잘된다... WKWebView 버그인지는 잘 모르겠다. 근데, ㅋ 웃긴게 openurl로 넘겨온게 아니면 슬러쉬 있든 없든 잘된다는 거다.ㅋ


    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        guard let query = url.query else {return false}
        let querys = query.components(separatedBy: "&")
        var keyValue = Dictionary<string,string>()
        
        for q in querys {
            guard let point = q.index(of: "=") else {continue}
            let keyEnd = q.index(before: point)
            let valueStart = q.index(after: point)
            
            let key = String(q[q.startIndex...keyEnd])
            var value = String(q[valueStart..< q.endIndex])  
            
            //url 끝에 슬러쉬 붙었다고 페이지 이동안됌. 이뭐병.... 끝에 슬러쉬를 없애주자...
            while value.hasSuffix("/"){
                let suffixIndex = value.index(value.endIndex, offsetBy: -1)
                value = String(value[value.startIndex..< suffixIndex])
            }
            keyValue[key] = value
        }
        //dosomethings..
        return true
    }

이러니 잘되네............. 결국 저 슬러쉬 문제를 정리하기 위해서 겸사겸사 쓴 포스트.

Posted by
|