iOS Developer Enterprise Program How To

Following are steps add a new developer to your iOS Developer Enterprise Program
Blue for Administrator / Green for Developer

1. Add new member 
2. Request certificate by using Keychain Access
3. Approve request
4. Download and install certificates
    Development certificate + WWDR intermediate certificate

5. Admin create provisioning profile (Wildcard & non-wildcard bundle ID)
    Must select new member’s name and add devices who can use
6. Download new provisioning profile
7. Select code signing provisioning profile (in XCode)
    > Debug : Wildcard bundle ID
    > Destribution(Release) : Specific bundle ID


Diagram:

Facebook被盜帳號處理措施123


今天下午連續收到兩位朋友請我”幫忙“收一下Y拍的購物簡訊…

看來這種詐騙方式還是不斷的存在,請大家小心謹慎不要幫忙收簡訊,也不要在奇怪的地方(圖書館, 網咖, 莫名的無線網路…) 登入自己的Facebook. 避免有心人士竊取帳號密碼。

如果發現自己被盜了,請馬上按照以下的方式處理
1. 改密碼
被盜帳號一定有原因,不管如何,避免自己朋友也受騙上當才是上策。
以下是改密碼的步驟~

**
到Facebook帳號設定

選擇”一般” -> “密碼” 來變更



2. 登出所有其他的連線 (Session)
每一台電腦/手機登入都會有一個連線維持著,讓使用者不會斷線重登入。
這一步驟就是要把除了現在自己登入的連線保留,其他都斷掉。

選取”帳號保安” -> “有效的連線”(Active Session) 並且把其他的裝置/連線全部都登出
新增說明文字

3.增加自己的帳號安全性**

參考電腦玩物的這篇教學,學習如何設定以下兩招
  1. 在不同地方登入需要記錄裝置
  2. 登入的時候會寄信到自己信箱(當他人登入時,就馬上會知道)



    希望大家能好好的保護自己的帳號,這種詐騙手法在MSN / Google Talk / Facebook 都有,
    如果收到“請求幫忙”訊息的時候,請好心的告訴自己朋友喔!



Mac 新手上路記錄 (App, Widget, Configure)

        剛入手的MacBook Air 13” 

第一天拿到就更新了 OS X 10.8.1,速度很快,非常舒服。

以下記錄一下安裝的東西

首先是Mac Application (免費為主, 付費的… 過陣子再說…)

生產力軟體(Productivity) SizeUp:多視窗管理,很方便(但是會跳Demo視窗)
Mou:Markdown 即時預覽編輯器 Dash:快速Snippets與文件查詢工具
Calendar for Mac:MenuBar上的Calendar - 看的到event! (2012/09/01新增) 瀏覽器(Browser)

Firefox Chrome
Opera 儲存(Storage)

Dropbox SkyDrive:因為有之前活動獲得的25G,所以還是用一下。 開發與編輯器(Development & Editor) Sublime Text:我最愛的純文字編輯器,設定可以參考這篇
SmartGit:目前覺得最好用的Git Client (SourceTree把我repo搞爛過…) XCode:iOS Development 多媒體(Mutimedia) 好照片:方便的照片特效處理軟體
Skitch:螢幕截圖軟體,附上基本畫筆可以標記 KKBox
VLC Player (2012/09/01新增) 終端機相關(Terminal)

Go2Shell:可以直接在Finder上開啟該目錄的Terminal iTerm:加強版Terminal 社交軟體(Social) Adium:MSN/Gtalk/… 整合即時通訊
MenuTab for Facebook:非常棒的Facebook整合 TweetDeck:Twitter Client, 管理多帳號的時候很方便(我還有jsdc.tw的帳號…)
Skype Line 系統軟體
另外還有Dashboard Widgets (尚在摸索中)
iStat Pro
Currency Converter Day Counter
HSLider Page Capture
PEMDAS Translator

由於從來沒有擁有過MacBook 所以

認真研究了一下快捷鍵(Keyboard Shortcut) 的部份。還有因為一直改系統配置,不斷的開開關關讓我覺得很煩,所以後來也把 System Preferences 設定了一個快捷鍵:(參考這篇的教學)

