Objective-C字符串操作编程实例:货币转换器

equinox· 2010-01-27
作者  equinox

原帖地址  http://www.cocoachina.com/bbs/read.php?tid-6705-fpage-2.html

我想大家在剛剛接觸Objective-C的時候都做過貨幣轉換器,那個轉換器的匯率在程序內部就已經做定了,編譯後不能修改,可是匯率是會變的。既然如 此,不如我們試試做一個線上貨幣轉換器吧。這個程序換算所需要的匯率都由服務器提供,這樣就不會出現匯率無法更新的問題了。

我在網上看到了一個網頁,地址是http://www.google.com/ig/calculator?hl=en&q=100CNY%3D%3FUSD。網頁的內容是:
{lhs: "100 Chinese yuan",rhs: "14.6387 U.S. dollars",error: "",icc: true}
將上述地址中的100、USD、JPY改成不同的字符串,網頁的內容也會隨之變化。
我們得到了這樣的地址:
http://www.google.com/ig/calculator?hl=en&q=color=#ff0000](待轉換的貨幣金額)(待轉換貨幣的類型)%3D%3F(要轉換到的貨幣類型)
會得到這樣的內容:
{lhs: "(待轉換的貨幣金額) (待轉換貨幣的類型)",rhs: "(轉換結果) (要轉換到的貨幣類型)",error: "",icc: true}
下面我們就做一個在線的貨幣轉換器。
首先創建一個Cocoa Project,雙擊MainMenu.xib,進入IB後繪制轉換器的窗口,大致這個樣子。


從library中拖一個Object到MainMenu.xib的主窗口,更改它的類名稱,並建立一個一個Action四個Outlet分別與窗口中的按鈕和TextField連接。


選擇剛剛創建的Object,點擊File,Write Class Files。
回到XCode,選擇剛剛創建的頭文件,在@interface後的冒號後面加上NSObject。選擇剛剛創建的.m文件。
上面提到的地址如果轉化成格式字符串的話會是這個樣子:
@"http://www.google.com/ig/calculator?hl=en&q=%@%@%%3D%%3F%@",待轉換的貨幣金額的NSNumber實例,待轉換貨幣類型的NSString字符串, 要轉換到的貨幣類型的NSString字符串
為什麼我要使用NSNumber實例而不直接使用"%f"標記?其實是為了精確度。如果使用"%f"標記的話小數的位數限制會比較大。當然,如果你要被轉換的數字是float的話,直接使用"%f"就行了。
我們在- (IBAction)convert:(id)sender方法的實現區域中寫上以下代碼:
    NSNumber *number=[NSNumber numberWithDouble:[Amount doubleValue]];
    NSString *base=[From stringValue];
    NSString *target=[To stringValue];
    NSString *URLString=[NSString
    stringWithFormat:@"http://www.google.com/ig/calculator?hl=en&q=%@%@%%3D%%3F%@",number,base,target];
這樣我們就能得到一個包含用作轉換的URL字符串的變量URLString,我們現在需要讀取在這個URL地址中的內容,代碼如下:
    NSString *content=[NSString stringWithContentsOfURL:[NSURL URLWithString:URLString]
                       encoding:NSASCIIStringEncoding error:nil];
這樣變量content中就包含了這個URL中的內容,現在我們就要對字符串進行裁剪工作了。我們先分析一下訪問頁面http://www.google.com/ig/calculator?hl=en&q=100CNY%3D%3FUSD時返回的內容。
{lhs: "100 Chinese yuan",rhs: "14.6387 U.S. dollars",error: "",icc: true}
我 們看到,在“rhs: "”(裡面包含一個冒號)後緊跟著的數字就是換算的結果。我們知道裁剪字符串有方法"-subStringFromIndex:" 和"-subStringToIndex:",但是我們現在要怎樣才能得到這個數字開頭的Index和結尾的Index呢?我們可以通過以下代碼實現:
    int begin=[content rangeOfString:@"rhs: \""].location+[content rangeOfString:@"rhs: \""].length;
    content=[content substringFromIndex:begin];
這 樣我們就裁去了換算結果前的字符了。"-rangeOfString:"方法能在接收者(就是那個字符串)中查找字符串“rhs: "”,並返回該字符串中第一個出現的“rhs: "”字符串的范圍(NSRange)。范圍是什麼?它是一個包含了范圍的開始位置(location)和長度(length)的數據結構。在上面的代碼 中,我們獲得了數據結構[content rangeOfString:@"rhs: \""]的開始位置和長度,並把它們加在一起,得到的就是這個數據結構結束位置後一個字符的位置(因為length不是從0開始的),然後進行的裁剪工作 就很簡單了。
到了這一步,如果我們使用[content doubleValue]或者[content floatValue]也能直接得到換算結果,但是這樣有時會出點問題,而且看上去也不太和諧,我們還是用字符串處理的方法來得到換算結果吧。
分析打開頁面時得到的內容,我們可以看到數字的末尾接著的是一個空格。我們使用下面的代碼進行裁剪:
    content=[content substringToIndex:[content rangeOfString:@" "].location];
上面提到,"-rangeOfString:"方法只會返回第一個出現的符合條件字符串的Range,所以不用擔心字符串中包含了不止一個空格。需要注意的是,"-subStringToIndex:"方法中那個Index裡的字符是不會在subString裡的。
最後一步,別忘了把計算的結果輸出到畫面上哦。
    [result setStringValue:[@"result:" stringByAppendingString:content]];
這一步可以用"-stringByAppendingString:"方法,用"-stringWithFormat:"也可以。一切完成以後,就按下Build and Go吧。



我們完成了一個在線的貨幣轉換器,如果我們沒有上網的話,貨幣轉換器就不能正常工作。不如大家動動腦筋,做一個線上可以用,線下也可以用的貨幣轉換器吧。(我不是指剛接觸Objective-C時做的那個貨幣轉換器,要能自動更新匯率的……)

Ps.如果沒有聯網就使用這個貨幣轉換器的話會引起崩潰,所以我在例子中加了一個判斷語句,完整的代碼:
    NSNumber *number=[NSNumber numberWithDouble:[Amount doubleValue]];
    NSString *base=[From stringValue];
    NSString *target=[To stringValue];
    NSString *URLString=[NSString
    stringWithFormat:@"http://www.google.com/ig/calculator?hl=en&q=%@%@%%3D%%3F%@",number,base,target];
    NSString *content=[NSString stringWithContentsOfURL:[NSURL URLWithString:URLString]
                       encoding:NSASCIIStringEncoding error:nil];
    if (content!=nil) {
    int begin=[content rangeOfString:@"rhs: \""].location+[content rangeOfString:@"rhs: \""].length;
    content=[content substringFromIndex:begin];
    content=[content substringToIndex:[content rangeOfString:@" "].location];
    [result setStringValue:[@"result:" stringByAppendingString:content]];
    }
    else {
        NSAlert* alert=[NSAlert alertWithMessageText:@"Error" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Please Connect the Internet."];
        [alert runModal];
    }

附件: Currency Online_Example.zip