淺談 Google App Indexing

Standard

App Indexing (圖片取自 App Indexing – Google Developers)

前言

上一篇 談到 Facebook 推出的 App Links 標準,為 Apps 之間的連結跳轉帶來解決方案,而 2015 的 Google I/O 大會推出的 Android M,其中一個亮點就是推出它們對於跨 Apps 跳轉的解決方案 — 也叫 App Links — 但它是透過 json 檔設定實現,這邊就不多做介紹了,有興趣可看 HOKO 的這篇介紹

而這篇要介紹的是關於 Google 的 App Indexing ,在這個行動裝置當道的時代,App Indexing 的出現便是為了讓 Google Search 亦能搜尋到 App 中的內容,甚至點擊搜尋結果就直接讓使用者透過 Deep Link 連到 App 內的特定頁面。

還是有些抽象?那麼先來看看 Google Developers 釋出的這支影片,有趣地介紹了實際應用的情境。

Continue reading

關於 AppLinks 兩三事

Standard

App Links

前言

在行動裝置時代,使用者更常停留在 App 中瀏覽資訊(像是 Facebook),而相對地在 Web 的停留時間就降低了。過去我們在 Web 上透過超連結搭起不同網站之間的橋,而在 App 與 App 之間又如何做到這件事呢?

當然,我們可以透過 URL Scheme 開啟應用程式,但我們並無法得知世上每個 App 的 URL Scheme,甚至是應用程式某個頁面 Deep Link 的 Scheme,而且萬一哪天增修了那又該如何?

我最近一部分的工作就在研究如何加強 App 於 Mobile Web 上的連結體驗,其實各大廠早提出了自己的構想及標準,例如 Google 提出的 App Indexing,以及 Facebook 提出的 App Links。

今天就 App Links 的部份做個簡單筆記與實作參考。App Indexing 等下次有空再寫文介紹囉。

Continue reading

[Web][JavaScript] 有安裝 App 便開啟 App (透過 App URL scheme),若無則導去下載 (Google Play/App Store) 的 workaround

Standard

前言

製作案件上遇到的需求,若使用者有安裝 App 便開啟 App (透過 App URL scheme),若無則導去下載 (Google Play/App Store)。

在 App 內這件事應該是可掌控的(在自己做的 App 中攔截特定網址做處理),但在網頁上要做到這件事就有點麻煩了。一般常見的作法是擺個 Smart Banner,不過只有 iOS Safari 原生就支援,其他的得靠 jQuery Smart Banner(前陣子我也貢獻了修正 Windows Phone 相關錯誤的 pull request :P) 這類的第三方 plugin。

但 Smart Banner 和案件的需求還是有些差異,得靠其他方法解決,在實作的過程中遇到一些小問題與相應的 workaround,特此記錄。

實測環境

跟公司 QA 部門借了幾台機器,以及測試的瀏覽器分別是:

  • iPhone 5S(iOS 8.1.0) – Safari
  • LG G3(Android 5.0) – 內建瀏覽器、Chrome Android 43.0.2357.93、Facebook inapp browser(核心為 Chrome 30.0.0.0)
  • ASUS ZenFone 5 – 內建瀏覽器、Chrome Android 40.0.2214.89
  • SONY Z3(Android 5.0.2) – Chrome Android 43.0.2357.93

服用本文前請注意:也許瀏覽器版本更新後,本文的方法就失效了,所以請作為參考就好哦。

實作與問題

之前在案件中,使用下面這段程式碼作為 workaround:

setTimeout(function() {
  window.location = scheme_link;
}, 25);
window.location = download_link;

註:其中 scheme_link 是 app 的 scheme,可以是單純開啟 App,或是直接進入 App 的某一個畫面。而 download_link 是下載 App 的 URL 連結,像是 Google Play 或是 App Store 的連結。

之前實測時,在裝置上大部分情況都能如預期的運作,但仍有特殊情況(如特定版本的 Chrome、Android Stock Browser)有點小問題。

而隨著瀏覽器版本更新,這次案件再實測似乎就會出現更詭異的情況了,例如同時打開 App 與 Google Play/App Store 的連結。

