E.J. BLOG

Archive for the ‘js’ tag

[Electron] How to codesign your Mac app

leave a comment

Image Credit

codesign

Introduction

Recently, Electron desktop application gets hot and popular among developers. It’s easy for developers to quickly mockup a desktop application and distribute it to three different platform with zero efforts ! (This is really a lie after I made another popular open source project called Kaku with the same tech.)

Ok back to topic, for companies who want to distribute their desktop apps to the world, they must codesign the application first ! The reason why this is important is because if you don’t do so, if the user enable gatekeeper by default, the application will be blocked due to unidentified developer and users will not be able to open it !

unidentified_developers

security_preferences_options

So in this article, I’ll try to share some my experiences about how to do the codesign for Mac app and what’s going on behind the problems.

TL;DR

Thanks to Marco Pracucci who wrote some useful details in his post, you can just follow these simple steps to do codesign :

  1. Get a Developer ID certificate from Apple and install it into your Mac’s Keychain
  2. Sign your application bundle codesign --deep --force --verbose --sign "<identity>" Application.app
  3. Verify the signature codesign --verify -vvvv Application.app and spctl -a -vvvv Application.app

Note: The identify here is the id wrapped inside the parentheses that you can get from keychain like the screenshot below:

keychain

But … the world sucks

The first problem I have encountered is version problem.

After codesign the app on my laptop (running 10.11.4) and share this app to my team members to test with, for those who are using 10.10.x, they will not be able to use the app and the gatekeeper’ll keep complaining something like the image below : 

vectr_damaged

But for the others who are using 10.11.4, the app is working well on their laptops (WTF???)

After googling a while, I finally found a discussion thread here on GitHub talking about this ! If you codesign your application on 10.11.4 , you’ll successfully get it codesigned and usable BUT for users who are using 10.10.x (to be specific those who use laptops <10.11.3) will have problems when opening that app.

From the discussion thread, we can learn that there are something changed from 10.11.3 to 10.11.4. If you want to hack that around by yourself, you’ll need to follow the steps here. But for me, I use electron-packager, so if you are using that too, you can just upgrade to 6.0.0+ because they already handle that for you on that version with zero efforts !

How to verify your app

  • codesign
    • This tool is not only for doing the codesign, but also you can use it to verify whether it’s well signed or not. After running it, you can get things like this :
  • spctl
    • For this tool, this is mainly used to see whether your codesigned application will be blocked by gatekeeper or not, if you didn’t get anything wording like accepted, your application will always be blocked or treated as damaged by gatekeeper, so it’s really important to use this tool to do the check every time when you create the new application.
    • Note: If you are using Apple Developer ID certificate to build you application and be distributed by yourself, Remember to change your [System] > [Privacy] to “Mac App Store and Identified developers. Otherwise, you will keep getting rejected information.

How to test

You can check details here from Apple’s documentations, but I’ll still copy some here.

  1. To disable Gatekeeper using the spctl command
    • $ sudo spctl --master-disable
  2. To confirm that Gatekeeper is enabled using the spctl command
    • $ spctl --status
      • If enabled, you will get assessments enabled
      • If disabled, you will get assessments disabled
  3. To test your Developer ID-signed app
    1. Make sure your gatekeeper is enabled by follow above ways.
    2. Email your Developer ID–signed app to yourself and use the copy that Mail downloads to trigger the dialog.
    3. Host your Developer ID–signed app on your own local or remote server and use the copy that Safari downloads to trigger the dialog.
    4. By doing so, your gatekeeper will be triggered correctly !

Troubleshooting

A) My certificate on keychain keeps showing expired

This problem is critical and annoys developers who are not familiar with Apple certificate things (like me !) When working on the codesign feature, I noticed that no matter how hard I re-install the certificate that I download from Apple, it will keep showing expired with no reason !

After trying and discussing this with one of my iOS friend, we finally realized it’s related to this notice ! For someone (not sure who, but including me), the Apple Worldwide Developer Relations Certification Intermediate Certificate is going to expire on Feb 14, 2016 which will cause the problem to make your certificate keeps expired.

What you need to take action here is to renew the this core certificate and try to re-install (or re-create) your developer certificate again and things will be solved … WTF !!

B) Where to find my certificate ?

For most of people, if you are writing desktop application by Electron, normally you’ll distribute your application by yourself (like us). But, I noticed that it’s really frustrating to figure out how to get that Developer ID Certificate !!