另外記錄一下幾個指令與小秘訣


顯示隱藏檔案指令指令defaults write com.apple.finder AppleShowAllFiles TRUE
killall Finder

列出安裝的package(.pkg)– (包裹還是套件阿~~~~~~?pkgutil –pkgs

螢幕取色使用內建的DigitalColor Meter 


最後透過MacPorts安裝了常用的一些工具(ex:htop),其他有想到再補。

尚未解決:
想找一套好的Blog編輯軟體,但是還在MarsEdit 3 / Ecto 等等的尋找中…

其他參考
40 Useful Mac OS X Shell Scripts and Terminal Commands

iOS Web 畫面閃爍問題 (CSS3)

在iOS (iPhone 4s/ iPad 2/iPod Touch) 上測試 Mobile Web的時候出現了閃爍問題
和Team member 花了一段時間發現一個很詭異的問題
狀況
1. 父節點(DIV)因為要做Transition使用了 **<span style="color: #666666;"> </span><span style="color: blue;">transform: translate3d(…)</span>**
<span style="font-family: Arial;">2\. 畫面處理完成後,觸動事件將子節點(DIV)的CSS改變** **</span><span style="color: blue; font-family: 'Courier New';">**left : *px**</span>

就在這個更改子節點的瞬間 iOS 的畫面一定會**<span style="color: red;">閃爍一下</span>** ``測試過了 iPad / iP4s / iPod Touch 都有這問題 但是Android 2.x 4.x 都沒有…

處理方式

原本以為是iOS 的 webkit 在處理特定 position 的 left 造成子節點重畫的問題,
後來想想覺得這 也太基本了吧 不太可能,經過嘗試以及搜尋,發現很多人都有類似問題。

像是StackOverflow 這篇 還有 這篇 他是改 CSS top 導致發生神秘的閃爍事件…

最後使用動態增加translatde3d 並且 reset 的 爛招 解法   

後來將以下的 css 指定給子節點 問題就解決了

transform: translate3d(0,0,0);
-webkit-transform: translate3d(0,0,0);

補充
回家後看到jsconsole/jsbin的作者 Remy Sharp 大大的影片

造成我畫面閃動的原因 應該是跟iOS的硬體加速有關

故需要Reset translate3d …..

真。他x的  上一次遇到這種神秘的問題 是面對高級瀏覽器 IE 6 …………… 

References
http://stackoverflow.com/questions/tagged/translate3d

My Sublime Text 2 on Windows 7 64bit

Sublime, the awesome, amazing editor.1. Get 64bit portable version

  • Official Website : http://www.sublimetext.com/22. Install Package Control
    This is the most complex step.
    Type Ctrl + ` and enter following python code

    import urllib2,os; pf=‘Package Control.sublime-package’; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),‘wb’).write(urllib2.urlopen(http://sublime.wbond.net/+pf.replace(‘ ‘,‘%20’)).read()); print ‘Please restart Sublime Text to finish installation’
    3. Install Packages (All from package control)

  • Alignment

  • Format shortcut – Ctrl + Alt + a* BracketHighlighter

  • CoffeeScript
  • Display Functions (Java)
  • Edit History

  • Jump to next/previous edit location

  • Add Key Binding* FileDiffs

  • Usage

  • Right click on tab (Or use command popup then search “Diff”)* Install KDiff3

  • Modify Code (filediffs.py)

    **
    Under WINMERGE_**if not WINMERGE:
    if os.path.exists(“%s\KDiff3\KDiff3.exe” % os.environ[‘ProgramFiles(x86)’]):

    WINMERGE = <span class="str">'"%s\KDiff3\KDiff3.exe"'</span> % os.environ[<span class="str">'ProgramFiles(x86)'</span>]
    

    else:

    WINMERGE = <span class="str">'"%s\KDiff3\KDiff3.exe"'</span> % os.environ[<span class="str">'ProgramFiles'</span>]
    

    ……
    _End of rundiff function

    if from_file == ‘from_file’ or to_file == ‘to_file’:

    cmd_line = <span class="str">'%s "%s" "%s"'</span> % (WINMERGE, from_file, to_file)
    print <span class="str">"KDiff3 command: "</span> + cmd_line
    Popen(cmd_line)</pre></pre>*   [Git](https://github.com/kemayo/sublime-text-2-git/wiki)
    
  • Call git command quickly – Need Git (mysysgit on Win7)

  • Usage : Command search “git”* HTML5

  • Snippets* IndentGuides

  • Indent line for editors* jQuery

  • Snippets* jQuery Snippets pack

  • Hint : Need enable jQuery support by command

  • Snippets* JS Minifier

  • Minify shortcut – Ctrl + Alt + m* JsFormat

  • Format shortcut – Ctrl + Alt + f* Pretty JSON

  • Format shortcut – Ctrl + Alt + j* Prefixr

  • Format shortcut – Ctrl + Alt + x (For CSS)* SideBarGit

  • SideBarEnhancement
  • SublimeCodeIntel (Must Have)

  • Autocomplete (Popup)* Tag

  • “/”to end tag

  • Format shortcut – Ctrl + Alt + f
  • Features : Edit –> Tag …* Terminal

  • Open file shortcut – Ctrl + Shift + t

  • Open folder shortcut – Ctrl + Shift + Alt + t* Tortoise

  • Need  TortoiseGit or TortoiseSVN

  • Update : 20120314 - **error: [Error 2] The system cannot find the file specified* WinMerge

  • Compare shortcut – Ctrl + Alt + d (Current file with previous edit file)

  • Modify Code (WinMerge.py)

    WINMERGE = “F:\WinMerge-2.12.4\WinMergeU.exe”
    ZenCoding (AWESOME!!)**Editor Shortcut*

  • Toggle sidebar (file explorer) – Ctrl + K then B

  • Command List - Ctrl + Shift + P
  • File Search – Ctrl + P

    Right Click Menu Support

  • Modify the Path of following regestries

  • Save following text into a .reg file then double click on it to apply
    Windows Registry Editor Version 5.00

    [HKEY_CLASSES_ROOT\\shell\SublimeText]
    @=“Edit With Sublime Text2”
    “Icon”=“D:\WindowsApp\Sublime\sublime_text.exe”
    “Position”=“Bottom”

    [HKEY_CLASSES_ROOT\\shell\SublimeText\command]
    @=“D:\WindowsApp\Sublime\sublime_text.exe %1”

《鐵娘子The Iron Lady》筆記

這篇文章我從Twitter 打到 Tumblr, 從Tumblr 打到 Blogger

昨天才看完電影,今天全憑記憶打,不知不覺就打了好多,部分英文可能有錯就不要太在意了

教育相關

  • 我們要不堅持立場,要不乾脆一事無成
    (We will stand on principle, or we will not stand at all)
  • 過去人們總是努力要完成某件事,現在卻是要努力成為某個人
    (It used to be about trying to do something, Now it’s about trying to be someone)
  • 如果父母總是要求孩子跟自己走一樣的路,那要怎麼要求孩子更傑出?
    > 教育是適性發展,不是要跟隨前人腳步
    政治相關

  • 以前政治是關於如何做事,現在是關於如何出名

  • 我們想要一個人民可以自由的選擇、犯錯、持有寬容及同情心的社會。這就是我們所謂的道德社會;不是一個國家要負所有責任,而沒有人須要為國家負責的社會。
  • 假裝我們都是平等的沒有任何好處,我們並不是相同的,從來沒有過,也永遠不會是
  • 人們已經不思考了,他們全憑感覺。一下說我覺得不妥,一下子又說抱歉我們組織覺得如何如何。
    當代最重大的問題之一就是我們被這樣一群人所統治

> 一個領導人不能只靠”感覺”,要理性地去思考每一步策略.* 那些人不是無能,就是懦弱> 這是鐵娘子教女兒開車時的話,其實正是暗指當時政客們的狀況

  • 總有人應該面對問題,說出難聽的真相! (對政客說) 你們這些人膽子太小了
  • In politics, If you want anything said, ask a man; If you want anything done, ask a woman
    人生相關

  • 生活本來就是自由選擇

  • 思想會化成語言,語言會化成行動,行動會變成習慣,習慣會變成個性,而個性會決定命運!
    我們想甚麼,就會造就自己成為什麼樣的人
    (Watch your thoughts for they become words. Watch your words for they become actions. Watch your actions for they become… habits. Watch your habits, for they become your character. And watch your character, for it becomes your destiny! What we think we become.)
  • 小心你想些什麼,因為它們會從你口中溜出來
    (Watch your thoughts for they become words)
  • 你想改變這個國家(團體/公司),就去領導它
    (If you want to change the party, lead it. If you want to change the country, lead it.)
    > 要堅定立場,做出自己的風格. 還記得某個網路圈的名人曾在FB上說過,如果你不喜歡你的(公司)環境,不是該抱怨,而是該改造它(然後我就按讚)

最後一句看似簡單但卻意義非凡的話

One’s life must mean more than that.

正適合送給所有正在為自己理性/夢想打拼的人

加油!

Request Https resource in Java

This article is about how to request resource from an HTTPS resource. e.g. https://a.b.c.d/test-metadata.xml

We have to do following two things

  • Trust all certificates (PKIX path building failed)
  • Pass SSL handshake verification (javax SSLHandshakeException)
  • Pass basic (username/password) authentication (401, Authentication Required)
import java.io.*;
import java.net.*;
import java.security.cert.*;
import javax.net.ssl.*;
public class HttpsRequestClient {
private final String USERNAME = "ryanwu";
private final String PASSWORD = "mypwd";
private final String TESTURL = "https://a.b.c.d/test-metadata.xml";
public static void main(String[] args) {
HttpsRequestClient client = new HttpsRequestClient();
switch (args.length) {
case 0:
client.testURL();
break;
case 1:
client.testURL(args[0]);
case 3:
client.testURL(args[0], args[1], args[2]);
default:
client.testURL();
}
}
public void testURL() {
testURL(TESTURL, USERNAME, PASSWORD);
}
public void testURL(String url) {
testURL(url, USERNAME, PASSWORD);
}
public void testURL(String testURL, final String name, final String pwd) {
HttpsURLConnection testConnection = null;
try {
// Trust All HttpsCertificates
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new AllPassTrustManager() }, null);
// Pass handshake verification
HostnameVerifier myHostnameVarifier = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
// Configuration
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(myHostnameVarifier);
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(name, pwd.toCharArray());
}
});
testConnection = (HttpsURLConnection) new URL(testURL).openConnection();
printHttpsCertificates(testConnection);
printResponseContent(testConnection);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (testConnection != null)
testConnection.disconnect();
}
}
private static void printHttpsCertificates(HttpsURLConnection con) {
try {
System.out.println("-----Certificates-----");
System.out.println("Response Code : " + con.getResponseCode());
System.out.println("Cipher Suite : " + con.getCipherSuite());
System.out.println(System.getProperty("line.separator"));
Certificate[] certs = con.getServerCertificates();
System.out.println("Certificate Number : " + certs.length);
for (int i = 0; i < certs.length; i++) {
Certificate cert = certs[i];
System.out.println("No : " + i);
System.out.println("Cert Type : " + cert.getType());
System.out.println("Cert Hash Code : " + cert.hashCode());
System.out.println("Cert Public Key Algorithm : " + cert.getPublicKey().getAlgorithm());
System.out.println("Cert Public Key Format : " + cert.getPublicKey().getFormat());
System.out.println(System.getProperty("line.separator"));
}
} catch (SSLPeerUnverifiedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void printResponseContent(HttpsURLConnection con) {
try {
System.out.println("-----Content-----");
BufferedReader br = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String input;
while ((input = br.readLine()) != null) {
System.out.println(input);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* A TrustManager which passes all certificates
*
* @see TrustManager
*/
private class AllPassTrustManager implements TrustManager, X509TrustManager {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
return;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
return;
}
}
}
`

With HttpClient, the testURL method will become easier

public void testURL(String testURL, String name, String pwd) {
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
// Trust all https certificates
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new AllPassTrustManager() }, null);
// Use apache SSLSocketFactory
httpclient.getConnectionManager().getSchemeRegistry()
.register(new Scheme("https", 443, new SSLSocketFactory(sc)));
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(AuthScope.ANY_HOST, 443),
new UsernamePasswordCredentials(name, pwd));
HttpGet httpget = new HttpGet(testURL);
ResponseHandler<String> handler = new ResponseHandler<String>() {
public String handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
System.out.println("Response Status : " + response.getStatusLine());
System.out.println("-----Content-----");
HttpEntity entity = response.getEntity();
if (entity != null) {
return EntityUtils.toString(entity);
} else {
return null;
}
}
};
System.out.println(httpclient.execute(httpget, handler));
} catch (Exception e) {
e.printStackTrace();
} finally {
httpclient.getConnectionManager().shutdown();
}
}

