iOS 添加快捷方式到桌面

前言

最近在乘車碼裏面作了一個需求,添加快捷方式到桌面,點擊桌面圖標打開app進入對應頁面。功能很小,可是涉及的知識點不少,涉及 openURL、HTML、JavaScript、Data URI Scheme、Base64 等。經過這個需求順便將這些知識都學習了,而後整理出來。javascript

原理

操做過程其實很簡單,就是在 app 裏面經過 Safari 瀏覽器打開一個引導頁面,而後點擊添加到主屏幕,以下圖html

,再點「添加」就行。後面點擊圖標直接打開app,跳轉到對應頁面。這個過程裏面涉及兩個問題前端

  1. 添加到桌面時保存的就是引導頁面 url,點擊打開的時候爲啥不是打開引導頁面,而是直接跳轉到 app裏面,這個如何實現?
  2. 沒網的狀況下點擊圖標,打開頁面如何能加載頁面內容並打開app呢?

第一個問題的解決辦法是這樣的,從 app 裏面打開引導頁面默認是非全屏的,可是從手機桌面點擊 icon 打開是全屏的,所以能夠根據是不是全屏來執行對應腳本,若是是全屏那麼久執行腳本跳轉到app,若是非全屏則添加相應的 HTML 內容,呈現引導頁。判斷是不是全屏的 JavaScript 方法是 window.navigator.standalone,爲 true 是全屏,爲 false 則非全屏。java

第二個問題解決辦法是這樣的,引導頁面須要在沒網的狀況下也能加載,那麼顯然是首先就要保存在咱們app裏面,在app裏面經過 openURL 打開的頁面沒辦法直接打開這個app裏面的引導頁面,所以咱們寫一個一箇中轉的HTML頁面保存在咱們服務器上,獲得這個服務器上 HTML 的url。而後使用 Data URI Scheme 技術,將咱們本地的 HTML 頁面轉成一個字符串放到服務器HTML 的 url 問號後面。當經過到 openURL 打開這個拼裝好的 url 後,成功加載這個頁面。而後經過 JavaScript 方法,獲取到咱們本地引導頁 HTML 轉的字符串,使用 window.location.replace()直接將當前頁面替換爲本地頁面,而後添加到桌面的就是添加的本地頁面,這裏保存的連接就是經過 Data URI Scheme 將本地頁面生成的字符串。web

步驟

1. 開發引導頁面

引導頁面 HTML 代碼以下objective-c

<!DOCTYPE html>
<html>
<head>
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="default">
    <meta content="text/html charset=UTF-8" http-equiv="Content-Type" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no" />
    <link rel="apple-touch-icon" href="TransitCodeIconImageData">
    <title>TransitCodeAppTitle</title>
</head>
<body>
    <a href="TransitCodeAppScheme" id="qbt" style="display:none"></a>
   <span id="msg"></span>
</body>
<script> if (window.navigator.standalone == true) { var lnk = document.getElementById("qbt").click(); } else { document.getElementById("msg").innerHTML='<center style="position:absolute;left:0;top:0;width: 100%;height: 100%;"> <img style="z-index:1;width:100%" src="TransitCodeLaunchImageData" /> </center>'; } </script>
</html>
複製代碼

代碼中包含的一些字符串含義以下: TransitCodeIconImageData:快捷方式在桌面的圖標 TransitCodeAppTitle:快捷方式的名稱 TransitCodeAppScheme:跳轉頁面對應的 scheme,好比 hellobike://hellobike.com/transitcode/home TransitCodeLaunchImageData:引導頁背景圖瀏覽器

通用這幾個字符串代替實際內容,主要是爲了後面統一替換,也方便其餘業務方使用,否則寫死了就只能乘車碼一個業務使用了。服務器

這裏經過 window.navigator.standalone 能夠知道引導頁是不是全屏展現,若是是全屏那麼跳轉到 app 對應頁面,非全屏則插入具體 HTML 內容,展現引導內容。app

2. 使用 Data URI Scheme 技術將引導頁轉爲一個字符串

代碼以下學習

- (NSString *)oppcreateDesktopWithPreUrl:(NSString *)preUrl iconUrl:(NSString *)iconUrl launchImageUrl:(NSString *)launchImageUrl appTitle:(NSString *)title scheme:(NSString *)scheme {
    if ([preUrl length] == 0) {
        return nil;
    }
    NSString *contentHtmlString = [self contentHtmlWithIconImageString:iconUrl launchImageString:launchImageUrl title:title appScheme:scheme];
    contentHtmlString = [contentHtmlString base64EncodedString];
    NSString *DataURIString = [NSString stringWithFormat:@"data:text/html;charset=utf-8;base64,%@",contentHtmlString];
    NSString *urlString = [NSString stringWithFormat:@"%@%@", preUrl, DataURIString];
    return urlString;
}

