What Is Software Design?

程式設計不是 “building software”,而是 “designing software”。

Is Design Dead?

軟體系統的設計是演進來的,不能一步到位,而是要藉由憑繁與使用者互動得到的回饋來修改系統設計。

Programming is Gardening, not Engineering

與其把程式設計比喻成蓋房子,實際上更像是園藝。

Orthogonality and the DRY Principle

所有程式設計活動其實都是維護,因為絕大部分的時間都在改code,寫一點改一點。即使是新專案,也很快需要回頭作修改。

2013年12月19日 星期四

Bower 管理網站套件 使用Polymer

bower 是 Twitter 團隊開發的一套網頁工具,用來管理或安裝 Web 開發所需要的 Package,像是 CSS 和 JavaScript,也可以依據套件的相依性來安裝,簡單來說,開發者不用再去煩惱套件相依性問題,以及時間久了想更新最新版本,還要到各 Package 網站來下載,這些步驟都省了,一個指令就可以全部做完上述的步驟。

透過 
Node.js 的 npm 工具來安裝

指令npm install bower -g

需要等上一段時間


查詢已經安裝的套件:

bower list


假設要安裝 jQuery 套件,請執行底下指令

bower install bootstrap spine jquery


執行上述指令,會列出專案安裝的套件名稱及版號
/home/www
├── backbone-amd#0.9.9
├── handlebars#1.0.0-rc.1
├── jquery#1.8.3
├── requirejs#2.1.2
└── underscore-amd#1.4.3
移除已安裝的套件:
bower uninstall jquery
升級已安裝套件:
bower update jquery
搜尋套件:

bower search jquery



Bower 套件相依性

在專案目錄底下新增 component.json bower.json 檔案,裡面寫入 (或者可透過 bower init 來初始化專案)
{
    "name""xxxxx",
    "version""1.0.0",
    "dependencies"{
        "jquery""1.8.3",
        "backbone-amd": null,
        "underscore-amd": null,
        "requirejs": null
    }
}

完成存檔後,請在專案目錄底下執行 bower install,會發現所有套件都會被安裝到assets/javascript/vendor 目錄,版號的定義請按照 semver 標準



參考文獻:http://blog.wu-boy.com/2013/01/bower-is-a-package-manager-for-the-web/


使用 bower 安裝 Polymer 0.1.1 

  1. Get the  polyfill libraries:
     bower install --save Polymer/platform
  2. Get the  core sugaring:
     bower install --save Polymer/polymer
  3. Get the  elements:
     bower install --save Polymer/polymer-elements
     bower install --save Polymer/polymer-ui-elements

你下完上面的指令後,該資料夾下會多出這個資料夾 bower_components/ 


在資料夾創造  index.html 的檔案  內容如下:

<!DOCTYPE html>
<html>
  <head>
    <script src="bower_components/platform/platform.js"></script>
    <link rel="import"
          href="bower_components/polymer-ui-tabs/polymer-ui-tabs.html">
  </head>
  <body>
    <polymer-ui-tabs selected="0">
      <span>One</span><span>Two</span><span>Three</span><span>Four</span><span>Five</span>
    </polymer-ui-tabs>
  </body>
</html>
Test your environment


不能直接開啟檔案 你的chrome 會檔
你必須要把他掛載到 iis 之類的


結果如下:




2013年11月7日 星期四

git - 在 master 上面加上新 tag

git - 在 master 上面加上新 tag

git tag -a (v1.3branch) -m "Release v1.3 Tag"



====================================

git tag v2.4.0  <===給tag

git push --tags <==tag push 上git

2013年11月6日 星期三

判斷是否為 iPhone 5

#define iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO)


所以當使用時,僅需照以下寫法使用即可囉
if (iPhone5)
//do something for iPhone 5
else
//do something for iPhone 4s 4 3GS etc..

ios table view 要把 Header table 拿掉

//設置Header table的高度

- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 1;

}

cocoapods 的更新指令


要更新 cocoapods

sudo gem update cocoapods




要更新 podfile內的版本

pod update

2013年10月24日 星期四

Eclipse 顯示中文 編輯中文 中文亂碼

step1.
step2.


恭喜你的亂碼,是否已經變回正常的中文字了呢?

2013年10月17日 星期四

輸入Picker View 樣式 資料時 navigation bar 要灰色 不能使用

step1.

全域宣告


UIButton *barBlockBut;

 像是如下:

@interface SportViewController () <UITextFieldDelegate>

{
  UIButton *barBlockBut;
}

step2.


調用textFieldDidBeginEditing

- (void)textFieldDidBeginEditing:(UITextField *)textField

{

    if(textField == (sportTimeTextField 這裡填寫您輸入的textField))
    {
        if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)         {
        self.view.window.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
        }

        barBlockBut = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
        [self.navigationController.navigationBar addSubview:barBlockBut];
        
    }

}

