2013年8月1日 星期四

Apple 的設計真的是走回頭路嗎?

話說今年 WWDC 的開發者大會中, iOS 7.0 的扁平化的設計,當然是有批評的聲音,這些批評直指整個重新的設計沒有新意;讓我們聽聽設計師 evenwu 看出那些內涵了。

2013年5月24日 星期五

為何撰寫 比較有變化視窗程式要學 XAML?

是因為若要開發比較有變化的視窗程式! 所以, 一定要使用 XAML, 比較簡單!

在早期, 有寫過微軟的視窗程式的人應該都知道 MFC4.0, 而Visual C++ 6.0 是活的最久的開發工具. (我在2011年還用了VC6.0 替客戶開發了一整套的應用程式, 只因為要支援 XP SE; 而 .NET3 需要 XP SP3)
在 MFC 的時代, 控制項就那些, 很沒有彈性, 且一點變化也沒有; 而且我們在撰寫時, 隨時要注意有沒有 Memory leak. Memory leak 的測試很花時間, 有時需測到2天2夜才會結果;

進入了 dot COM 時代了, 學了 IUnknown 的觀念, 微軟加強了函數庫的管理和取得的方便性, 和讓 VB/VC/VJ 可共用的函數庫, 也使用了可以互通的資料結構(也就是 Automation 資料型態: VARIANT). 但其實整個視窗開發並沒有很大的變化(只有對網頁ActiveX加強了).

來到了 dot NET 的時代, 微軟使用了 Common Language Runtime (CLR) 機制, 來作資源回收、輾轉呼叫、事件舉發與處理和例外處理. 若對 CLR 很陌生, 沒關係~ 就把它想像成 Java Virtual Mechine 就好了, 只不過是 CLR 是微軟作的, Java VM 是 Sun 作的.

而 dot NET 所開發出來的執行檔(EXE)或動態連結檔(DLL), 在微軟文件稱它叫作 Assembly; 它並不是機器原生碼(Machine Native code), 也就是, 執行電腦內沒有 dot NET 的環境, 它是無法執行的; 和 JAVA 一樣.

Assembly 包含了
  1. Manifest : 包含了全球唯一的識別名稱、版本、文化(Culture)資訊...等等
  2. Type Metadata : 包含了內部所有類別(Class)、資料型別(Type)...等等
  3. MSIL : Microsoft Intermediate Language, 中介語言; 剛提到了 dot NET 開發出來的執行檔並不是機器原生碼, 而所有的程式都會被 Compile 成 MSIL; 而當程式被執行時, CLR 會去開啟 JIT-Compile (Just In Time Compile, 即時編譯器), 透過 JIT-Compile, 產生CPU可執行的機器原生碼.
  4. Resource : 指在開發時, 專案內的圖檔、XAML檔和相關資源檔...等等

前面一大堆, 並都沒提到為何使用 XAML 比較容易開發有變化的視窗程式, 先來看下圖
用XAML開發的程式 

在圖片中,有三個按鈕, 滑鼠在按鈕上會有玻璃特效, 被選取的按鈕有藍色的框, 還有被點擊時, 按鈕有旋轉的特效.. 以上都是 XAML便可達成, 請參考這裡 C# 的指令, 一行都沒加.

在 dot NET 3.0 時(包含3.0之前),只有 Form 視窗程式, 而 Form 視窗程式要作到上述的特效, 那指令可要寫不少; 而在 3.5 之後, 開始支援 Windows presentation foundation (WPF)才開始使用 XAML 語法. 現在, 在 Visual C# 新增一個專案, 仍有 Window Form 和 WPF 可以選擇, 就直接使用 WPF 視窗吧~ 便何況, Visual 2012 己經附了 Expression Blend, 不需要另外購買了.

2013年5月19日 星期日

Visual C#: WPF: Uniform resource identifier (URI)

(Uniform Resource Identifier)URI 統一資源識別元,繼承階層為 System.Uri. 就是以物件的方式去記錄一筆資料,而資料內容就是指到一個資源(這資源可能是 一個圖檔、或一個資料庫、或任何 WPF 的資源檔).

URI 類別和 XCode中的 NSURL 類別很像,而在下面我將協助瞭解 * Uri如何使用:Uri的建構字串 * pack::Pack URI 字串使用的概念:

Uri如何使用:Uri的建構字串