於是再度至 stackoverflow.com 尋找其他解決方案,找到 一個 2014 年 8 月左右被更新的解答

我針對該解答再做些微調後的 workground 整理說明如下:

Continue reading

近況與 React 初體驗

Standard

好一陣子沒有更新部落格了,年初到現在依然在渾沌瞎忙碌中度過,讓人有些倦怠,暫時沒寫文的靈感。

不過這篇也不是技術文,就當給蜘蛛網密佈的部落格澆個水吧…。

那麼,這陣子除了工作之外,還做了什麼呢?


參加 Modern Web 2015

距離上次 WebConf 2013 也好久了,參加這樣的大型研討會對我來說就是吸收新知,了解一下現在職場上大家都玩些什麼東西。

社交嘛…個性低調的我對在社群 social 總覺得彆扭不自在 XD 還是跟同行的朋友聊聊、交換筆記就好。

  • 最喜歡的場次:
    • 唐鳳 的 《開源之道》
       非技術場,但講到一些社群中人與人間相處、溝通的觀念相當有感觸呢,同理心、分享、尊重等等,在職場、交友上也很受用。

  • 前端相關場次:

    • 阿當 的 Pinkoi 把手機版網站變好用了
       WebConf 2013 中阿當 分享的場次 相當有收穫,這場關於 Pinkoi 手機版網站優化的經驗分享依然如此。
       雖說有些我已經有在工作中實做過了(例如 RESS、pushState、PageSpeed),但也有許多細節未曾注意到。
       在與設計師合作、給使用者更佳的體驗、前端效能細節方面,前端還有好多部分可以努力的,希望自己也能繼續往這方面精進。

    • Chris 的 從技術角度看 Responsive Web Design
       講者分享了許多 RWD 實作技巧,而其中講到跟 PM、設計師溝通這部分特別讓我會心一笑啊 XD
       我覺得設計師、PM 能擁有網頁基礎概念的話…,嗯,應該說是無論職務,都能對彼此的領域有所涉略、了解彼此的難處與需求的話,在實做產品上能夠有很大的幫助啊。(消弭認知落差、找到彼此合作的最佳解)

    • Eric Chuang 的 當網頁遇上原生 App
       由於我目前待的公司主要產品是 App,也曾有人提過想用網頁技術來實做 App 中的內容頁,「用網頁來做,覺得這樣成本比較低」,但身為第一線網頁前端開發才會了解 – 實際上其中血淚與坑的成本並不會比較低 XD
       看到簡報中介紹各家手機廠自幹 ─ “Improve" ─ 原生手機瀏覽器導致的後果與靈異事件,真的是心有戚戚焉(哭)。

針對這些前端場次,我也在公司的開發者分享時間做了個大補帖式的分享了 XD

不過比起 WebConf 2013,個人覺得這次有點小失望呢,大概是門票價格跟我想聽的場次(跟我聽得懂的 XD)沒有成正比吧 Orz


不定期的週末技術小聚會

前同事牽線下,認識幾位前端、設計師朋友,分享彼此在工作上遇到的前端心得與疑難雜症,另外聽聽不同公司對於前端開發上的做法也滿有幫助的,無論是好是壞。

因為身為從來沒掛過前端工程師職稱的前端工程師,在公司想不斷針對前端開發、設計議題討論,總是有種難逢知音的感覺。

也許這種前端朋友間的交流是另一種解決方式吧…


React 初體驗

實做在公司專案上

覺得一直瞎忙很難進步啊,另外也想追一下前端圈滿熱門的 React,觀察到前端人力市場這個技術需求越來越常出現了。

所以抽空自己默默研究了 React,並在公司專案的某功能實做看看。從原本用 Python 接公司 API 再於 template 印出的方式,改寫為 React 元件。另外因為公司案子要兼顧 SEO,所以就在 Server 上透過 python-reactpython-webpack 跑專案的 React 程式,讓內容是可被搜尋引擎蒐錄的。