談創業家與專業經理人

這是今天在Twitter上回應了@Deduce大大的一段話

我覺得專業經理人跟創業家有很大的相似點, 只是喜歡的生活型態不同罷了.

這樣講或許有點草率,不過專業經理人和創業家的異同,其實在很多地方都有這類的討論

到底這兩者差在哪?

下圖為 孫易新心智圖法 網站彙整EMBA雜誌第295期文章”創業家和專業經理人有何不同”所得到的心智圖

中午吃飯時順口問了同事對於這兩者之間的看法.

TonyQ:字不一樣(當場毆飛)

Ian覺得這兩者的驅動(Driven)不同, 專業經理人是透過指標(例如股價,效率,收入)來驅動, 創業家是透過目標(創造更好的Todo List, 雲端筆記本, 社群互動…)來驅動. (簡言之:Different motivation)。

這兩者在現今社會也有著非常不同的印象

  • 專業經理人 : 普遍認知為妥善運用目前資源追求極大利益者
  • 創業家 : 普遍認知為尋求偉大夢想的實踐者

加上在執行層面上來說,這兩者的確有非常大的重疊. 甚至有非常多的例子是從專業經理人成了創業家,從創業家到執行長。所以不論是企業管理研究或是創業圈都對這兩者有許許多多的討論與分析。
好多年前在BBS上有轉錄一篇文章, 叫做”天生注定當老闆”(剛剛Google找不到原文…只有許多轉載與片段)
其中提到的創業家特質,很大一部分跟專業經理人所必須具備的特質是一樣的。不過其中也提到創業家與專業經理人天生性格上最大的鴻溝是對於不可測及不確定變數的容忍 (簡言之就是對於風險的容忍程度。)