I have tried several times from https://developer.apple.com, but there is nothing related to Developer ID Certificate (or maybe it’s mainly because I am using different role, so it’s not showing up ?) ! After reading tons of articles, I finally realized that it’s inside Xcode !! You can check the screenshot below :

issue_certificate

But you can notice that the buttons are grey and is not clickable. That’s mainly because the role is wrong !! Even if you are admin role, you still can’t generate that ! Only Team Agent can do that ! So if you are developer or admin, Go ask your leader for that and tell him/her to press the button above to create the certificate for you.

After getting the certificate (it will be name like this xxxxxxx.p12), you can just double-click the file and install into your keychain. Remember, always keep them private :)

Note: Only the first one who made the certificate and uploaded to Apple Developer can have this .p12 file. This will only exist on his own keychain and you can’t even get it from Apple Developer. So remember to ask him to export that p12 file and share with the whole team ! Remember, if you lost this .p12 file, no one can save you and you need to regenerate another certificate again.

Last few words

It’s really a hard time to fight with codesign stuffs especially there are less resources talking about this. But whatever, I wrote them down already !! If this article does help you, please feel free to share !

And also, if there is anything wrong or missing in the article, feel free to tell me and I’ll update it ! See you guys next time :)

Reference

  1. https://pracucci.com/atom-electron-signing-mac-app.html
  2. https://github.com/electron/electron/issues/4899
  3. https://goo.gl/ZgKXr1
  4. https://developer.apple.com/support/certificates/expiration/

Written by EragonJ

April 21st, 2016 at 6:19 pm

[Javascript] TwZip.js

leave a comment

twzip

Github Link

最近因為 Hax4 有 project 需要用到台灣郵遞區號,所以就花了一點時間做了一個簡單的 js (jQuery) plugin – TwZip.js。不過身為一個前端工程師當然想把事情都留在前端處理就好,因此當初在設計這個 plugin 的時候就打算把所有的資料都放在前端,然後以 lazyload 的方式把資料載進來而不需要後端的支援(超懶)。

而說到資料,TwZip.js 的資料是從中華郵政全球資訊網下載來的,然後簡單寫了一個 makefile 搭配 node.js 自動產生數百個鄉鎮市區的 metadata 供前端使用。

這邊要提一個我一直被卡住的白痴問題(OS 老師當初應該把我當掉),因為原本我的設計是三層式架構(像是 台北市/信義區/信義路),但是這會造成資料過度碎片化的問題。之所以會這樣是因為在 file system 裡面最小單位的 block or Cluster 有一個最小容量,像我電腦就是 4 KB,所以如果資料小於 4KB 就還是以 4KB 計,因此這個三層式設計最後就產生出 16X MB 的資料(因為產生出太多 metadata 了)… 整個比原本的專案大上好幾十倍呀 …