-(NSString *)contentHtmlWithIconImageString:(NSString *)iconImageString launchImageString:(NSString *)launchImageString title:(NSString *)title appScheme:(NSString *)scheme{
    NSString *contentHtmlPath = [self getcontentHTMLTempletPath];
    NSString *contentHtmlString = [NSString stringWithContentsOfFile:contentHtmlPath encoding:NSUTF8StringEncoding error:nil];
    /*替換字符串*/
    contentHtmlString = [contentHtmlString stringByReplacingOccurrencesOfString:@"TransitCodeIconImageData" withString:iconImageString];
    contentHtmlString = [contentHtmlString stringByReplacingOccurrencesOfString:@"TransitCodeLaunchImageData" withString:launchImageString];
    contentHtmlString = [contentHtmlString stringByReplacingOccurrencesOfString:@"TransitCodeAppTitle" withString:title];
    contentHtmlString = [contentHtmlString stringByReplacingOccurrencesOfString:@"TransitCodeAppScheme" withString:scheme];
    return contentHtmlString;
}

- (NSString *)getcontentHTMLTempletPath{
    NSString *path = [[JYTransitCodeBundle() resourcePath] stringByAppendingPathComponent:@"/content.html"];
    return path;
}
複製代碼

能夠簡單理解 Data URI Scheme 技術就是講一個文件,圖片或者HTML文件等等,經過 Base64 加密等轉爲字符串放到 HTML 裏面直接加載,這樣就不用請求服務器了。這裏咱們須要將上面介紹的本地的引導 HTML 頁面轉爲一個字符串,後面要將這個字符串拼到服務器HTML url 後面。

看代碼能夠知道,經過 getcontentHTMLTempletPath 方法拿到本地 HTML 文件路徑,而後將裏面內容進行替換爲乘車碼快捷方式相關內容。而後將 HTML 內容轉爲 base64 編碼。最後經過將 base64 編碼按照特定格式拼接便可,這裏是 [NSString stringWithFormat:@"data:text/html;charset=utf-8;base64,%@",contentHtmlString];以 data:text/html;charset=utf-8;base64, 開頭,後面咱們能夠看到存儲的時候也是保存的這個。

3. 打開服務器 HTML 頁,用本地引導頁替換

用上面生成的字符串拼到服務器 HTML 頁面url (這裏我是直接將 HTML 文件放到 cdn 上面而後拿到連接)後面,代碼以下

- (void)addShortcutToDesk {
    NSString *preUrl = @"https://m.hellobike.com/resource/app/transitcode/Wqwc6vYfE-hrud7-nBDeU.html";
    preUrl = [NSString stringWithFormat:@"%@?dataurl=", kSafeStr(preUrl)];
    NSString *title = @"哈囉乘車碼";
    NSString *scheme = @"hellobike://hellobike.com/transitcode/home";
    NSString *iconUrl = @"https://m.hellobike.com/resource/app/transitcode/OZtmwCABaAMfiaE2IAC6E.png";
    NSString *launchImageUrl = @"https://m.hellobike.com/resource/app/transitcode/SRJ3IqkkcZIn2MPAzVmS4.png";
    NSString *urlString = [self oppcreateDesktopWithPreUrl:preUrl iconUrl:iconUrl launchImageUrl:launchImageUrl appTitle:title scheme:scheme];

    UIApplication *application = [UIApplication sharedApplication];
    NSURL *URL = [NSURL URLWithString:urlString];

    if (@available(iOS 10.0, *)) {
        [application openURL:URL options:@{}
           completionHandler:^(BOOL success) {
        }];
    } else {
        [application openURL:URL];
    }
}
複製代碼

這裏服務器保存的 HTML頁面很簡單,加載後主要就是經過上面拼接的連接獲取本地引導頁內容,而後加載引導頁,代碼以下

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
</body>
<script type="text/javascript"> const dataurl = ''; var url = location.search; if (url && url.length > 1 && url.indexOf('?dataurl=') !== -1) { url = url.replace("?dataurl=", ""); window.location.replace(url); } else { window.location.replace(dataurl); } </script>
</html>
複製代碼

經過 location.search 方法能夠獲取到拼接好的url內容,而後拿到咱們拼上去的內容,使用 window.location.replace 方法來從新進行內容替換,就能夠展現咱們本地的引導頁了。此時展現就是非全屏展現,跟從快捷鍵打開不同。

4. 根據引導頁指示操做

引導頁面有詳細流程圖,按圖操做保存便可。

後記

這個需求功能很簡單,可是涉及的知識仍是很多,涉及到前端方面屬於本身比較薄弱的方面,所以須要多積累一些相關知識才更好完成相關需求。

相關文章
相關標籤/搜索