在下面的範例中, 將建立URI的物件.

Uri myPicUri = new Uri("http://www.xxx.com/thePicture.png");  //指到網路某一個圖檔
Uri myBlogUri = new Uri("http://cypress-soho.blogspot.tw/");  //指到本部落格

但如何指到自身程式(Assembly)內的資源檔,那就需要 Pack URI

pack:Pack URI 字串使用的概念:

Pack URI包含了二個元件:授權/路徑.其格式如下

pack://*authority*/*path*

而WPF支援兩種授權:appliction:///siteoforigin:/// , application:///授權 可識別編譯時期己知的應用程式資源檔案.而siteofiorigin:///授權可識別來源網站.

封裝 URI 圖表

而另外需要注意 Pack URI可提供給開放式封裝慣例(OPC)使用,故需要符合OPC要求, 以致 "/"字元必須取代為","字元. 所以在正式使用上,字串為以application:,,,來取application:///

Uri myPng = new Uri("pack://application,,,/cat.png");       //指到Assembly內的cat.png

2013年5月17日 星期五

Markdown 語法 (syntax) 和 範例 (sample)

Markdown 是一個非常方便用來寫部落格的語法。可以透過一些定義好的符號或格式,便可輕易的編排你的文章,先不需要使用大量的HTML,雖然最後仍是需要轉換成HTML。先讓我們先下面的範例:
> ### This is a header
> 
> 1. This is the first list item.
> 2. This is the secord list item.
如此所產生的結果如下:

This is a header

  1. This is the first list item.
  2. This is the secord list item.
就以上所產生的結果,我們可以看到
  1. Blockquotes: Email形式的區塊引言,也在左側上一條灰色的直線,它是利用一個">"的符號所產生的。
  2. 標題:Markdown 所支援的標題從 H1 到 H6。H1 字型最大,而 H6 字型最小;它是以"#"符號來表示,一個#為 H1;而六個#為 H6;
  3. 有序清單:以一個數字開頭接著一個小數點,後面至少要接著一個空格,來表示。另外,還有無序清單,可用符號"*" "+" "-"一個加一個空格來表示。