實做完的心得是 – 所有東西都元件化,拆解,然後被 React 規範該怎麼寫元件的原則下,寫起功能來挺能專注的,回頭看也比較清晰明瞭。


寫了兩個 React Components

手法還很拙劣,未來進步再來改進。

不過真的有包元件包上癮的感覺 XD


最近大概就是這樣,依然是在瞎忙 loop 中找些讓自己過得有趣一點的方式(遠目

啊,轉眼 2015 的一半就這樣過去了…

網站前端調校之「禁止轉譯的 CSS」

Standard

網站前端載入校能優化上,可透過 Google PageSpeed Insights 來評估與抓出問題,還會根據待改進項目的多寡及嚴重性給予優化上的分數。

最近在製作公司網站的專案,雖然沒什麼內容,但趁上線前就試著用 PageSpeed Insights 掃了一下。下圖是一開始的情況:

啊,雖然我不是分數控,但顯示紅色驚嘆號好像不大酷。

Continue reading

在 Google 試算表中實作抽獎功能

Standard

最近公司的活動網站剛結束,接下來要準備抽獎了。
由於沒有後台抽獎功能,趁著下個案子還在 pending 的空檔,來試試看如何在 Google 試算表 中達成抽獎功能,方便行銷夥伴們一鍵抽獎。
最近也是尾牙的季節,也許抽獎也用得上噢。


首先,假設名單資料長這樣:

佈置抽獎所需的物件。我們手動加上一欄「亂數」,並在右方空白處新增抽獎結果的表格,包含對應的獎品、希望呈現的相關資訊等。

接下來是重頭戲,撰寫抽獎相關的 Apps Script
Continue reading

在 Flask 中處理 JavaScript 裡指定 route path 的問題

Standard

目前的工作,開發團隊使用的框架是 Python 的 Flask;而身為小小前端的我在撰寫 Javascript 時,經常會遇到要在 JavaScript 中送 AJAX 到某個 route path 的實作,聽起來並不麻煩,但這個 route name 是在 Flask 中指定的,日後有可能更改,情況一多就改不完了,所以在 JavaScript 中寫死不是個好辦法。

記得之前在搭配 Rails 進行前端工作時,可以在 .js.erb 中寫 <% url = Demo::Application.routes.url_helpers %> 再用 url.某個 route name 來達成指定 route path 的目的。

可惜 Flask 好像沒有…,直接在 JavaScript 裡面寫 url_for 是沒用的(不考量更動結構,.js 依然都還是放在 static/ 目錄底下);比較直觀的作法大概是在 template (會引入該 .js 的那支 .html 檔案)裡面加上 js 變數,再透過 url_for 指定 route path 給它:

<script>
  var path = "{{ url_for('.test') }}";
</script>

嗯,是啊,在 template 中本來就可以使用 Jinja 語法的,只是我仍覺得這個解法不大漂亮。

所以想了些繞路的作法(若熟 Flask 的朋友路過,知道怎麼解才比較漂亮的話,請不吝賜教呀~),記錄於下:

Continue reading

十個行動版網頁(Mobile Web)開發輔助工具

Standard

近期筆者執行了滿多行動版網頁(Mobile Web),同時也是 RWD 設計的專案。光測不同的瀏覽器(IE 8-11、Chrome、Firefox、Safari)就夠忙了,而行動平台上的各種尺寸、瀏覽器與其他變因更是耗費不少前端工程師的青春…XD

而有時候光用桌面瀏覽器模擬手機瀏覽器,並無法完全真實呈現在行動裝置的情況,所以在開發的過程中使用了許多工具來輔助,在開發期就力求盡量測到(並進而解決)不同裝置的「近似」真實的情況。

以下列出十項,個人覺得還不錯的行動網頁開發輔助工具:

Continue reading

在 Android 原生瀏覽器上特別模糊的 SVG 圖片與 workaround

Standard

最近在執行的手機版網頁專案,針對其中許多 icons,我都使用了 SVG 圖片來取代高解析裝置下表現地慘不忍睹的 PNG 圖片,銳利的向量圖片放大縮小也不怕,真棒。

但在進行不同裝置的測試時,發現在某些 Android 上用原生瀏覽器瀏覽時,某些 SVG 圖片特別模糊,毛邊都相當明顯,但又不是每張 SVG 圖片都是如此,相當詭異。

舉個例子:


(可點圖放大)

  • 左方是正常的情況,SVG 圖檔相當清晰
    (Chrome for Android v36)
  • 右方則是在 Android 原生瀏覽器上的情況
    可以注意圖片的邊緣都相當模糊、不銳利

經過比較發現,在我這個專案的情境中,只有被套上 transform: rotateposition: fixed,且是 background-image 方式使用的 SVG 圖片會有這個問題。

上 stackoverflow 搜尋看看,果然有類似的問題被提出(雖然提問者的情境與我不同),而也有人提出了 workaround 來暫時解決這個問題。

根據討論串,這應是 Android 原生瀏覽器及 Chrome for Android 25 版之前的 issue,這個 issue 會使符合上述情境的 SVG 圖片,以 CSS 像素的密度(density)被繪製出來,但多數高階 Android 手機中,CSS 的 1px 並不等於裝置的 1px,所以會讓它看起來很模糊。

而討論串中被提到的 workaround 雖然也沒有對為何可以這樣解決的原理做太多解釋,但也滿有意思的,是在 SVG 檔案中嵌入一個透明(opacity=0)的文字物件:

<text transform="matrix(1 0 0 1 7.1079 13.5215)" opacity="0" font-family="'MyriadPro-Regular'" font-size="12">a</text>

就可讓 Android 原生瀏覽器/Chrome for Android 正常地繪製符合上述情境的 SVG 圖片,就連 zoom in 也一樣清楚噢。

[Rails] 修正 simple_form 2.1 中 input value 使用英文之外的多語系字元,導致無法正常產生 label for, input id 對應的錯誤

Standard

近日在解票時,遇到一張關於 simple_form 表單問題的 ticket。
(註:該專案使用的 SimpleForm 是 v2.1.1 版本)

# 先聲明小弟是前端工程師,完全的 Rails 生手,有說明錯誤的地方請多多包涵哦 :$

情況是這樣子的,在這個專案裡,使用者個人資料的表單中有個這樣的欄位:

它是以群組核取框(checkboxes)呈現,使用者同時可以核取多個項目。

但奇怪的是,用 SimpleForm 產生的這個欄位,在點選「科技」、「網路」、「手機」的文字(label)時,預期行為應是「讓點選的 label 文字左方的核取框作用(勾選或取消勾選)」,但無論按哪個文字,都是第一項「科技」的核取框有反應而已。

這是因為產生的 HTML 語法有誤導致:

<div class="input check_boxes optional">
  <label class="check_boxes optional" for="user_profile_attributes_preferred_info">喜歡哪類資訊</label>
  <span>
    <input name="user[profile_attributes][preferred_info][]" type="hidden" value="">
    <input class="check_boxes optional" id="user_profile_attributes_preferred_info_" name="user[profile_attributes][preferred_info][]" type="checkbox" value="科技">
    <label class="collection_check_boxes" for="user_profile_attributes_preferred_info_">科技
    </label>
  </span>
  <span>
    <input name="user[profile_attributes][preferred_info][]" type="hidden" value="">
    <input class="check_boxes optional" id="user_profile_attributes_preferred_info_" name="user[profile_attributes][preferred_info][]" type="checkbox" value="網路">
    <label class="collection_check_boxes" for="user_profile_attributes_preferred_info_">網路
    </label>
  </span>
  <span>
    <input name="user[profile_attributes][preferred_info][]" type="hidden" value="">
    <input class="check_boxes optional" id="user_profile_attributes_preferred_info_" name="user[profile_attributes][preferred_info][]" type="checkbox" value="手機">
    <label class="collection_check_boxes" for="user_profile_attributes_preferred_info_">手機
    </label>
  </span>
</div>

不大正常,每個 input 的 id 以及 label 的 for 屬性值都一模一樣,當然選不到預期對應的項目囉。

Continue reading