用一個比喻來說,這兩者就像從不同的登山口,穿戴類似的裝備兩個登山者,不論面對颳風下雨都有著堅忍不拔的毅力,但面對每一個突發狀況的處理方式卻不完全相同。

身為一個創業家需不需要有專業經理人的思維呢 ?

許多巨型企業(如IBM, Manpower)都有一個制度,就是把較為成熟的產品部門或技術團隊,切出去當成Branch。整個Branch的五管(包含支出與收入)都獨立運作責任自付。這造就出了許多十八般武藝樣樣精通的專業領導人才,若這些人離開後,踏上創業路,也往往都能建立起自己的一片天。

剛剛在翻舊文時從我的Evernote發現一篇之前有意思的文章 「專業經理人」比「創業家老闆」更愛錢?其中談到非金錢動機在進場與退場行為中扮演的角色. 這篇文章提供了幾個假設供需要了解分析一間公司的人做參考

ec

其中提出三個假設

  1. 在由專業經理人所掌管的公司裡,「市場經濟吸引力」與「進場可能性」呈正相關的可能性,大於由所有人管理的公司。
  2. 由專業經理人管控的公司,比起由企業所有人身兼經理人的公司,更有可能因為經濟誘因愈小,而提高退出市場的可能性。
  3. 在由專業經理人所管理的公司裡,「市場經濟吸引力」與「公司價格」兩者之間的正向關係,比起在由所有人管理的公司裡更為強烈。