為了解決這個問題,最後就改成兩層式架構(像是 台北市/信義區,也因為層數變少的關係所以最後就變成約 4 MB 的資料了,整個就是皆大歡喜。

還記得以前的前輩曾經教過我在寫程式的時候要先把 API 想好,確定使用者使用的介面再開始寫細節,透過這樣的決定來讓整個專案照著預期的方向前進才是比較好的,這樣才可以提前知道這個設計上的缺陷及問題,算是又多了一點體悟吧!

儘管如此,目前這個 plugin 還只能算是一個 prototype ,未來應該會再把 zipcode 的資訊透過 callback 傳回去。其他的功能就再說吧。

DogFooding ++

Written by EragonJ

June 3rd, 2014 at 6:14 pm

[FxOs] Inter App Communication

leave a comment

之前投了一篇稿在 Mozilla TW 的謀智台客,主要是在探討 FxOS 如何透過 IAC 在 App 間溝通資料,廢話不多說,請看:

iac

在開發 App 的時候,我們有時候需要在App之間傳遞資訊,而今天我們要介紹的主角就是新引入的 WebAPI: IAC (Inter App Communication),有了這個好東西,我們就可以輕易的在 App 間傳遞訊息,以下就用筆者遇到的例子來說明吧:

User story

當使用者拿到 Firefox OS 手機,第一次開機的時候,會自動先開啓 FTU (First Time Use) App 作導覽。當導覽進行到最後一步的時候,會看到這個畫面,可以按下「Home」鍵回到主畫面。

ftu-mobile-627x1024

而在 Firefox OS 平板上,最後一步的導覽畫面會是這樣,但是改透過由螢幕下方往上滑動的手勢回到主畫面:

ftu-tablet-1024x640

大家可能還不是很明白為什麼這個 User Story 下面要使用 IAC,讓我解釋一下。因為在手機剛啟動的時候,我們的 FTU 是一個獨立的 App,而這個 App 是被 System App 所呼叫起來的,兩個 App 之間如果需要溝通,就需要透過 IAC 來傳遞資料。

之所以 FTU App 需要跟 System App 做溝通,是因為「使用者在 FTU 導覽過程中,是無法按 Home 鍵離開的」,但很不巧的這個需求在 Firefox OS 平台是 Tablet 的時候反而變成是一種限制,怎麼說呢,因為對 Tablet 來說,我們並沒有實體的 Home 鍵,因此「Swipe 向上的手勢」就被我們定義成「使用者按 Home 鍵」,但是在先前 Mobile 的需求下,使用者在 FTU 是不允許按 Home 鍵的!!因此這就產生了一個問題,我要怎麼判別使用者現在的情境是:

  1. Tablet 使用者
  2. FTU 已經導覽到最後一步
  3. 使用者可以透過螢幕下方往上滑動的手勢(等同按 Home 鍵)離開 FTU App

這個時候…我們就需要 IAC 的幫助!

IAC , we need your help

這邊要解釋一下 FTU App、System App 及 IAC 的角色。

FTU App 的功用主要是在教導使用者如何初始設定 FxOS 及透過 step by step 的教學來了解如何使用 FxOS 的裝置,所以他可以知道使用者目前的 step 到哪個階段了。

System App 在這裡的功用是在處理使用者按下 Home 鍵時要處理的事情,他只知道目前使用者是不是按下 Home 鍵(在 Tablet 就是 Swipe 向上的手勢),然後依照各個平台做相對應的事情。

而 IAC 的角色就是 FTU App 及 System App 溝通的橋樑,因為 System App 不知道目前 FTU App 是不是到了最後一步,所以自然就無法解除阻擋 Home 鍵這件事情,所以在這個 User Story 下,當使用者來到最後一個 Step 的時候(而且是在 Tablet 的平台),FTU App 就會透過 IAC 和 System App 溝通,然後請求 System App 可以讓我們以透過 Swipe 向上的手勢(等同按 Home 鍵)離開 FTU App。

在 Gaia 我是這麼做的:

In FTU App :

從程式碼中可以看到我們透過 app 實體去連接一個 keyword(在這個例子中就是 ftucomms),FTU App 跟 System App 之間就是透過這個 keyword 來當做識別並透過 port 來溝通,我們只需要把東西通通塞進 port.postMessage 做雞精就對了!

聰明的你可能會問,所以 App 只需要隨便用個 keyword 就可以連結並傳東西嗎?當然不行,接收訊息的 App (傳送訊息的不需要)還需要去它的 manifest.webapp 設定如下:

這樣子我們 System App 就可以接收來自 FTU App 的訊息了!在 System App 只要我們確定傳送進來的 message 是我們當初預期的 ‘done’ 就可以放行讓使用者可以透過 Swipe 向上的手勢離開 FTU App 了!

不過你可能又會問我要怎麼讓 System App 來接這個訊息呢,這是個好問題。如果你需要透過 IAC 來做資料傳遞的時候,你需要使用 mozSetMessageHandler 來掛載相對應的 Handler。

下面是 IAC 的基本使用方法:

但是要注意的是因為這個 API 只會執行最後一個掛上去的 Handler,所以當你一個 App 要做多組 IAC 資訊傳遞的時候就需要自己做額外的處理。

但在寫程式的時候沒注意到件事情,所以當時 Music App 的另一個 contributor – Jim Porter 同時也自己在 System App 建立了一個 Handler,而我的 Handler 又是在他建立之前建立的,因此所有我 FTU 有關的 Handler 不會執行到,因為通通都被它的 Handler 蓋過去了。

所以為了讓後面的人不要發生這個問題,之後就和 Jim Porter 討論出一個 IACHanlder,每個 App 只要引入這段 javascript ,我們就會自動幫他建好一個共用的 Handler,所有的資料都是這個 Handler 統一管理,然後以一個固定的 naming 用 Custom Event 的方式傳播出去,讓有需要的人可以自己接 Event。(有興趣了解實作的人可以看這裡

所以最後 System App 只要用這樣簡單一行程式碼就可以接 Event 然後做解除限制的動作了:

是不是很簡單呢!希望這篇能夠幫助到也需要使用 IAC 的開發者朋友哦 :)

參考資料: Inter App Communication wiki 文件

Written by EragonJ

December 16th, 2013 at 9:33 pm

Posted in FxOS

Tagged with , ,