[Windows Phone]解決Windows Phone SDK抓不到VS2010完整版的問題

意興來潮來玩一下Windows Phone芒果機的開發

在開發環境的部分,除了有Windows 7

還要另外安裝Windows Phone SDK

 

Windows Phone SDK官網下載:

http://www.microsoft.com/zh-tw/download/details.aspx?id=27570

安裝之後,如果沒有Visual Studio 2010的話,他會很貼心的幫你安裝

Visual Studio 2010 Express供你使用


各位版大,不知道是否像我一樣

本身已經安裝好了Visual Studio 2010

 

在安裝之後仍然出現Express版,而本身完整版卻沒有安裝完成

可以遵循以下步驟:

相關樣版,而這問題可透過以下方式解決

要複製二個地方

 

第一個地方,C#版本的Silverlight for Windows Phone資料夾:

C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDEProjectTemplatesCSharpSilverlight for Windows Phone

整個Silverlight for Windows Phone資料夾複製到:

C:Users你的使用者名稱DocumentsVisual Studio 2010TemplatesProjectTemplatesVisual C#


第二個地方,VB版本的Silverlight for Windows Phone資料夾:

C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDEProjectTemplatesVisualBasicSilverlight for Windows Phone

整個Silverlight for Windows Phone資料夾複製到:

C:Users你的使用者名稱DocumentsVisual Studio 2010TemplatesProjectTemplatesVisual Basic

 

注意路徑中Visual Basic的空格,一個有一個沒有

若你的Win7版本是32位元的,把紅字中的(x86)字樣拿掉就是你的路徑

紅字的使用者名稱代換成你的使用者名稱

所以最後你的

C:Users你的使用者名稱DocumentsVisual Studio 2010TemplatesProjectTemplates

的 Visual Basic 和 Visual C# 資料夾都會有同名的但內容不一樣的 Silverlight for Windows Phone 資料夾

2012-06-26 10 42 15  

 

 

然後在開始選單中找到 所有程式 > Microsoft Visual Studio 2010 > Visual Studio Tools > Visual Studio 命令提示字元 (2010)

2012-06-26 09 14 22    

在指令鍵入

devenv.exe /setup

不做這個動作的話,在新增的頁面可以看到但不能建立

2012-06-26 10 07 12  


再重開VS2010即可

在檔案 > 新增 > 專案 之中

就會看到新的專案從你的VS2010出現摟

2012-06-26 10 37 12  

 

參考資料:

http://www.dotblogs.com.tw/ian/archive/2012/02/15/69380.aspx

http://mnc363eo.iteye.com/blog/1351962

[MySQL] 如何在phpMyAdmin裡開啟Designer功能

小提示:這是比較進階的文章,不知道等一下的步驟在幹嘛的,就跳過整篇文章吧 

———————————-

想必有用PHP & MySQL寫過網頁吧,想必phpMyAdmin應該是你的好朋友 (笑)

phpMyAdmin裡,其中有個還不錯用的功能就是Designer
可以畫資料庫的關聯圖,對於資料表關聯的了解有很大的幫助

但這功能在之後的版本,預設被關掉了

在這裡可以教你怎麼把它打開

———————————-

而PHP & MySQL自己重頭裝到好的很多
市面上整合平台更多

Appserv、XAMPP、WAMP、MAMP…… 

對於裝在不同的系統(Win、Mac、Linux),路徑也會不致相同

但是有個好消息

phpMyAdmin對於平台的相依性很小
只要PHP和MySQL的環境有架起來
phpMyAdmin它,都能跑

如果你夠大膽,可以去官網下載最新版phpMyAdmin

http://www.phpmyadmin.net/home_page/index.php

 

然後換上去 (撰文的時候使用phpMyAdmin 3.5.1版)

———————————-

以我在使用的XAMPP為例

Windows 版的路徑:
C:\xampp\phpMyAdmin

Mac 版的路徑:
/Applications/XAMPP/xamppfiles/phpmyadmin

Linux 版的路徑:
/opt/lampp/phpmyadmin

 

Apache先關掉,
然後將舊版的phpMyAdmin備份起來(目錄更名),將新版3.5.1的phpMyAdmin複製上去(不要用取代的) 

———————————-

打開目錄底下的config.sample.inc.php,複製一份
檔名叫config.inc.php

使用文字編輯器打開

找到以下這一段:

/*
* phpMyAdmin configuration storage settings.
*/

/* User used to manipulate with storage */
// $cfg[‘Servers’][$i][‘controlhost’] = ”;
$cfg[‘Servers’][$i][‘controluser’] = ‘pma’;
$cfg[‘Servers’][$i][‘controlpass’] = ‘pmapass’;

/* Storage database and tables */
$cfg[‘Servers’][$i][‘pmadb’] = ‘phpmyadmin’;
$cfg[‘Servers’][$i][‘bookmarktable’] = ‘pma_bookmark’;
$cfg[‘Servers’][$i][‘relation’] = ‘pma_relation’;
$cfg[‘Servers’][$i][‘table_info’] = ‘pma_table_info’;
$cfg[‘Servers’][$i][‘table_coords’] = ‘pma_table_coords’;
$cfg[‘Servers’][$i][‘pdf_pages’] = ‘pma_pdf_pages’;
$cfg[‘Servers’][$i][‘column_info’] = ‘pma_column_info’;
$cfg[‘Servers’][$i][‘history’] = ‘pma_history’;
$cfg[‘Servers’][$i][‘table_uiprefs’] = ‘pma_table_uiprefs’;
$cfg[‘Servers’][$i][‘tracking’] = ‘pma_tracking’;
$cfg[‘Servers’][$i][‘designer_coords’] = ‘pma_designer_coords’;
$cfg[‘Servers’][$i][‘userconfig’] = ‘pma_userconfig’;
$cfg[‘Servers’][$i][‘recent’] = ‘pma_recent’;
$cfg[‘Servers’][$i][‘table_uiprefs’] = ‘pma_table_uiprefs’;

拿掉註解(不同版本,其中的值可能有多有少,會有些許不同,
找到你的那一段,不要直接複製,除非你很確定版本和我的相同),然後存檔

然後再打開Apache

———————————-

phpMyAdmin用MySQL的root帳號登入之後
點選匯入

檔案選擇 examples/create_tables.sql 的檔案,執行之後
會出現名字叫phpmyadmin的資料庫

然後按左上角的Exit鈕重新登入