在所謂浪頭上的產業(白話:市場熱錢的聚集處),只有極少部分的公司是由所謂的專業經理人管理。排除企業導師等等的外部協助,身為一個資訊創業者,除了從做中學之外,對於專業經理人的思維與管理態度也必須要有一定程度的狩獵(最常見的切入點是行銷,專案管理,與人力資源管理),否則就算募了一大筆錢或是擁有很好的Business Model,也很有可能被時代的潮流淹沒。

 

去創業好還是去當專業經理人好?

隨著Diablo 3 即將發行,用這張D2圖來解釋最合理也不過

skill

這世界上本來就沒有所謂完美的Career Path, 你想玩什麼就玩什麼,如果現階段的環境無法達到滿足或讓你覺得生活無趣,那代表你需要一點改變了。上述提到的創業家的特質與中山大學創意管理教授劉常勇提出的10D是很可以參考的指標。

基本上,累積自己的價值(點技能)都不會有壞處,但是在有限的資源(例如時間)內如何將這些技能在正確的時間發揮,就是每一個人都需要好好思考的了。

為什麼IT公司需要行銷人員?

我知道全世界只有10種人, 一種是懂Binary的, 一種是不懂的

台灣的開發者/程式設計師, 素質好, 薪水不高. 這點是有目共睹的優秀(?)狀況.