step3.

- (void)textFieldDidEndEditing:(UITextField *)textField
{


   if(barBlockBut)
    {
        [barBlockBut removeFromSuperview];
        barBlockBut = nil;
        if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
            self.view.window.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
            
        }
        
    }


}


ps:

記得 該UITextField  要設定

TextField.delegate = self;


2013年10月4日 星期五

ios7 status bar 隱藏 hide

ios7對於 狀態列有很大的改變

舊的程式碼為
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];

不過在ios7中這個方法已經無法work了

解決方法1.

到infor.plist中 加入 key: UIViewControllerBasedStatusBarAppearance
設置為no

這樣就告訴系統說 status bar 不依賴 UIViewcontroller.

解決方法2.

- (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; //UIStatusBarStyleDefault = 0 黑色文字,浅色背景时使用 //UIStatusBarStyleLightContent = 1 白色文字,深色背景时使用 }
上面的code是控制顯示時的樣式,下面的code是控制是否顯示status bar

調用以下的code 會觸發上面的code
- (BOOL)prefersStatusBarHidden { return NO; //返回NO表示要显示,返回YES将hiden }



[self setNeedsStatusBarAppearanceUpdate];

如果想加入動畫如下:

[UIView animateWithDuration:0.5 animations:^{ [self setNeedsStatusBarAppearanceUpdate]; }];


參考文獻:http://www.ifun.cc/blog/2013/09/28/ios7yin-cang-status-bar/

2013年9月27日 星期五

git commit 排除掉不需要的資料

在git 裡面需要commit 最笨的方法就是 git add . 的指令會把所有東西都commit 上去

有些檔案我們不希望加入版本控制的追蹤,例如說Database的schema或是一些log檔,這時候你可以將他們加入 .gitignore 中來讓 Git 忽略他們,使用編輯器來打開你的 .gitignore 檔案。

利用這樣的方法  再搭配 git commit -a 來做commit的動作可以避免資料雜亂與龐大~!


2013年9月25日 星期三

git 自己建立一個新的 Repository

step1.
到你要存取的資料夾下


git init

這時你就會看到 Git 告訴你說已經在這邊建立好一個新的 Git Repository。


Clone(複製)別人的 Repository



將他複製起來後到你的目錄下輸入 git clone
$ https://github.com/JOHNBASS/Sports-stars.git
如此便會將這個 Git Repository下載到我們的資料夾, git clone 預設會將下載的 git 存成一樣檔名的資料夾,如果你要更改成別的名稱的話只需要在網址後面加上你想要更改的名稱即可,像是:
$ https://github.com/JOHNBASS/Sports-stars.git test1
這樣子下載下來的 Repository 的名稱就會從原本的 Sports-stars 變成 test1 了。

參考資料:http://gogojimmy.net/2012/01/17/how-to-use-git-1-git-basic/

Git alias 的功能 縮短指令

Git 也有提供 alias 的功能

例如你可以將 git status 縮寫為 git stgit checkout 縮寫為 git co 等,你只要這樣設定

git config --global alias.st status

這樣一來只要打 git st 就等同於打 git status 了。

Git 預設輸出是沒有顏色的,我們可以讓他在輸出時加上顏色讓我們更容易閱讀:


git config --global color.ui true

參考文獻:http://gogojimmy.net/2012/01/17/how-to-use-git-1-git-basic/

2013年9月11日 星期三

UITextField 設定 游標的 顏色 set color

step1.

宣告一個 UITextField *bmiTextField;

加入


 bmiTextField.delegate = self;



step2.

設定事件

- (void)textFieldDidEndEditing:(UITextField *)textField
{

      //確定text裡面有值
        if(textField.layer.borderWidth)
        {
            textField.layer.borderWidth = 0;
            textField.backgroundColor = [UIUtility greenColor];
            textField.textColor = [UIColor whiteColor];
           //設定游標顏色
            [[textField valueForKey:@"textInputTraits"] setValue:[UIColor whiteColor] forKey:@"insertionPointColor"];
        }

       
    }
//確定text裡面沒有值
    else
    {
        [[textField valueForKey:@"textInputTraits"] setValue:[UIColor blueColor] forKey:@"insertionPointColor"];
        textField.layer.borderWidth = 0.5;
        textField.backgroundColor = [UIColor whiteColor];
        textField.textColor = [UIColor blackColor];
    }
}

2013年9月5日 星期四

UITextField 後面加入小x 清除 輸入 資料 / 清除的事件

step1.


 UITextField *endTextField;


endTextField[[UITextField alloc] initWithFrame:CGRectMake(10, 50, 300, 30)];

    [contentBaseView addSubview:endTextField];

endTextField.delegate = self;
    
endTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
    
//加入後面的小xx
endTextField.clearButtonMode = UITextFieldViewModeWhileEditing;

step2.

//這是textfield 清除的事件

-(BOOL)textFieldShouldClear:(UITextField *)textField
{
    //NSLog(@"check in textFieldShouldClear");
    textField.text = @"";
    self.period.endDate = nil;
    return YES;
}

NSUserDefaults Save/Read/Clear 儲存/讀取/清除

step1.
// 定義名稱 define key
#define kIsActive @"isActive"
#define kUserName @"userName"
step2.
// 讀取資料
-(void)loadInfo {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSLog(@"Name : %@", [defaults stringForKey:kUserName]);
NSLog(@"isActive : %@", ([defaults boolForKey:kIsActive] ? @"YES" : @"NO"));
}
step3. 
// 儲存資料
-(void)saveInfo {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *userName = @"Hank";
BOOL isActive = YES;
[defaults setObject:userName forKey:kUserName];
[defaults setBool:isActive forKey:kIsActive];
}
step4. 
// 清除資料
-(void)clearInfo {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:kUserName];
[defaults removeObjectForKey:kIsActive];
}
 
