简体   繁体   English

从应用内部链接到Safari“添加到主屏幕”?

[英]Link to Safari “Add to Home Screen” from inside app?

My app has a custom URL scheme and can use deep linking to jump straight from a URL to some content. 我的应用程序有自定义URL方案,可以使用深层链接直接从URL跳转到某些内容。 I'd love to replicate the behaviour in the recent Facebook Groups app, which allows the user to hit an "Add to Home Screen" button in the app, which takes them out to a custom-designed localhost page in Safari, allowing them to tap Safari's Share and Add to Home Screen buttons, which will then add an icon to their home screen which, when tapped, takes them into the Groups app, and to the specific group in question. 我想在最近的Facebook Groups应用程序中复制这种行为,该应用程序允许用户点击应用程序中的“添加到主屏幕”按钮,将其带到Safari中的自定义设计的localhost页面,允许他们点击Safari的“共享”和“添加到主屏幕”按钮,然后在其主屏幕上添加一个图标,当点击该图标时,将其带入群组应用程序以及相关的特定群组。

My problem is that if I send my custom URL scheme deep link to Safari, before the user could tap Add to Home Screen, it'll follow that link and just end up right back in my app. 我的问题是,如果我将我的自定义URL方案深度链接发送到Safari,在用户可以点击添加到主屏幕之前,它将跟随该链接,并在我的应用程序中直接返回。 I need to send something to Safari which won't actually follow the deep link, but will still link to it if the user adds it to their home screen, and I have no idea how to do that. 我需要向Safari发送一些实际上不会跟随深层链接的内容,但如果用户将其添加到主屏幕,它仍会链接到它,我不知道该怎么做。

Facebook Groups' generated links in the Safari address bar look something like this, have they perhaps embedded JavaScript directly into the URL?: Facebook群组在Safari地址栏中生成的链接看起来像这样,是否可以将JavaScript直接嵌入到URL中?:

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

Any idea what that is, and how I might do something similar? 知道那是什么,以及我如何做类似的事情?

If you paste these characters into any online base64 decoder, you'll get the following: 如果将这些字符粘贴到任何在线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>

Instead of #### there is the following: 而不是####有以下内容:

<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>');

So I believe their implementation is as follows: 所以我相信它们的实现如下:

1) There is a web server embedded in the application (something like RoutingHTTPServer ). 1)应用程序中嵌入了Web服务器(类似于RoutingHTTPServer )。 It's running on some port like 5555 and configured to return a page with contents like: 它在某个端口上运行,如5555,并配置为返回包含以下内容的页面:

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

The syntax is wrong, but the idea is to replace the current URL ( http://localhost:5555 ) with that base64 encoded data. 语法错误,但想法是用该base64编码数据替换当前URL( http:// localhost:5555 )。

2) When you tap add to home page in the app, it opens the link http://localhost:5555 in the Safari, the web server inside the app responds with the web page, containing a script that replaces the URL with base64 encoded data (this data contains the current time, when the script was generated) 2)当你在应用程序中点击add to home page ,它会在Safari中打开链接http://localhost:5555 ,应用程序内的Web服务器会响应网页,其中包含用base64编码替换URL的脚本data(此数据包含生成脚本时的当前时间)

3)From the contents of the base64 encoded data you can see that there are two checks: 3)从base64编码数据的内容中可以看到有两个检查:

a)if the app is running not in Safari, but standalone a)如果应用程序不在Safari中运行,而是独立运行

b)if some time has passed since the script was generated b)如果脚本生成后已经过了一段时间

If any of these statements is true, you are redirected into the app using deep link. 如果这些陈述中的任何一个属实,您将使用深层链接重定向到应用程序。 If both of them are false, the page prompting user to add link to home screen is shown (that's what I replaced with #### ). 如果它们都为假,则会显示提示用户将链接添加到主屏幕的页面(这是我用####替换的内容)。

When the link is added to home screen, all these scripts and web pages are embedded into that link as base64 encoded data. 当链接添加到主屏幕时,所有这些脚本和网页都作为base64编码数据嵌入到该链接中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM