从应用程序内部 Link 到 Safari "Add to Home Screen"?

Link to Safari "Add to Home Screen" from inside app?

我的应用程序有一个自定义 URL 方案,可以使用深度 linking 从 URL 直接跳转到某些内容。我很想复制最近 Facebook Groups 应用程序中的行为,它允许用户点击应用程序中的 "Add to Home Screen" 按钮,将他们带到 Safari 中定制设计的 localhost 页面,允许他们点击 Safari 的共享和添加到主屏幕按钮,然后将一个图标添加到他们的主屏幕,当点击该图标时,他们将进入组应用程序,并进入相关的特定组。

我的问题是,如果我将我的自定义 URL scheme deep link 发送到 Safari,在用户可以点击添加到主屏幕之前,它将遵循 link 和刚回到我的应用程序。我需要向 Safari 发送一些东西,它实际上不会跟随深度 link,但如果用户将它添加到他们的主屏幕,它仍然会 link,我不知道该怎么做.

Facebook 群组在 Safari 地址栏中生成的 link 看起来像这样,他们是否可能将 JavaScript 直接嵌入到 URL 中?:

data:text/html;charset=UTF-8;base64, <tens of thousands of characters in an alpha-numeric string>

知道那是什么吗?我该如何做类似的事情?

如果您将这些字符粘贴到任何在线 base64 解码器中,您将得到以下内容:

<!DOCTYPE HTML>
<html>

<head id="htmlHead">
    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;" />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="apple-mobile-web-app-capable" content="no" />
    <title>Promote Groups or Pages</title>
    <link rel="apple-touch-icon-precomposed" href="data:image/png;base64,
</head>

<body>
    <a id="redirect" href="fb-groups://group?id=1503507809911018&s=s"></a>
</body>

</html>
<script type="text/javascript">
    function jump() {
        var e = document.getElementById('redirect');
        var ev = document.createEvent('MouseEvents');
        ev.initEvent('click', true, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
        e.dispatchEvent(ev);
        window.close();
    }
    if (("standalone" in window.navigator) && window.navigator.standalone) {
        document.body.style.backgroundColor = '#000000';
        jump();
    } else {
        var time = 1422371365;
        var timeout = new Date().getTime() / 1000;
        if (timeout > time + 4) {
            document.write('</head><body bgcolor="#fff"><div align="center"></div>');
            jump();
        } else {
            document.write(
              ####
                          )}
    }
</script>

代替####的是:

<style>
    html,
    body,
    div,
    span,
    object,
    iframe,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6 {
        margin: 0;
        padding: 0;
        border: 0;
        font-size: 100%;
        vertical-align: baseline;
        font-family: HelveticaNeue-Light, sans-serif;
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        -khtml-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none
    }
    a {
        color: inherit;
        text-decoration: none
    }
    #headerBox {
        width: 100%;
        height: 48px;
        border-bottom: .5px solid #979797;
        background-color: #F6F6F6;
        text-align: center
    }
    #popoverBox {
        position: absolute;
        bottom: 15px;
        width: 290px;
        height: 132px;
        -webkit-border-radius: 11px;
        border-radius: 11px;
        background-color: #2891F7;
        border: none;
        margin-left: -145px;
        left: 50%
    }
    #popoverBox:after {
        top: 100%;
        left: 50%;
        border: solid transparent;
        content: " ";
        height: 0;
        width: 0;
        position: absolute;
        pointer-events: none;
        border-color: rgba(40, 145, 247, 0);
        border-top-color: #2891F7;
        border-width: 13px;
        margin-left: -13px
    }
    .icon {
        margin-bottom: 5px
    }
    #groupIconContainer {
        margin-left: 40px;
        width: 60px;
        float: left;
        height: 100%
    }
    #groupIcon {
        height: 60px;
        width: 60px;
        -webkit-border-radius: 14px;
        border-radius: 14px;
        background-color: #FFF;
        margin-top: 25px
    }
    #addToHomeIconContainer {
        margin-right: 40px;
        width: 60px;
        float: right;
        height: 100%
    }
    #addToHomeIcon {
        margin-top: 25px
    }
    #arrow {
        margin: 0 auto;
        display: block;
        margin-top: 49px
    }
    #infoText {
        color: #141823;
        font-size: 18px;
        line-height: 28px;
        text-align: center;
        width: 280px;
        height: 160px;
        margin: auto;
        position: absolute;
        top: 0;
        left: 0;
        bottom: 0;
        right: 0
    }
    .iconLabelContainer {
        font-size: 12px;
        color: #FFF;
        line-height: 14px;
        width: 100px;
        height: 30px;
        margin-left: -20px;
        text-align: center
    }
    #groupCoverImage {
        box-sizing: border-box;
        -webkit-box-sizing: border-box;
        background-size: cover;
        background-position: center;
        background-image: url("data:image/png;base64,
        width: 52px;
        height: 52px;
        border-radius: 50%;
        position: relative;
        top: 4px;
        left: 4px;
        border: 0.5px solid rgba(0, 0, 0, 0.10);
    }
</style>