step5. 主程式
// 執行
- (void)viewDidLoad
{
[super viewDidLoad];
[self saveInfo];
[self loadInfo];
[self clearInfo];
[self loadInfo];
}

2013年8月28日 星期三

mac 開發 android 安裝 IDE

step1

下載ADT Bundle
http://developer.android.com/sdk/index.html



step2
啟動Eclipse

step3

升級套件

如果遇到要求升級的錯誤訊息,可從Android SDK Manager升級套件 


step4

可從Window -> Android SDK Manager 打開Android SDK Manager 視窗





參考http://apphook.blogspot.tw/2013/08/adt-bundle.html

Mac 辨別 32it or 64bit





開terminal輸入uname -a, 出現i386事串就是32,x86_64就是64位元。


2013年8月20日 星期二

Phonegap LocalNotification 本地推播 Android

step1.
請先請到以下的網址 下載 phonegap-plugins
https://github.com/phonegap/phonegap-plugins/tree/master/Android/LocalNotification

step2.
複製LocalNotification.js 到你的 www資料夾內
並且在index.html 中把他加入進去
<script type="text/javascript" charset="utf-8" src="js/LocalNotification.js"></script>

step3.
創造一個 package  命名為com.phonegap.plugin.localnotification

AlarmHelper
AlarmOptions
AlarmReceiver
AlarmRestoreOnBoot
LocalNotification
以上的java檔加入

step4.
AlarmReceiver 來修改錯誤
將R檔選擇到你自己目前的drawable.ic_launcher

final Notification notification = new Notification(R.drawable.ic_launcher, tickerText,
System.currentTimeMillis());


LocalNotification來修改錯誤
這已經是舊版的
//import com.phonegap.api.Plugin;
//import com.phonegap.api.PluginResult;
改為新版的
import org.apache.cordova.api.CordovaPlugin;

import org.apache.cordova.api.PluginResult;

還有alarm 這 改為以下的Code
alarm = new AlarmHelper(this.cordova.getActivity());

step5.

Update your res/xml/plugins.xml file
加入以下的code


<plugin name="LocalNotification" value="com.phonegap.plugin.localnotification.LocalNotification" />

step6.

 AndroidManifest.xml 檔案裡面 找出<application>標籤
加入以下的code


<receiver android:name="com.phonegap.plugin.localnotification.AlarmReceiver" >
</receiver>

<receiver android:name="com.phonegap.plugin.localnotification.AlarmRestoreOnBoot" >
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

step7.
html 的使用方法

<!DOCTYPE html>

<html>
    <head>
        <meta charset="utf-8" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
        <link rel="stylesheet" type="text/css" href="css/index.css" />
        <script type="text/javascript" src="cordova_2.9.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
        <script type="text/javascript" charset="utf-8" src="js/LocalNotification.js"></script>
        <title>Hello World</title>

    <script type="text/javascript">
    document.addEventListener("deviceready", appReady, false);

    function appReady() {
        console.log("Device ready");
        if (typeof plugins !== "undefined") {
            plugins.localNotification
                    .add({
                        date : new Date(),
                        message : "Phonegap - Local Notification\r\nSubtitle comes after linebreak",
                        ticker : "This is a sample ticker text",
                        repeatDaily : false,
                        id : 4
                    });
        }
    }

    document.addEventListener("deviceready", appReady, false);
</script>

    </head>
    <body>


        <div class="app">
            <h1>Apache Cordova</h1>
            <div id="deviceready" class="blink">
                <p class="event listening">Connecting to Device</p>
                <p class="event received">Device is Ready</p>
            </div>
        </div>

         <script type="text/javascript">
             //app.initialize();
         </script>
    </body>

</html>