2012/12/17

CodeIgniter + Smarty

用 Smarty 用了這麼多年,寫 PHP 不用它還真不習慣。以下是 CodeIgniter 整合 Smarty 的步驟:

Step 1. 下載最新的 CodeIgniter 和 Smarty(目前是 CodeIgniter_2.1.3.zip 和 Smarty-3.1.12.tar.gz)。

2012/12/05

Mac 安裝 SmartFoxServer 2X

目前(2012/12/05)最新版本是 2.4.0,要裝此版本,要先安裝 2.0.1 版,然後直接安裝 2.4.0 更新檔即可。

1. 下載 2.0.1 Mac OS X 安裝檔(連結)。
2. 掛載、安裝(預設安裝到 /Applications/SmartFoxServer2X 目錄下)。
掛載安裝檔。

輸入帳號、密碼。

開始進行安裝。
授權協議。

指定安裝目錄。



如果要開機時自動啟動 SmartFoxServer,就勾選。如果不勾選,需要自行啟動。

開始進行安裝。

安裝完成。
3. 下載 2.4.0 Patch 檔(連結)。
4. 在安裝目錄下解開下載的壓縮檔。如果是用預設的安裝目錄,在 /Applications/SmartFoxServer2X 目錄下應該會有 SFS2X-Patch-2.4.0 這個目錄。
在 SmartFoxServer2X 目錄中,解開 Patch 檔。解開的 SFS2X-Patch-2.4.0 要和 SFS2X 目錄在同一層。

5. 在終端機執行 /Applications/SmartFoxServer2X/SFS2X-Patch-2.4.0/install-osx.sh
從終端機執行 install-osx.sh

cd /Applications/SmartFoxServer2X/SFS2X-Patch-2.4.0
./install-osx.sh

更新完成。
6. 如果安裝時沒有選擇 Install as service , SmartFoxServer 不會自行啟動。只要從 LaunchPad 或應用程式內執行 SFS2X 就可以啟動 SmartFoxServer。
從 LaunchPad 裡行 SFS2X,啟動 SmartFoxServer。

手動啟動成功後,會出現 SFS 2X READY 文字。按下 Cancel 就會停止 SmartFoxServer。


2012/12/02

[Castle Age] Whirlpool 入手

Whirlpool - 2012/12/03

2012/11/29

Android 設備 統計資料

Android Device DashboardAndroid Developers Blog 在 2009/12/17 釋出的資訊,提供從 Google Play 上搜集到的統計資訊(像是 API 版本、螢幕尺寸、解析度)。企劃以及開發人員可藉此得知目前主流的 Android 設備規格,再決定要針對那個規格進行開發。
Android - Current Distribution ~2012/11/01

Android - Screen Sizes and Densities ~2012/10/01



Mac 下的 mysql.sock