<body>
    <div id="headerBox"><span style="font-size:17px;color:#2891F7;line-height:20px;position:relative;top:13.5px"><a href="fb-groups://">Отмена</a></span>
    </div>
    <div id="infoText">Коснитесь кнопки
        <svg style="vertical-align:text-bottom" width="22px" height="30px" viewbox="0 0 44 60" version="1.1">
            <defs></defs>
            <g id="Final" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
                <g id="Add-Group-to-Home-Screen" transform="translate(-299.000000, -459.000000)">
                    <g id="Tap-+-below-+-Share-Icon" transform="translate(231.000000, 458.000000)">
                        <g id="share-icon" transform="translate(60.000000, 0.000000)">
                            <path d="M20.4,12 L30,2.4 L39.6,12" id="Shape" stroke="#3F75FF" stroke-width="2"></path>
                            <path d="M30,39.0000013 L30,2.7996" id="Shape" stroke="#3F75FF" stroke-width="2"></path>
                            <rect id="Rectangle-path" x="0" y="0" width="60" height="60"></rect>
                            <path d="M20.2682927,20 L9,20 L9,60 L51,60 L51,20 L39.7317073,20" id="Shape" stroke="#3F75FF" stroke-width="2"></path>
                        </g>
                    </g>
                </g>
            </g>
        </svg> ниже,
        <br>Затем коснитесь &ldquo;Добавить на основной экран&rdquo;</div>
    <div id="popoverBox">
        <div id="groupIconContainer">
            <div id="groupIcon" class="icon">
                <div id="groupCoverImage"></div>
            </div>
            <div class="iconLabelContainer">Promote Groups or Pages</div>
            <!-- Replace with dynamic name -->
        </div>
        <div id="addToHomeIconContainer">
            <svg id="addToHomeIcon" width="60px" height="60px" viewbox="0 0 120 120" version="1.1">
                <defs></defs>
                <g id="Add-Group-to-Home-Screen-Spec" transform="translate(-410.000000, -802.000000)">
                    <g id="Add-to-Home-Screen" transform="translate(367.000000, 802.000000)">
                        <g id="Add-to-Home-Screen-Icon" transform="translate(43.000000, 0.000000)">
                            <rect id="Rectangle-6" fill="#FFFFFF" x="0" y="0" width="120" height="120" rx="28"></rect>
                            <rect id="Rectangle-6" fill="#686870" x="25" y="25" width="70" height="70" rx="15"></rect>
                            <path d="M58,58 L58,46.991617 C58,45.8978404 58.8954305,45 60,45 C61.1122704,45 62,45.8916773 62,46.991617 L62,58 L73.008383,58 C74.1021596,58 75,58.8954305 75,60 C75,61.1122704 74.1083227,62 73.008383,62 L62,62 L62,73.008383 C62,74.1021596 61.1045695,75 60,75 C58.8877296,75 58,74.1083227 58,73.008383 L58,62 L46.991617,62 C45.8978404,62 45,61.1045695 45,60 C45,58.8877296 45.8916773,58 46.991617,58 L58,58 Z" id="Rectangle-8" fill="#FFFFFF"></path>
                        </g>
                    </g>
                </g>
            </svg>
            <div class="iconLabelContainer">Добавить на
                <br>основной экран</div>
        </div>
        <svg id="arrow" width="12px" height="20px" viewbox="0 0 24 40" version="1.1">
            <defs></defs>
            <g id="Explorations" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
                <g id="Add-Group-to-Home-Screen" transform="translate(-307.000000, -847.000000)" stroke-linecap="round" stroke="#FFFFFF" stroke-width="5">
                    <g id="Group" sketch:type="MSLayerGroup" transform="translate(30.000000, 752.000000)">
                        <path d="M297,132 L280,115 L297,98" id="Path-35" transform="translate(288.500000, 115.000000) rotate(-180.000000) translate(-288.500000, -115.000000) "></path>
                    </g>
                </g>
            </g>
        </svg>
    </div>
    <div id="popoverNub"></div>');

所以我相信他们的实现如下:

1) 应用程序中嵌入了一个 Web 服务器(类似于 RoutingHTTPServer)。它在某些端口上 运行,例如 5555,并配置为 return 一个页面,内容如下:

<HTML><script>window.location.href=[data:text/html;charset=UTF-8;base64, tens of thousands of characters in an alpha-numeric string]</script></HTML>

语法错误,但想法是用该 base64 编码数据替换当前的 URL (http://localhost:5555)。

2) 当您在应用程序中点击 add to home page 时,它会在 Safari 中打开 link http://localhost:5555,应用程序内的 Web 服务器响应网页,其中包含用 base64 编码数据替换 URL 的脚本(此数据包含当前时间,即生成脚本的时间)

3)从base64编码数据的内容可以看出有两个校验:

a) 如果应用程序 运行 不是在 Safari 中,而是独立的

b)如果脚本生成后已经过去了一段时间

如果这些陈述中的任何一个为真,您将使用 deep link 重定向到应用程序。 如果两者都为假,则会显示提示用户将 link 添加到主屏幕的页面(这是我用 #### 替换的页面)。

当 link 添加到主屏幕时,所有这些脚本和网页都作为 base64 编码数据嵌入到 link 中。