除了這些,還有
  • 程式碼區塊:以一個tab或四個空格開始,結果會產生如下圖,一個區域。
    我是程式碼區塊
  • 分格線:用三個或以上的星號、減號、底線來建立分隔線。
  • 連結:在字串中,有個關𨧞字會連到指定的網址。以[方括號]標記,接著以括號填入綱址如下:
     如同我在[之前](http://cypress-soho.blogspot.tw/)所提到的... 
  • 強調:在要__強調__的文字,在前後加入一或二個的星號或底線。
    *singleasterisks*
    _single underscores_
    **double asterisks**
    __double underscores__
    
    結果為
    singleasterisks
    single underscores
    double asterisks
    double underscores

  • 坎入圖片:和連結有像,但差別在多了一個驚嘆號。
    ![圖片的替代文字](http://localhost/cat.png)
有關更詳細 markdown語法,請看這裡

2013年4月22日 星期一

Xcode : 如何開啟 facebook 粉絲頁,在facebook app 或 Safari 上

開啟 facebook 粉絲頁,簡單一個指令搞定。
[[UIApplication sharedApplication] openURL: [NSURL URLWithString:@"https://www.facebook/com/taiwanbreezeman"]];
若只是這樣,就遜了。 當 iPhone上有安裝 facebook app,最好能直接打開在 facebook app上。以下便是範例:
NSURL *url = [NSURL URLWithString:@"fb://profile/277473558949767"];
[[UIApplication sharedApplication] openURL:url];
問題來,在 profile 後面那一長串的數字是什麼?? 那便是 facebook 的 profile id。在我解釋如何取得profile id 前;容我介紹一下,social graph 和 profile id 的關係。
social graph 這個詞是2007由 facebook 所提出,其概念很簡單,每個人/事/物都是一個點;而關係是一個便是一條線。你,和親朋好友的關係;和就讀過的學校的關係;和工作的地點的關係;和去過的地點/餐廳或店家的關係; 想像一張白紙,在白紙的中心劃一個點代表你自已,在你自已點的周邊,點上代表著親朋好友/學校/公司/景點或店家的點。再將代表你的點和這些點以線代表關係,連起來。便可形成如下圖(來自Wiki),屬於你的 social graph。
Social_graph

而每一個點都有一個 profile 來描述這個點它代表的人/事/物。而每個點都擁有一個獨一無二的編號,那就是 profile id。
好,言歸正傳,取得 profile id 的方法有二種。 一種是,它就顯示在網址列上:
在網址上

而另一種,無法在網址列上找到。如下圖,是以關鍵字的方式顯示;那就需要 facebook另一個網址來查詢了,查詢網址格式為:"http://graph.facebook.com/{關鍵字}"。頁面顯示便是profile 的內容,在內容中找尋一個名為 "id" 的字串,後面所帶出來的數字,便是 profile id。
透過facebook

2013年4月10日 星期三

Xcode: 讀取 (read) / 寫入 (write) plist file

要開啟 plist file,首先要先知道 plist file 的根 (root) 是何種資料型態。"根"的資料型態有二種:Array / Dictionary。
plist 的根,只能是Array或Dictionary
依資料型態選擇不同,使用不同類別來開啟。

* Array範例:

NSString *plistPath = [[[NSBundle mainBundle] bundle]
stringByAppendingPathComponent:@"MyPlist.plist"];
NSArray *plistArray = [NSArray arrayWithContentsOfFile: plistPath]; //讀取plist file
NSString *propertyString = [plistArray objectAtIndex:2];            //取得字串物件
NSInteger *propertyInt = [[plistArray objectAtIndex:2] intValue]; //取得整數值
Bool propertyBool = [[plistArray objectAtIndex:2] boolValue];    //取得布林值
float propertyFloat = [[plistArray objectAtIndex:2] floatValue];   //取得浮點數值
[plistArray writeToFile:plistPath atomically:NO]; //回寫plist file

* Dictionary範例:

NSString *plistPath = [[[NSBundle mainBundle] bundle]
stringByAppendingPathComponent:@"MyPlist.plist"];
NSDictionary *plistDic = [NSDictionary dictionaryWithContentsOfFile: plistPath]; //讀取plist file
NSString *propertyString = [plistDic objectForKey:@"姓名"];            //取得字串物件
NSInteger *propertyInt = [[plistDic objectForKey:@"年齡"] intValue]; //取得整數值
Bool propertyBool = [[plistDic objectForKey:@"已婚"]  boolValue];    //取得布林值
float propertyFloat = [[plistDic objectForKey:@"身高"]  floatValue];   //取得浮點數

[plistDic writeToFile:plistPath atomically:NO]; //回寫plist file

2013年4月9日 星期二

Xcode : plist file 都支援那些資料格式















在上篇提到,plist file 可以儲存設定 / 資料,但其支援的的資料格式有那些?上圖為從 Apple developer 截圖下來的。一般而言,資料格式有 NSArray / NSDictionary / NSString / NSData / integer / float / Boolean。


  • NSString:儲存字串;
  • NSArray:objective-c 內的陣列型態,和C語言的陣列有些不同,在C語言宣告一個陣列為 "int index[10]",這個 index[] 僅能存放整數,依宣告不同的資料型態,而存放不同類型的資料;而NSArray的第一個不同是,僅能存放 objective-c 的 "id",所謂 "id" 即為物件。第二個不同是不能在放 int 資料,因為 int 資料不是物件,而需要將 int 資料轉為 NSNumber 物件來儲放。第三個不同是NSArray 僅能夠儲放 "id",只是物件都能儲放,可在第零位置上放置字串,第一放置NSData;並不限制要同一種資料型態。
  • NSDictionary:NSArray 這麼好用,在一個陣列中,可以放不同的資料。問題來了,不同位址放不同型態的資料,很難不搞混吧。我也不這麼作,風險太大了。用NSDictionary 吧!NSDictionary 用的不是位址來儲放資料,而是以key值來作索引,例如:以 "name" 來作姓名的索引,便可取出姓名的字串,或用 "age" 來作年齡的的索引,便可取年齡的整數值;
  • NSData:用來儲存 NSData物件,只要是能轉成 NSData的物件皆可;我曾將幾張小圖,分別用 NSData 物件存在 plist file,照樣可以用。
  • integer / float / Boolean:全部都是用 NSNumber 物件來儲存。寫入和讀出的指令要一致;千萬別寫入時用 numberWithBool 寫入boolean 值,而讀取時用 intValue,讀出來的卻是整數值,那就糗了。


ref: Apple developer