在 Mac 下安裝 MySQL 之後,執行 php 程式時出現以下錯誤訊息:
Warning: mysql_connect(): [2002] No such file or directory (trying to connect via unix:///var/mysql/mysql.sock) in /Users/Someone/xxx.php on line 52
原因是 Mac 下的 mysql.sock 的存放路徑,與 PHP 的預設值不同。
PHP 預設值是 /var/mysql/mysql.sock,而 MySQL in Mac 卻是在 /tmp/mysql.sock
因此最簡單的解決方式就是設定一個 symbolic link 就好:
sudo mkdir /var/mysql;
sudo ln -s /tmp/mysql.sock /var/mysql/mysql.sock
當然也可以去改 PHP 設定檔 (php.ini) 或 MySQL 設定檔 (my.cnf),只是有點麻煩,網路上有相關文章,此不贅述。

2012/10/29

常見密碼 2012

依據 SplashData 公布的資料(連結),以下是網友常用的密碼前 25 名,如果你的密碼在這份清單上,最好趕緊更換以免遭人盜用!

  1. password
  2. 123456
  3. 12345678
  4. abc123
  5. qwerty
  6. monkey
  7. letmein
  8. dragon
  9. 111111
  10. baseball
  11. iloveyou
  12. trustno1
  13. 1234567
  14. sunshine
  15. master
  16. 123123
  17. welcome
  18. shadow
  19. ashley
  20. football
  21. jesus
  22. michael
  23. ninja
  24. mustang
  25. password1

2012/09/09

偽 app - 把連結放到 iOS 裝置的主畫面螢幕

有時候在 iPhone 或 iPad 的主畫面螢幕 (Home Screen) 上,會有一些看起來很像 app 但又不是 app 的偽 app,因為這些 app 在 App Store 上搜尋不到,在 iTunes 裡也沒有。
這類的偽 app 實際上只是一個連結,就像在 PC 上,把瀏覽器的網址拖曳到桌面上一樣,點擊之後都是用瀏覽器開啟。

那麼在 iPhone 或 iPad 上開啟之後,怎麼會沒有看到 Safari 的上方的網址列、下方的工具列呢?而且這些連結的圖檔,又怎麼看起來這麼像 app 呢?
原因其實很簡單,就是 iOS 有支援這種效果,只要連結的內容有依照 iOS 的規則設定,就可以看起來像是真的 app 一樣。

2012/08/29

[iOS] 設定透明背景的 UIWebView

webView.opaque = NO;
[webView setBackgroundColor:[UIColor clearColor]];
[self hideGradientBackground:webView];

- (void) hideGradientBackground:(UIView*)theView
{
  for (UIView * subview in theView.subviews)
  {
    if ([subview isKindOfClass:[UIImageView class]])
      subview.hidden = YES;

    [self hideGradientBackground:subview];
  }
}
UIWebView 裡的 html 也要設定成透明背景。
<body style="background-color: transparent;">

UIImage to CCSprite

利用 UIImage 的 CGImage 屬性。
UIImage *myImg = [UIImage imageNamed:@"myImg.png"];
CGImageRef myImgRef = [myImg CGImage];
CCSprite *mySprite = [CCSprite spriteWithCGImage:myImgRef key:@"myImg.png"];

2012/08/04

[Castle Age] Armor of Redemption 入手

Armor of Redemption - 2012/08/04

2012/07/18

載入 Facebook JavaScript SDK (2012.07.)

(官網上建議的載入範例有改,更新一下)
如果要在網站上使用 Facebook 提供的 JavaScript SDK,可利用以下的程式碼載入(2012.07.18. 官網範例):
<div id="fb-root"></div>

這段程式碼最好能緊接在 <body> 標籤之後。

資料來源:JavaScript SDK - Facebook 開發人員

2012/05/27

md5 & raw binary format

直接看 code 吧:
$str = "hello world";

$m1 = md5($str);
$m2 = md5($str, true);
$m3 = pack("H*", $m1);
$tm = unpack("H*", $m2);
$m4 = $tm[1];

echo $m1 . PHP_EOL;  // 5eb63bbbe01eeed093cb22bb8f5acdc3
echo $m2 . PHP_EOL;  // ^?;???Г?"??Z??
echo $m3 . PHP_EOL;  // ^?;???Г?"??Z??
echo $m4 . PHP_EOL;  // 5eb63bbbe01eeed093cb22bb8f5acdc3

// $m1 == $m4
// $m2 == $m3

Git Hosting: GitHub vs BitBucket

GitHub 和 BitBucket 共有特點
  • unlimited public repositories: 公開的 repositories 沒有數量限制。
  • unlimited public collaborators: 公開的 collaborators 沒有數量限制。
  • wiki
  • issue
GitHub 特點
  • 依據 private repositories 數量作為收費基準。免費版不提供 private repositories,付費版最少每月 $7 美金可以有 5 個 private repositories。
  • 提供企業解決方案,可擁有專屬的 GitHub server(當然,是虛擬主機,不是實體主機)。
  • 使用人數多。
BitBucket 特點
  • unlimited private repositories: 私有的 repositories 沒有使用限制。
  • 依據 private repositories 的 user 數量作為收費基準。免費版可以有 5 個 users,付費版每月 $10 美金可以有 10 個 users。
小結
  • 以成本考量,如果需要 private repositories,BitBucket 是比較好的選擇。
  • 若是開源專案,放在 GitHub 上可以有較多的 follower。
  • 企業使用可考慮 GitHub Enterprise 方案,畢竟有一臺專屬的 GitHub server 安全性會比較高。
收費說明頁面

2012/05/16

s3cmd 的 RequestTimeTooSkewed 錯誤訊息

server 上存取 s3 的 script 突然掛了,除錯時發現執行 s3cmd 會出現以下錯誤訊息:
> s3cmd ls s3://mybucket/foo/lalala/
ERROR: S3 error: 403 (RequestTimeTooSkewed): The difference between the request time and the current time is too large.
爬了一下文,發現原因是出在 server 的時間跑掉了,有網友說容錯時間差約在 15 分鐘內。這台 server 時間慢了快半小時,難怪會有問題。用 ntpdate 校正一下時間就 ok 了。

2012/05/01

[Titanium Mobile] 取得 iOS 下的檔案大小

直接用 Titanium.Filesystem.File 的 size 屬性就可以了。
var file = Ti.Filesystem.File(Titanium.Filesystem.applicationDataDirectory, 'test.png');
Ti.API.info('file size is ' + file.size);

2012/04/28

[Titanium Mobile] 讀取遠端 json 檔

遠端 json 檔案內容:
{"url":"http://blog.gilbert.tw/","version":"1.0.0"}
擷取程式碼:
var xhr = Titanium.Network.createHTTPClient({
 onload: function(){
  var obj = JSON.parse(this.responseData);
  Ti.API.info('url: ' + obj.url);
  Ti.API.info('version: ' + obj.version);
 },
 onerror: function(){
  Ti.API.error('get remote json file failed.');
 },
 timeout: 5000
});
xhr.open('GET', 'http://public.gilbert.tw/blog/remotefile.json');
xhr.send();

[Titanium Mobile] 取得 app 版本編號

透過 Titanium.App 可以取得 tiapp.xml 內的設定:

  • Titanium.App.version - 版本編號
  • Titanium.App.name - app 名稱。
  • Titanium.App.id - app 編號。
  • Titanium.App.guid - app 唯一編號。

2012/04/25

Mac 下的 Android Emulator 操作

跟 Android Emulator 搞了好幾天,紀錄一下 Mac 下的指令:
(以下的 Android SDK 安裝目錄是 /Applications/android-sdk-macosx/)

開啟 Android SDK Manager
cd /Applications/android-sdk-macosx/tools
./android

開啟 AVD Manager
cd /Applications/android-sdk-macosx/tools
./android avd

建立新的 AVD
開啟 AVD Manager 之後,按下右側的「New...」按鍵。

啓動 AVD
開啟 AVD Manager 之後,挑選要執行的 AVD 之後,按下右側的「Start...」按鍵。

將 apk 安裝到 AVD 上
先啓動 AVD,再執行
cd /Applications/android-sdk-macosx/platform-tools/
./adb install /path/to/file/app.apk

開啟 AVD 之後的鍵盤操作
  • Menu - F2
  • Back - ESC
  • 改變方向 - Control + F11 或 Control + F12
  • 全螢幕 - Alt + Enter



參考資料:

2012/04/03

Mac 下 wget 的替代方案

在 unix 下習慣用 wget 抓網頁檔案,但 Mac 沒有內建 wget,因此只好用 curl 替代:
curl -O http://www.abc.com/xyz.html

2012/04/02

[Titanium Mobile] 設定 app 顯示名稱

iOS 版只要參考這篇 2012/2/17 的文章 Internationalization of App Names 實作就可以了。但如果是 Android 版,就要注意以下幾個地方:
  1. Android 的 AndroidManifest.xml 是放在 platform/android/ 目錄下,不是放在 platform/android/res/ 目錄下,不要被文章內的截圖給誤導了。
  2. AndroidManifest.xml 裡的 @string/app_name 的 app_name 要和 strings.xml 裡的 key 值一致。如果 strings.xml 是複製文章內 iOS 用的 app.xml,記得要改一下,因為 app.xml 裡的 key 是 appname,不是 app_name,少了這個底線、兩邊就兜不起來。

2012/04/01

CFBundleLocalizations is not of the required type for that key.

今日將 app 送審前進行驗證時出現以下錯誤:
CFBundleLocalizations is not of the required type for that key.
發佈到 iPhone 上測試的時候還很正常,沒想到送審時會出狀況。在 Info.plist 裡的設定:
 CFBundleLocalizations
 zh_TW
查了一下官方文件,CFBundleLocalizations 的型別是 Array,因此正確的格式應該是:
 CFBundleLocalizations
 
  zh_TW
 
但也有網友說這樣寫雖然驗證會過,但 app 執行時會無法正常啓動,建議直接把這個設定移除掉。便將 Info.plist 裡的 CFBundleLocalizations 直接刪掉,在 iPhone 上測試也沒什麼問題,再次驗證也通過了,也就順利送審了!

2012/03/28

CastleVille 之 Debug Menu

顯然是工程版不小心流出來了...
CastleVille - Debug Menu
畫面右側的按鈕上方多了一個 bug 小圖(紅線圈起來的地方),點擊之後 Debug Menu 就開啟來了。不過 server 端似乎有擋,按鈕點擊之後沒有效果,而且還會要求重新載入頁面(還是被發現了?)。

anyway,再次證明,天下沒有不出包的遊戲。

2012/03/26

CodeIgniter 2.1.0 上傳類別 Upload 的 Bug

今天試用了一下 CodeIgniter 的上傳類別 upload,沒想到就遇到的 bug。
不管怎麼設定 config,都出現以下的錯誤訊息:
Severity: Notice  --> Undefined index: tmp_path /web/system/libraries/Upload.php 1058
The filetype you are attempting to upload is not allowed.
後來直接去看 Upload.php 的第 1058 行到底是寫什麼東西:
if (DIRECTORY_SEPARATOR !== '\\' && function_exists('exec'))
{
 $output = array();
 @exec('file --brief --mime-type ' . escapeshellarg($file['tmp_path']), $output, $return_code);
 if ($return_code === 0 && strlen($output[0]) > 0) // A return status code != 0 would mean failed execution
 {
  $this->file_type = rtrim($output[0]);
  return;
 }
}
原來是 $file['tmp_path'] 這裡出了問題。php 的 $_FILES 變數沒有 tmp_path 這個鍵值,明顯是 tmp_name 誤植成 tmp_path。因此將 1058 行的 tmp_path 改成 tmp_name 就可以了。

2012/03/11

[Titanium Mobile] 用內建瀏覽器開啟 url

Titanium.Platform.openURL('http://www.google.com.tw/')

[Titanium Mobile] APNS Code Snippet

// register APNS
Titanium.Network.registerForPushNotifications({
 types:[
  Titanium.Network.NOTIFICATION_TYPE_ALERT,
  Titanium.Network.NOTIFICATION_TYPE_BADGE,
  Titanium.Network.NOTIFICATION_TYPE_SOUND
 ],
 success: function(e){
  var token = e.deviceToken;
  Titanium.API.info('APNS token: ' + e.token);
 },
 error: function(e){
  Titanium.API.info("disabled: " + e);
 },
 callback: function(e){
  alert(e.data.alert);
 }
});

Android App 上架時的 Promo Text

Android App 上架時,有個 Promo Text 欄位可以填寫:
Android App 上架時的 Promo Text 欄位


這個欄位裡的文字,是當 app 出現在像下方最上方的推廣位置時,app 右側顯示的文字。
Promo Text 對應的顯示位置

2012/02/25

[Titanium Mobile] facebook 打卡

可以透過 Titanium.Facebook.requestWithGraphPath() 實現, 記得要取得 publish_checkins 存取許可。
Titanium.Facebook.permissions = ['publish_checkins'];
var data = {
    place: '129184707152754',             // 地點的 facebook ID
    coordinates: {
        'latitude': '24.155192490479',    // 緯度
        'longitude': '121.6223442453'     // 經度
    },
    access_token: Titanium.Facebook.accessToken
};
Titanium.Facebook.requestWithGraphPath('me/checkins', data, 'POST', function(e){
    if (e.success) {
        alert('success: ' + e.result);
    } else {
        if (e.error) {
            alert('error: ' + e.error);
        } else {
            alert('unknown error');
        }
    }
});
如果是 Android 系統,coordinates 要用 JSON.stringify() 處理,不然會打卡失敗,這點要特別注意!
    coordinates: JSON.stringify({
        'latitude': '24.155192490479',    // 緯度
        'longitude': '121.6223442453'     // 經度
    }),

2012/02/18

[網站介紹] .htaccessEditor - 產生 .htaccess 檔

網址:http://www.htaccesseditor.com/
http://www.htaccessEditor.com
網站預設的語系是日文,但右上角可以選擇顯示語系,有繁中可以選擇。

iOS app 之 Promo Codes 常見問題(針對軟體開發人員)

抽空看了一下 App Store 的 Promo Codes 說明,把重點摘錄一下:
  1. 每個版本只有 50 個 Promo Codes。只要 app 有新的版本,就可以再取得 50 個 Promo Codes。
  2. Promo Codes 的有效期限是四個禮拜,產生之後四個禮拜沒用,就會失效。但如果開發者的合約到期沒續約,Promo Codes 會立即失效。
  3. 只有 Legal 角色(也就是 Team Agent 權限)的使用者,才能在 iTunes Connect 中申請 Promo Codes。
  4. 只有在 app 通過審核,並且處於 Ready for Sale 狀態下,才能申請 Promo Codes。
  5. In-App Purchases 目前沒有 Promo Codes。
  6. 使用 Promo Codes 取得 app 的 Apple ID,無法在 App Store 上評分或發表評論。

2012/02/16

[Titanium Mobile] 顯示向上對齊的文字

Titanium.UI.Label 沒有向上對齊(類似 vertical-align)的屬性,如果將 height 設定成 auto 可以達到自動向上對齊的效果,但會失去截字的效果,並且高度變成無法控制。

[Titanium Mobile] 顯示文字: Label, TextField, TextArea

要在畫面上顯示文字,通常是用 Titanium.UI.Label ,但 Titanium.UI.TextField  Titanium.UI.TextArea 這兩個物件也可以用來顯示文字。

Titanium.UI.Label 在官方文件裡的說明:
A text label, with optional background image.
功能就類似 HTML 裡的 <span>,專責顯示文字。

Titanium.UI.TextField 在官方文件裡的說明:
A single line text field.
這就類似 HTML 裡的 <input type=text>,可以讓使用者輸入單一行文字。

Titanium.UI.TextArea 在官方文件裡的說明:
A multiline text field that supports editing and scrolling.
不消說,這就類似 HTML 裡的 <textarea>,可以讓使用者輸入多行文字。

2012/02/13

[Castle Age] Helm of Arcane Energies 入手

Helm of Arcane Energies - 2012/02/13

2012/02/12

SKU number

在 app store 申請 app 上架時要填一個 SKU number 的資訊,欄位旁的說明是:
A unique number used to identify the app you are adding.
這個 SKU 是 Stock Keeping Unit 的縮寫,有人翻譯成「庫存單位」或「最小存貨單位」,係指商品庫存控制時的最小單位。比如說一隻原子筆有筆套和筆兩個部位,如果將筆套和筆各自當作庫存單位,那麼一隻原子筆就有兩個 SKU number,筆套和筆各自有一個 SKU number。如果不將筆套和筆分開來算,兩個合在一起當作一個庫存單位,那就只有一個 SKU number。SKU number 是各公司自行定義、編碼的,以上例來說,一般書局、文具店會把筆套和筆當成單一商品,給與一個 SKU number。但原子筆的製造商,就會將筆套和筆各自賦予一個 SKU number。
因此 app store 裡的 SKU number,是軟體開發者用來分辨自己開發的 app 所使用的唯一編號。雖然欄位說明是寫 a unique number,但實際上可以輸入文字或空白,因此如果不曉得要怎麼輸入,直接輸入 app 名稱也行。唯一要注意的是,這個 SKU number 在 app 建立之後就不能修改,請特別留心(不是送審之後,是在 iTunes Connect 裡完成 Add New App 流程之後就不能改!)。


2012/01/28

免密碼 ssh 登入 server 失敗原因探查

免密碼 ssh 登入 server 這個基本技能從一開始接觸 unix 就學起來用了,最近有台 server 卻無法用這招登入,每次 ssh 都得輸入密碼。由於這台 server 不是我負責的,其上運行的服務也不甚瞭解,因此也不便置喙。

今天有空查了一下原因,原來是檔案系統權限的問題。當以 ssh 登入時在 auth.log 裡出現以下錯誤訊息:

Jan 28 21:32:57 command sshd[30613]: Authentication refused: bad ownership or modes for directory /www/someone

以 ssh 登入的帳號 someone 的家目錄 /www/someone 是以 NFS 掛載的,而 NFS server 上設定 /www/someone/.ssh 這個目錄以及其下的所有檔案,權限均不屬於 someone 這個帳號,因此造成無法免密碼 ssh 登入。

PS. 免密碼 ssh 登入 server 這個基本技能網路上已經有很多文章,搜尋關鍵字是 ssh login without password。