就會選取資料庫時,就會看見Designer了

 

 

 

參考資料:

Enable Designer in PHPMyAdmin

http://www.novell.com/communities/node/8932/enable-designer-phpmyadmin

[Android] 使用HTTP的POST方式和網頁表單溝通 (加上資料庫、執行緒)

Screen Shot 2012-04-06 at 下午4.47.14     

 

這是由之前寫的這一篇

http://j796160836.pixnet.net/blog/post/28994669

所延伸出來的

 

眼尖的網友已經發現,之前放上的程式碼範例已經不能Run了
把專案使用的Android版本放在2.3.3以下就可以正確執行
而把它升到4.0就會出錯

有人發現為什麼了嗎?


打開LogCat就可以清楚的看到

Screen Shot 2012-04-06 at 上午12.13.33  

Android 4.0 (ICS)在網路的部份多了一個新的Exception

叫做android.os.NetworkOnMainThreadException
意思很白話的就是:網路的活動跑在主要執行緒上了啦!

ICS很貼心的告訴你,這樣子你的APP可能會因為等待回應太久(超過5秒)
而會被系統強制關閉(收到ANR)

 

(備註:之前是為了示例方便,所以沒有照多執行緒的寫法撰寫,在這裡當然也就不能執行啦
Android光這點就還蠻嚴謹的)


OK,瞭解為何出錯的原因
也剛好在這裡,帶大家看看多執行緒要怎麼改吧

專案的Layout版面等定義上和之前這篇一模一樣
有特別修改的地方會特別標出

 

package com.J_Test.httpPostTest;

import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast; 

public class Main extends Activity implements OnClickListener

{

   private EditText txtMessage;

   private Button sendBtn;

   private String uriAPI = "http://192.168.1.3/httptest/httpPostTest.php";

   /* 「要更新版面」的訊息代碼 /

   protected static final int REFRESH_DATA = 0x00000001;

 

   /* 建立UI Thread使用的Handler,來接收其他Thread來的訊息 /

   Handler mHandler = new Handler()

   {

      @Override

      public void handleMessage(Message msg)

      {

          switch (msg.what)

          {

          // 顯示網路上抓取的資料

          case REFRESH_DATA:

             String result = null;

             if (msg.obj instanceof String)

                result = (String) msg.obj;

             if (result != null)

                // 印出網路回傳的文字

                Toast.makeText(Main.this, result, Toast.LENGTH_LONG).show();

             break;

          }

      }

   };

 

   @Override

   public void onCreate(Bundle savedInstanceState)

   {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.main);

 

      txtMessage = (EditText) findViewById(R.id.txt_message);
      sendBtn = (Button) findViewById(R.id.send_btn);

 

      if (sendBtn != null)
          sendBtn.setOnClickListener(this);

   }

 

   @Override
   public void onClick(View v)

   {

      if (v == sendBtn)

      {

          if (txtMessage != null)

          {

             // 擷取文字框上的文字

             String msg = txtMessage.getEditableText().toString();

             // 動一個Thread(執行緒),將要傳送的資料放進Runnable中,讓Thread執行

             Thread t = new Thread(new sendPostRunnable(msg));

             t.start();

          }

      }

   }

 

   private String sendPostDataToInternet(String strTxt)

   {

      / 建立HTTP Post連線 /

      HttpPost httpRequest = new HttpPost(uriAPI);

      /*

       * Post運作傳送變數必須用NameValuePair[]陣列儲存

       */

      List<NameValuePair> params = new ArrayList<NameValuePair>();

      params.add(new BasicNameValuePair("data", strTxt));

 

      try

      {

          / 發出HTTP request /

          httpRequest.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));

          / 取得HTTP response /

          HttpResponse httpResponse = new DefaultHttpClient()

                .execute(httpRequest);

          / 若狀態碼為200 ok /

          if (httpResponse.getStatusLine().getStatusCode() == 200)

          {

             / 取出回應字串 /

             String strResult = EntityUtils.toString(httpResponse

                   .getEntity());

             // 回傳回應字串

             return strResult;

          }

      } catch (Exception e)

      {

          e.printStackTrace();

      }

      return null;

   }

 

   class sendPostRunnable implements Runnable

   {

      String strTxt = null;

 

      // 建構子,設定要傳的字串

      public sendPostRunnable(String strTxt)

      {

         this.strTxt = strTxt;

      }

 

      @Override

      public void run()

      {

          String result = sendPostDataToInternet(strTxt);

          mHandler.obtainMessage(REFRESH_DATA, result).sendToTarget();

      }

   }

}


特別注意這裡

  Handler mHandler = new Handler()

   {

      @Override

      public void handleMessage(Message msg)

      {

          switch (msg.what)

          {

          case REFRESH_DATA:

             // …………(相關程式碼)

             break;

          }

      }

   }; 

這是Android對於多執行緒的寫法

這裡做了一個Handler來接收訊息

因為當你建立執行緒,資料處理與主執行緒無關

當然,新建出來的執行緒,是碰不到UI介面的 (會跳Exception)

所以才會如此設計

 

訊息,說穿了就是一個int,可以自行定義訊息的內容

 

/** 「要更新版面」的訊息代碼 */

   protected static final intREFRESH_DATA = 0x00000001;

 

類別一開始就定義這個常數

然後在

public void handleMessage(Message msg){

}

的地方就可以使用 msg.what 存取到訊息的內容

這裡用Switch – case的方式撰寫

 


 

發訊息的函式如下

mHandler.obtainMessage(REFRESH_DATA, result).sendToTarget(); 

發訊息的相關方法呼叫可參考官方說明

http://developer.android.com/reference/android/os/Handler.html

 

文件上可看到,obtainMessage有這幾個多載方法

obtainMessage(int what);

obtainMessage(int what, int arg1, int arg2);

obtainMessage(int what, int arg1, int arg2, Object obj);

obtainMessage(int what, Object obj);

常用的有第一、第二、第四種

 

尤其是第四種,這訊息可以傳入Object

所以自由度很高

 


最後,是建立執行緒

 

// 動一個Thread(執行緒),將要傳送的資料放進Runnable中,讓Thread執行

Thread t = new Thread(new sendPostRunnable(msg));

t.start();

 

這裡是用一個臨時的執行緒的方式

在建構子之中傳入一個Runnable來達成

執行緒的部分也可以用匿名class的方式撰寫

 

// 擷取文字框上的文字