看到一篇文章在探討行銷人員的存在目的, 就做個翻譯當紀錄. 

警惕一下不誤正業半調子的我

如果沒有那些Marketing的傢伙:

  1. 更少人會知道我們 : 包括了我們的客戶 && 朋友 && Google上循線而來的人們

  2. extends 1 = 更少的花費(俗稱Cost Down)

  3. implement 2 = 開發者薪水可以++

  4. 不用給獎金 (或稱Commission, 回扣, 業務獎勵…)  NOR 我正好”收到一封邀請“, 希望我去一間有優秀行銷團隊的公司工作

  5. R.I.P GPWGFTCCW - 別說什麼擁有好功能的好產品可以改變世界
    Great Product with great functionalities that can change the world.

如果沒有那些社群管理員(或者相關的社群管理策略)

  1. 沒有社群擁護我們 = 我們必須“用盡所有可能”自己測試我們所有產品
    以網頁內容管理系統為例, 從功能測試, 模組相容測試到網頁使用這測試, 流覽器相容測試 都自己來.
    養一個QA Team應該比較快 - 但是很貴 Smile

  2. 沒有社群擁護我們 = 要怎麼知道改怎麼改善?又或者知道客戶的需求?  
    如果不是熱情的社群提供大量意見供篩選, 而是靠著少數客戶的意見想法作產品決策,
    那跟作外包接案有什麼不同???

  3. 沒有社群擁護我們 = 怎麼獲得下一個新產品的好點子?
    創業圈很愛說”怎麼滿足使用者的需求”, 沒有人告訴你, 只能問天了.

  4. 沒有社群擁護我們 = 怎麼找到有人可以告訴你 “你他X的了”
    懸崖勒馬, 亡羊補牢其實有時候有用. 但往往都是洗頭洗一半將錯就錯.

  5. 沒有社群擁護我們 = 怎麼找到有人可以幫你寫詳細的文件 /  抓Bug / 分享產品的喜悅 / 甚至鼓勵你

唉呦不錯喔!我喜歡你們的產品

原文最下面附上這句話

* I am so sorry, but someone should change the ordered list to start from 0/zero/. Starting from 1 is so lame.

翻譯 - 我很抱歉, 但是有人應該把上面的清單改成從0開始. 從1開始很鳥.

看到這句話, 我的認知除了身為RD的老梗以外,

這句話其實深深暗喻 : 行銷/社群的計畫策略, 就算不在一開始投入預算, 也該列入計畫中.

總結

Stay focus ,Go to marketing, listen to users, evaluate feedback, keep improving/shipping