final String msg = txtMessage.getEditableText().toString();

new Thread()

{

       public void run()

       {

            String result = sendPostDataToInternet(msg);

            mHandler.obtainMessage(REFRESH_DATA, result).sendToTarget();

       }

}.start();

 

但這樣的方式要注意,內部類別(Inner class)當中

只能存取外部的常數(這是Java的規定)

final String msg;

所以為何String前面要加上final了

 

詳細多執行緒可參考

[Android] 多執行緒-Handler和Thread的關係

http://j796160836.pixnet.net/blog/post/28766165

[Android] 關於Thread執行緒

http://j796160836.pixnet.net/blog/post/29895257

 


很多網友都問到,

為何我在Android傳送出來的資料
在瀏覽器中怎麼都看不見

因為資料到伺服器上沒有將它存下來
在這裡可以做一些修改

我們把傳到伺服器上的資料
用MySQL存下來,然後再顯示最後輸入的資料

 

以PHP為例,我們在phpmyadmin上
建立一個資料庫,名稱叫 httpPostTest

實際設定如圖:

Screen Shot 2012-04-06 at 下午2.45.22  

這是其對應的SQL

CREATE TABLE IF NOT EXISTS weblog (
log_id int(11) NOT NULL AUTO_INCREMENT COMMENT ‘編號’,
data varchar(255) NOT NULL COMMENT ‘傳入的資料’,
post_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ‘發佈時間’,
PRIMARY KEY (log_id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT=’訊息記錄’ AUTO_INCREMENT=1 ;

 


 

之前使用的 httpPostTest.php 我們做一些修改

<?php

// 資料庫相關資料
$database_dblink = "httpPostTest";
$username_dblink = "root";
$password_dblink = "YOUR_ROOT_PASSWORD";

// 建立資料庫連線
$dblink = mysql_pconnect("localhost", $username_dblink, $password_dblink) or trigger_error(mysql_error(),E_USER_ERROR);
mysql_query("SET NAMES utf8",$dblink);
mysql_query("SET CHARACTER_SET_CLIENT=utf8",$dblink);
mysql_query("SET CHARACTER_SET_RESULTS=utf8",$dblink);
mysql_select_db($database_dblink, $dblink);

// 宣告utf-8的編碼
header("Content-Type:text/html; charset=utf-8");
// 接收POST/GET的資料
$data=@$_REQUEST[‘data’];

// 如果有資料
if (strcmp(trim($data), "")!=0)
{
      // 將資料輸入進資料庫
      $insertSQL = sprintf("INSERT INTO weblog (data) VALUES (‘%s’);", $data);
      mysql_query($insertSQL, $dblink) or die(mysql_error());
}

// 從資料庫撈出來最後一筆資料
$query_rs = "SELECT * FROM weblog order by log_id desc limit 0,1";
$rs = mysql_query($query_rs, $dblink) or die(mysql_error());

$row = mysql_fetch_assoc($rs);
echo "data=".$row[‘data’]."n"."time=".$row[‘post_time’];

?>

這樣在瀏覽器就會暫存最後一筆的資料了

如果有學過PHP相關的語法

以上的程式碼應該不難才是

 

 


最後還是提醒一下,Android還沒有跑出來的朋友
若是在Logcat看到類似Permission denied的字眼

代表你忘記了AndroidManifest.xml的這句摟,詳細看之前寫的這篇

    <!– 這裡加入可以存取網路的權限 –>

    <uses-permission android:name="android.permission.INTERNET" />

 


關於source code的部份,我已經放上gitHub了

https://github.com/j796160836/httpPostTest

[iOS筆記] 關於Protocol和物件導向 (Java下的介面(Interface) )

有關於iOS底下的Protocol

 

請參照至其版大的文章

Protocol in Objective-C

http://blog.eddie.com.tw/2010/12/11/protocol-in-objective-c/

這版大實在寫的思路很清晰,推薦一下摟

(看來我還是要多多拜讀別人的文章才是)

————————————————————————————————

為了響應不全文引用,以下採用節錄的,完整內容請移至版大的文章

 

Objective-C是單一繼承的,如果想要做到一個類別同時擁有多種型別的能力,可以透過實作其它型別的interface來達成這個目的。在Java/AS3是用”interface”這個關鍵字,在Objective-C則是用”@protocol”。

(有寫過Java/AS3的要特別注意不要把interface跟protocol搞混了
,在Objective-C的interface等於Java/AS3的class,而protocol則是相當於interface)

Johnny: 關於protocol這點,我也常常搞混…..= =||


如果你要新增一個自定的protocol的話,可以直接在你的專案裡新增一個protocol檔:

image

新增完成之後(它是一個header檔),就可以開始來寫了,

—————————————————————————————————

程式碼如下:

@protocol Drawable

@required
-(void) draw;
-(void) changeColor;

@optional
-(void) whateverMethod;

@end

在上面這段程式碼裡,我放了三個方法,但沒有寫內容。接下來如果我要實作自這個protocol的話,所有定義在@protocol裡的方法都得實作出來。

如果沒特別標明的,預設是@required。如果你要實作這個protocol的話,照英文字面來看,@required的部份是規定要實作的,@optional的話就隨你高興了。要注意的是@required跟@optional這兩個語法的影響範圍,是從它以下所有的method都會被影響,直到另一個directive或是@end為止


————————————————————————————————————————-

實作protocol的方法就是用”<>”標記,裡面放protocol的名稱。並不限定只能實作一個protocol,如果要實作多個protocol的話,則是用逗點分開

因為在protocol的地方已經有定義好了方法,所以在@interface的地方就不用再特別寫一次,只要在@implementation裡補上該實作的方法就行了。

// ————–

// interface
// ————–
#import <Cocoa/Cocoa.h>
#import “Drawable.h”

@interface Book : NSObject <Drawable>
{
int price;
}
@property int price;

@end

// ————–
// implementation
// ————–
#import “Book.h”
@implementation Book

@synthesize price;

// 實作方法draw
-(void) draw
{
NSLog(@”draw me!”);
}

// 實作方法changeColor
-(void) changeColor
{
NSLog(@”change color!”);
}

@end

 

————————————————————————————————————————-

Johnny: 簡單來講,protocol就是Java裡的介面(Interface),上面開出來的方法(method)
且有@required字樣的都要被實作(implementation)

protocol名稱加綴在類別(class)後面
只是為了要讓Complier,確實的去檢查,開出來的方法

是有都通通有實作完畢

實驗發現,某些Class對於protocol要求沒那麼嚴苛

只要實作出它要的方法,而不用加掛這個綴字

而且避免混淆,我現在習慣通通都加上去

(包含放在Class名稱之後的 < > ,和其protocol要的方法一起宣告在header檔)

 

 

我還是覺得還是要學Java一樣,嚴謹一點比較好,較不會出錯

[iOS] 從檔案載入NSMutableArray和NSMutableDictionary 的筆記

在iOS開發上

若是從檔案讀取一些資料,想必會用到

  • NSMutableArray
  • NSMutableDictionary

這二個類別

Mutable是可變動的意思,所以建立之後還可以變動

NSMutableArray的話存取方式採用序號來存取值

而NSMutableDictionary採用自訂的鍵值(key)來存取值(value)

 

二者可以互相混用,NSMutableDictionary裡面有NSMutableArray

或是NSMutableArray裡面包含NSMutableDictionary (就像本次範例)

 

使用initWithContentsOfFile: 方法來載入plist

https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html#//apple_ref/occ/instm/NSData/initWithContentsOfFile:

NSMutableArray要取得值使用objectAtIndex 方法

https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html#//apple_ref/occ/instm/NSArray/objectAtIndex:

NSMutableDictionary要取得值使用objectForKey方法

https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDictionary/objectForKey:


提外話一下

如果有寫過php的話

他的概念和php的array有一點點類似

http://php.net/manual/en/language.types.array.php

而NSMutableArray類似於

<?php

$array = array("foo", "bar");
var_dump($array);
?>
螢幕輸出:

array(4) { [0]=> string(3) “foo” [1]=> string(3) “bar” }


NSMutableDictionary類似於

<?php
$array = array(
    "foo" => "bar",
    "bar" => "foo"
);
var_dump($array);
?>
螢幕輸出:

array(4) { [“foo”]=> string(3) “bar” [“bar”]=> string(3) “foo” }

 


 

建立一個專案,在專案上按右鍵New File:

Screen Shot 2012-03-25 at 上午10.51.49  

新增一個Property List,名叫article.plist

 

article.plist原始碼如下

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN""http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">

    <array>

        <dict>

            <key>title</key>

            <string>title 01</string>

            <key>content</key>

            <string>content 01</string>

        </dict>

        <dict>

            <key>title</key>

            <string>title 02</string>

            <key>content</key>

            <string>content 02</string>

        </dict>

        <dict>

            <key>title</key>

            <string>title 03</string>

            <key>content</key>

            <string>content 03</string>

        </dict>

    </array>

</plist>

 

 做一個Button出來,綁定TestpList_btn_onClick方法,該方法如下

 

– (IBAction)TestpList_btn_onClick:(id)sender {

   

    // 取得專案中內建的pList路徑

    NSString *path = [[NSBundlemainBundle] pathForResource:@"article"ofType:@"plist"];

    NSLog(@"pList Path: %@n", path);

    // pList中的資料從檔案載入

     NSMutableArray *data_pList = [[NSMutableArrayalloc] initWithContentsOfFile:path];

   

    for(NSInteger i=0;i<[data_pList count]; i++)

    {

        NSIndexPath *indexPath=[NSIndexPathindexPathForRow:i inSection:0];

        NSString *title = [[data_pList objectAtIndex:indexPath.row] objectForKey:@"title"];

        NSString *content = [[data_pList objectAtIndex:indexPath.row] objectForKey:@"content"];

        NSLog(@"Index: %i Title: %@ Content: %@n", i, title, content);

    }

}

 

 然後運行程式,按下按鈕之後,在Log這邊得到以下結果:

Screen Shot 2012-03-25 at 上午10.55.55  


順便補充在iOS上的printf裡的格式跟一般的C語言不同 

https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265-SW1

string 要使用 %@

integer 要使用 %i 而不是 %d

 

瞭解JSON格式

這篇…我想就是給初次看JSON格式的人看的吧
如果懂了它的格式,不會太難

JSON全名叫做JavaScript Object Notation
就是在JavaScript之中,表示物件的一種格式

既然是格式,為何這麼多人愛用
可以好好瞭解一下

 

 

JSON格式簡單來說,就是這二句重點:


物件(object)用大括號 { }

陣列(array)用中括號 [ ]

先記住這概念


如果你看不懂JSON,可以用類似這種線上JSON格式化的網站

http://www.jsoneditoronline.org

幫助你瞭解

google搜尋一下:json format

就會有很多,這個網站我覺得做得不錯
我不是故意要打它的廣告,但這網站應該有助於JSON的學習


 

物件(object)

這裡說的object,不管你曾經在哪裡聽過這個名詞

他就是用key-value的方式儲存

來個範例吧!

{"subject":"Math","score":80}

這就是json裡的object

Screen Shot 2012-12-24 at 11.40.23 AM  

key-value就是指一個鍵值(key)對應一個值(value),跟變數很像

像是subject這個key有個值叫Math

score它的值為80

 

官方網站有個迷宮圖,有助於理解

object  

 


陣列(array)

陣列可能就比較熟悉些

例如

[0,4,5,2,7,8,3]

Screen Shot 2012-12-24 at 12.12.01 PM  

不難理解,就像是之前寫陣列一類似
這裡的範例是使用數字,但也可以是文字布林或者是陣列物件null。當然,混合就不用說了,絕對OK。

value  

 

文字(text)的例子

["Tom", "John", "Amy", "Ivy"]

Screen Shot 2012-12-24 at 12.32.54 PM  

布林(Boolean)

[true, true, false, false, true, true]

Screen Shot 2012-12-24 at 12.34.43 PM  

硬要用key-value的方式解釋的話
就是0,1,2,3的照順序的數字

array  

 

所以物件和陣列,某方面來說(不考慮資料損失),是可以互相轉換

若 物件 -> 陣列

就會損失鍵值(key)的資料,留下值(value)
或是程式到時候指定說,要鍵值陣列(key array),就會把所有的鍵值(key)合併一起成陣列

若 陣列 -> 物件

就可以將每個值編上數字

 

這裡注意一點
json object的鍵值(key),一定要用文字做鍵值

以下是錯誤的

{0:"Tom", 1:"John", 2:"Amy", 3:"Ivy"}  // error syntax

Screen Shot 2012-12-24 at 12.45.37 PM  

正確應改為

{"0":"Tom", "1":"John", "2":"Amy", "3":"Ivy"}

而整個JSON格式文件之中,是不能使用註解的

 

最後用這二個範例結束吧

成績單

[{"name":"Tom","lastname":"Chen","report":[{"subject":"Math","score":80},{"subject":"English","score":90}]},{"name":"Amy","lastname":"Lin","report":[{"subject":"Math","score":86},{"subject":"English","score":88}]}]

Untitled_Panorama1  

看起來很複雜,對吧?
其實不難

我們做成大家看得懂的表格

成績單1

姓名  Tom Chen 
數學 80 
英文  90 

成績單2

姓名  Amy Lin 
數學 86
英文 88 

 

剛剛也有提到這是個成績單
一開始用一個陣列 [] 包起來,然後是二個物件 {}

[{ …學生1… },{ …學生2… }]

學生資料內有姓名和成績

{"name":"Tom","lastname":"Chen","report": …成績資料… }

成績的部份,因為有很多成績資料,所以有用陣列 [] 包起來

{"name":"Tom","lastname":"Chen","report":[{ …成績1… },{ …成績2… }]} 

一個成績資料,也是個物件

{"subject":"Math","score":80}

全部拼起來就成那樣

 

如果用XML的格式寫就長這樣

<data>

    <student>
        <name>Tom</name>
        <lastname>Chen</lastname>

        <report>

            <subject>
                <name>Math</name>
                <score>80</score>
            </subject>
            <subject>
                <name>English</name>
                <score>90</score>
            </subject>

        </report>
    </student>

    <student>
        <name>Amy</name>
        <lastname>Lin</lastname>

        <report>

            <subject>
                <name>Math</name>
                <score>86</score>
            </subject>
            <subject>
                <name>English</name>
                <score>88</score>
            </subject>

        </report>
    </student>

</data>

應該不會太難

 

最後是網站上一開始附的範例

{"name":"John Smith","age":32,"employed":true,"address":{"street":"701 First Ave.","city":"Sunnyvale, CA 95125","country":"United States"},"children":[{"name":"Richard","age":7},{"name":"Susan","age":4},{"name":"James","age":3}]}

Screen Shot 2012-12-24 at 1.57.08 PM  

用XML可能會這麼寫:

<person>

    <name>John Smith</name>
    <age>32</age>
    <employed>true</employed>

    <address>
        <street>701 First Ave.</street>
        <city>Sunnyvale, CA 95125</city>
        <country>United States</country>
    </address>

    <childrens>

        <child>
            <name>Richard</name>
            <age>7</age>
        </child>

        <child>
            <name>Susan</name>
            <score>4</score>
        </child>

        <child>
            <name>Susan</name>
            <score>4</score>
        </child>

    </childrens>

</person>

比起XML,JSON的格式看起來是不是簡潔許多呢?

 


備註

在JSON的格式中,關於中文或其他非英文的部份

一定要用Unicode encode過

通常這個一般處理JSON的函式庫都會做掉

除非你自己print,自己兜出JSON格式

像是

我是中文  就會變成  u6211u662fu4e2du6587

類似這種 u開頭,接一串數字的東西

可以用這個工具做轉換(不過一般程式的library會做掉啦,這不用擔心)

http://www.htmlescape.net/stringescape_tool.html

 

另外有些字元在JSON不能直接打,需要做跳脫的(escape character) 在這
有些大家都很熟悉,就不細講了

"
\
/
b
f
n
r
t

這裡有些字碼表供參考

http://en.wikipedia.org/wiki/List_of_Unicode_characters

 

最後,練練英文,去JSON官方網站去看看吧

http://www.json.org

可以看到不同語言對於這個資料格式的實作
接下來也會提到實作的部分

 

參考資料:

http://zh.wikipedia.org/zh-tw/JSON

[HTTP相關] 解析HTTP封包,瞭解Session ID和3-way handshake(三向交握)

這就是我們一直在用,不管是手機還是瀏覽器
在這虛擬化技術,雲端科技,Web 2.0等等蓬勃發展的年代
只要是上網,一定完全脫離不了Http的關係

對於網路,這是很基底的概念
想要讓技術層面更進一步
可以從日常接觸到的概念開始
讀通了,就很有用

—————————————————————–(以上都是廢話)—————————————————————

好吧,說真的我不大會教網路這種東西
可能有修過網路相關課程的人,可能會比較懂一點

我盡量從觀察到實際結果,配合網路概念解釋一遍 

 

HTTP封包

我先放這次抓HTTP封包的截圖,再來解釋可能會比較有概念一點

2011-10-21 00 09 30.png  

 

這次所使用的軟體是Wireshark,是個抓封包的軟體

http://www.wireshark.org/download.html

裝好之後選擇網路介面然後就可以看到類似像上圖的東西了喔
我想你一定是在看我的文章,你看你的視窗上面有pixnet耶

 


 

講起網路,不免還是從OSI七層開始講起

這個部份我覺得wiki分類的真好  http://en.wikipedia.org/wiki/OSI_model

2011-10-21 00 17 37.png    

有興趣可以點開wiki的連結看,裡面有對應的文章

天音:這時候要像老師一樣諄諄教誨 (雖然我很不想~>"<)

 

OSI七層協定從下到上分別為

實體層(Physical Layer),資料鏈結層(Data Link Layer),網路層(Network Layer),傳輸層(Transport Layer),會談層(Session Layer),展現層(Presentation Layer),應用層(Application Layer)

裡面藍字的內容都是現有協定名字

wiki的目錄,一堆藍字都沒看過沒關係,在這裡,我們只要管  TCP  HTTP  在哪一層就行了


 

對應到我們抓到的HTTP封包

Screen Shot 2012-03-13 at 下午5.36.47  

第一行,是個概覽,這個封包總共收到幾個Frame(訊框)等等

第二行,就是我們收到的Frame(訊框),可以看到我們用Ethernet協定傳送,裡面記錄著最後傳和目標傳到的Mac位址….等等

第三行,就是TCP/IP中的IP協定(Internet Protocol),紀錄著來源和目標的IP等等資訊

第四行,Transmission Control Protocol縮寫就是TCP協定啦,HTTP連線也是基於TCP協定的,可以看到來源和目的的port(連接埠)號

第五行,就是HTTP協定(Hypertext Transfer Protocol)啦

這裡有展開,可以看到完整的HTTP標頭,一個HTTP連線原來附著這麼多的資訊,也是等下要講的重點

第六行,沒甚麼特別的,就只是網頁原始碼

 


封包和傳送原理

封包大概是這樣子的

osi1  

從程式的眼光來看好了,軟體要送個資料到另一台電腦

除了  實體層(Physical Layer) 之外  

會依序從上往下包

你可以想成要送人家禮物要包裝

或想成郵局要送郵務,要在包裹上貼很多標籤

或是辦公室的便利貼,貼一些備註訊息

 

每往下一層就加一些東西上去,到別人的電腦也是這樣,一層層拿掉標籤

最後得到資料

 

HTTP(應用層)也是如此,HTTP是基於TCP(傳輸層)的

在連線的時候也是如此

要先有TCP先連線才會可以跑HTTP的協定

 

 

不要問我為什麼要分那麼多層,網路這東西是有歷史的

很多東西到現今也還在變化 (但這個概念短時間已經是不會變了)

 


先解釋TCP

看到一堆紅線了嗎

分成前三組和後三組

前三組,就是出名的三向交握 (3-way handshake 也有人翻譯三次握手)

(天音:甚麼三向交握都看攏無)

 

看英文比中文意思比較準,意思就是 握手寒暄 啦

 

 

請設想一個情況,想你打skype給朋友
剛接起來網路電話的時候有沒有遇到這樣的情況

[SYN]              我: 哈嚕, 有沒有聽到聲音?

[SYN, ACK]      A: 有聽到,那我呢?有沒有聽到聲音

[ACK]              我: 有滴~

(…….然後開始聊天,喔不是,是傳資料=  =")

 

沒錯,三向交握就這麼簡單

標籤看起來很複雜而已

 

另外這組

[FIN, ACK]

[ACK]

是四向交握協定Four-way Handshake,用來關閉連線的

引用一下文章的內容

1. (B) –> ACK/FIN –> (A)

2. (B) <–     ACK    <– (A)

3. (B) <– ACK/FIN <– (A)

4. (B) –>    ACK     –> (A)

理當要有四個,為何只有二個?我想是Keep-Alive的關係

所以連線沒有斷,保持連線,若有其他的要求就可以馬上繼續連線
而不用重新建立連線


HTTP標頭

HTTP標頭裡面有很多資訊,像是Server的資訊,很明顯是跟Apache做連線

這裡也很清楚看到中間有Set-Coookie: 和PHPSESSID就是Session的ID啦

當Server使用Session時

雖然Session的資料是放在Server上沒錯〈Client看不到〉

為了分辨這個是那個Client連來的
所以會放一個Session ID給Client

(像是你去寄放物品的櫃台寄放東西,櫃台會交給你一把鑰匙一樣)
用鑰匙認顧客

而且這個Session ID會隨著你的連線,在下次要求的時候,放在標頭裡面
一起發送給Server

 

而在網頁設計當中,Session往往都被當成會員登入等依據

當你在清理Cookie的時候,Session ID也一起被你清掉了
也理所當然的被登出了

 

但Session使用上有些限制

  1.  他只能在同一個網域名字下使用,不能跨網域

  2.  Client端要開啟Cookie (當然這項,一般的瀏覽器通常都是開啟的)

  3.  通常Session和Cookie一樣,有Expires(失效時間)的

所以Facebook的認證上考慮到這些限制,才會採用OAuth 2.0

就是模擬Session的原理,只是把Session ID變成token的方式,用HTTP最簡單的GET方式

掛在網址串上面,以做身分的識別

(有關OAuth2.0相關的東西下次再講)


所以Hsuan網友在Android建立HTTP連線裡面

http://j796160836.pixnet.net/blog/post/28994669

問的問題:

 

我在1.php 寫 session 
在2.php echo出session的值
這是沒問題的

但是如果用android端做測試的話
會抓不到session的值
請問這個跟android端有關係嗎??

所以在程式中,Session ID並沒有存下來

 


參考資料:

TCP: SYN ACK FIN RST PSH URG 詳解

https://sites.google.com/site/cimpleteam/articles/tcpsynackfinrstpshurgxiangjie

TCP/IP 概論

http://www2.meps.tp.edu.tw/documents/memo/TCP%EF%BC%8FIP%E6%A6%82%E8%AB%96/index.htm

[iOS] 利用NSURLConnection建立HTTP連線 (GET篇)

最近在研究iOS開發,對於Http連線的好處
在這裡就不再贅述

之前寫過Android版本的,請見:

http://j796160836.pixnet.net/blog/post/28994669

 

雖然我也在學習中,我盡量解釋其方法
如果有誤,還煩請大大們指正

——————————————————————————————————————-

 

開一個新的專案

在Interface Builder版面設計中,拉出一個Button和一個Label

——————————————————————————————————————-

其中 Button Touch Up Instide 中綁定  – (IBAction)request_btn_onclick:(id)sender   方法

LabelReferencing Outlets 綁定  @property (retain, nonatomic) IBOutletUILabel *label;     變數

——————————————————————————————————————-

 

ViewController.h 放入以下宣告

@interface ViewController : UIViewController

{

    NSMutableData *responseData;

}

 

// 開始接收資料,會呼叫此方法

– (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;

// 接收新的資料時,會呼叫此方法

– (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;

// 下載完畢時,會呼叫此方法

– (void)connectionDidFinishLoading:(NSURLConnection *)connection;

// 連線錯誤時,會呼叫此方法

– (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;

——————————————————————————————————————-

ViewController.m 加入以下程式片段

 

#pragma mark – Connection delegate

– (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

    // 開始下載,重置responseData資料

    NSLog(@”didReceiveResponse”);

    [responseDatasetLength:0];

}

– (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

    // 下載中,附加資料

    [responseDataappendData:data];

}

– (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

    // 下載完成,釋放responseData

    [connection release];

    NSLog (@”succeeded  %d byte received”, [responseDatalength]);

    // 轉譯編碼文字

    NSString *responseString = [[NSStringalloc] initWithData:responseDataencoding:NSUTF8StringEncoding];

   

    [responseDatarelease];

   

    label.text =  responseString;

    [responseString release];

}

– (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

    // 下載錯誤

    label.text = [NSStringstringWithFormat:@”Connection failed: %@”,[error description]];

    NSLog(@”Connection failed! Error – %@ %@”,

          [error localizedDescription],

          [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);

}

——————————————————————————————————————-

這段就是按鈕按下去會執行的語法

#pragma mark – Button onClick

 

– (IBAction)request_btn_onclick:(id)sender {

   

    responseData = [[NSMutableDatadata] retain];

    NSString *url = [NSString stringWithFormat:@”http://127.0.0.1/httptest/t.php”];

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURLURLWithString:url ]];

    [[NSURLConnection alloc] initWithRequest:request delegate:self];

   

}

——————————————————————————————————————-

我簡單解釋一下

剛剛在ViewController之中新增一個 NSMutableDatadata 變數 (Mutable代表可變動的)

然後在 – (IBAction)request_btn_onclick:(id)sender 這裡

指定一個 url 就是我們要瀏覽的位置,GET要上傳的內容就串在後面

再來建立一個 NSURLRequest 和 NSURLConnection 把連線建立起來

回應的部分傳進delegate (委派)之中

 

而delegate (委派)有四個

 

// 開始接收資料,會呼叫此方法

– (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;

當系統開始要接收資料的時候這個方法會被呼叫到
要把這 responseData 給清空,如果UI上有ProgressBar的話要將之歸零

// 接收新的資料時,會呼叫此方法

– (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;

每次資料在下載的時候,會不停的呼叫這個方法
可以看到這個data傳入的參數,就是每一小塊一小塊的資料
我們只要把它累加起來即可,如果UI上有ProgressBar的話就可以慢慢累加1

// 下載完畢時,會呼叫此方法

– (void)connectionDidFinishLoading:(NSURLConnection *)connection;

最後跑完會呼叫這個方法,就是你需要做處理的部分
例如顯示到畫面上,存入SQLite….等等


// 連線錯誤時,會呼叫此方法

– (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;

最後就是這個,中間若有網路錯誤等因素就會呼叫這個方法
你可以跳一個提示框或是印Log

 

這個範例的url是指到本機的Apache Server的其中的一隻php網頁
你也可以換成yahoo等網站,只是會跑出一堆網頁原始碼而已

可以玩看看 

——————————————————————————————————————-

以下是我不負責任的把語法翻成大家熟悉的Java
對於像我一樣,對Objective-C有閱讀障礙的

可以看一下(當然,底下的程式完全不能跑,就不用複製了….XD)

 

public  class  ViewController  implements  NSURLConnectionDelegate  {

 

   public  static  UILabel  label;

 

   private  NSMutableData  responseData;

 

   public  void  viewDidLoad()  {

 

      responseData  =  new  NSMutableData();

 

      NSString  url  =  “http://127.0.0.1/httptest/t.php”;

 

      NSURLRequest  request  =  new  NSURLRequest(url);

 

      new  NSURLConnection(request,  this);

 

   }

 

 

 

   @Override

 

   public  void  didReceiveResponse(NSURLConnection  connection, NSURLResponse  response)  {

 

      //  開始下載,重置responseData資料

 

      NSLog(“didReceiveResponse”);

 

      responseData.setLength(0);

 

   }

 

 

 

   @Override

 

   public  void  didReceiveData(NSURLConnection  connection,  NSData  data)  {

 

      //  下載中,附加資料

 

      responseData.appendData(data);

 

   }

 

 

 

   @Override

 

   public  void  connectionDidFinishLoading(NSURLConnection  connection)  {

 

      //  下載完成,釋放responseData

 

      connection  =  null;

 

      NSLog(NSString.format(“succeeded    %d  byte  received”responseData.length));

 

      //  轉譯編碼文字

 

      NSString  responseNSString  =  responseData.toNSStringWithEncoding(NSUTF8NSStringEncoding);

 

      responseData  =  null;

 

 

 

      label.text  =  responseNSString;

 

      responseNSString  =  null;

 

   }

 

 

 

   @Override

 

   public  void  didFailWithError(NSURLConnection  connection,  NSError  error)  {

 

      //  下載錯誤

 

      label.text  =  NSString.format(“Connection  failed:  %s”,  error.description());

 

      NSLog(NSString.format(“Connection  failed!  Error  –  %s”,

 

             error.localizedDescription()));

 

   }

 

}

——————————————————————————————————————-

參考資料

http://www.01-labor.com/2011/07/nsurlconnectionhttp.html

http://stm237.iteye.com/blog/1005752

NSURLConnection官方文件

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html

[iOS開發] 讓JB後的iPhone/iPad能夠從xcode安裝發佈自己開發的程式 (免付費開發者帳號)

注意:這只是拿來做程式開發測試用途,越獄(Jailbreak)後所產生的後果和問題要自行負責

 

首先,先感謝綠毒團隊 讓A5晶片(iPhone 4s / iPad2) 在iOS 5.01也成功越獄了
這下能夠釋放iDevices的全功能,讓iDevices更強大


好吧,這次的重點
是要讓自己寫的iOS程式能夠在實機底下執行做測試
畢竟有些功能模擬器還是無法達到的

若程式的規模不及到要上架的程度
可以使用這個方法來做測試

 

當然,有付費版的開發者帳號最佳 (USD$99/年),就別看此篇了
在開始之前,你需要先JB你的裝置
這可能需要你自行去Google,假設你已經完成越獄了
會有個Cydia的程式安裝在你的裝置上 

 

筆者的環境

Mac OSX 10.7.2 (Lion)

Xcode 4.2.1

iPad2 16G Wifi (iOS 5.01 Jailbreaken)

 

 

等下將會以iOS 5.01 做示範


Step1  到cydia安裝AppSync

 

打開Cydia,使用底下的搜尋框尋找Appsync

100APPLE_IMG_0049.PNG  

就會有很多的名稱叫AppSync for iOS5.0+,擇一安裝即可 (這需符合你裝置的iOS版本)

這裡只是以此為範例 


Step2  編輯SDKSettings.plist

 

打開Finder,找到左側欄的應用程式 > 工具程式 > 終端機

 

鍵入指令

sudo vi /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/SDKSettings.plist

 

若是xcode 4.3版請修改

vi /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/SDKSettings.plist

(感謝Chiakie大大的幫忙)

Screen Shot 2012-01-23 at 下午1.52.00.png

輸入自己帳戶的密碼之後

會打開vim的介面
(vim共有三種模式 一般介面,編輯模式,指令列模式)

詳細vim操作可參照 鳥哥的文章
http://linux.vbird.org/linux_basic/0310vi.php

按下鍵盤的 i 可以編輯,編輯完畢按下鍵盤的 Esc

Screen Shot 2012-01-23 at 下午1.54.04.png

尋找CODE_SIGNING_REQUIRED,這個Key
將其底下的String從YES改成NO

 

編輯完畢按下鍵盤的Esc鍵,直接鍵入 :wq  在按鍵盤的 Enter (或return鍵)

Screen Shot 2012-01-23 at 下午2.39.06.png  

即可退出


Step3  修改Xcode專案的設定

 

打開你的Xcode,開啟你需要編輯的專案

Screen Shot 2012-01-21 at 下午5.14.25.png

依照圖片按到專案名稱,按下Info頁籤

找到Deployment Target,確認iOS Deployment Target是否是為 5.0  (這需符合你裝置的iOS版本)

 

再來相同的地方,找到Build Settings的頁籤

Screen Shot 2012-01-21 at 下午5.13.29.png

找到Code Signing

將以下全部改成Don’t Code Sign

(預設值是Debug > Any iOS SDK和Release >  Any iOS SDK的值為iPhone Developer)

 

 


Step4  連接你的iDevice (iPhone/iPad)

 

連接你的iPhone或iPad

按下專案視窗的右邊Organizer,找到Devices頁籤

Screen Shot 2012-01-23 at 下午12.39.36.png

可以找到你的裝置並且是亮綠燈的,且符合專案使用的iOS版本

 

 

回到專案視窗

  

按Scheme下拉框選擇你剛剛連接的裝置,按下Run

複製 -Screen Shot 2012-01-23 at 下午12.53.46.png  

就會開始編譯

 Screen Shot 2012-01-23 at 下午12.52.47.png

 


Step5  實機測試

 

編譯成功後

Screen Shot 2012-01-23 at 下午12.53.46.png  

會出現這樣

Error launching remote program: fail to get the task for process ……

的錯誤沒有關係

 

查看一下iPhone或iPad

100APPLE_IMG_0048.PNG  

你會發現他已經成功裝到你的機器上摟

 

 


參考資料

http://www.minwt.com/?p=2825

http://happyjc1106.blogspot.com/2011/12/xcode43.html

http://linux.vbird.org/linux_basic/0310vi.php

 

 

 

Macbook pro 13″使用至今的心得

我沒有品牌忠誠度,盡量中立的寫
主要注重在Mac & Windows差異的部分 

==散熱和電源方面==
Unibody用整塊鋁合金片製造,散熱還不錯,只會底下熱而已,鍵盤區不燙,也很有質感
風扇平時很少轉,除非跑即時聲音運算(EX: fl studio)或是圖形運算(EX: 星海II)的時候
風扇全開的時候會嚇到~哈哈,還好是轉一下就會降下來

 

 

i5處理器對我來說蠻夠用的,但好像是插著電源才會跑全速

Macbook pro的電池還蠻能撐的,號稱有6hr啦
實際一直玩它玩3hr不是問題
磁鐵接頭,接上去嚇一跳,Wow~

整體來說比我之前的12.5″的筆電(Acer TM3000)還要輕巧
但裝備一項都沒缺 (除了VGA頭之外啦,那外接線盒有點雞肋) 

 

==使用習慣==
control鍵,option(alt)鍵,command鍵 常常還是處於混亂狀態

在Mac底下:
control鍵還是control鍵
option鍵 = alt鍵
command鍵 = ctrl鍵

在Windows (跑Boot camp)底下:
control鍵 = ctrl鍵
option鍵 = alt鍵
command鍵 = window key……..=口=”

常常按錯不打緊,旁邊還有fn鍵來攪局,按錯頗正常
————————–
再來就是又愛又恨的Muti-touch
很多人搞不清楚,這跟Windows差異也最大
Lion這點做進控制台的觸控版設定頁面裡面,選項旁邊就是影片教學

雙指雙點 = 滑鼠右鍵 (這我最不能苟同,還好可以改成右下角)
雙指滑動 = 滑鼠滾輪 (這還蠻不錯的,不需局限筆電的右側邊)
三指按住窗框可移動視窗位置
四指向左右滑 = 切換不同的桌面 (還OK的項目)
四指向上滑 = 所有視窗和桌面的一覽
四指向下滑 = 相同類型的視窗(EX:瀏覽器) Expose打散
以上二個動作就是沒事做做手指運動XDD
找視窗還蠻順的,不致於說找不到,對於Dock上的工作列表的依賴性就降低了

四指抓取動作 = 打開啟動器,會有所有程式一覽 (類似iphone上的程式icon的放大版)
四指釋放動作(抓取的相反) = 關閉啟動器 or 顯示桌面 (這超難做到的,乾脆改成隱藏點比較快)

雙指縮放 & 雙指旋轉 (這支援的軟體真的不多,只有Apple出了才有效用)

Mac 雖然講求人性化,但還是需強記這些手勢和動作
看看apple要不要傳播給更多人知道這些小玩意兒
————————–
Vmware fusion和Boot camp實在絕配
Boot camp允許你在Mac上安裝Windows (我是裝Win7 x64啦)
而Vmware fusion又可以簡單的詢問你要不要設定Boot Camp虛擬機
轉換一下直接完成
打開虛擬機後就可以輕鬆的在Mac和Windows裡面切換了
當然剛剛的Muti-touch手勢,大部分都有幫你帶進來

沒事簡單的文書處理的時候可以開虛擬機
真正需要效能的時候開Boot Camp
虛擬機不慢,用起來像在用雙核電腦的感覺
這點我還蠻喜歡的

反倒是Boot Camp這就變成了一個缺點
他對於Windows的支援度整體就是失敗

剛剛的Muti-touch手勢全部廢掉
只剩最簡單的觸控版左鍵和右鍵
當然就沒有所謂的滾輪了,請慢慢拖曳Scroll bar吧

 

指令方面因為都是Unix-like所以一些Linux指令是通用的
還沒有用它寫過Windows程式,聽說會和其他的Windows不相容

可能是我對Mac軟體不熟吧,有沒有方便的文字編輯器? (EX: Notepad++或是Emeditor)
 

 

————————–
最後就是長時間在Mac筆電鍵盤打字,手腕和框邊一直磨擦,頗不舒服的 (可能大一點尺寸會改善吧)

delete鍵在哪裡…..原來是fn鍵+delete呀
沒有出名的Ctrl + alt + delete

到Mac底下要被改成  fn鍵 + control + option + delete
XDDD