The Old Blog Archive (Traditional Chinese), 2004-2009

ObjectiveFlickr新進度:PhotoSearch Demo

這個週末又繼續把ObjectiveFlickr往前推進。整個framework已經重寫過了,現在只剩下兩個class是需要的,一個叫OFFlickrContext,一個叫OFFlickrInvocation。大幅改名是為了讓class name更能反映實際的功能,但也因此讓過去的舊程式要大改才能使用ObjectiveFlickr了。

這一週新寫的demo是這樣子的。

Ruby on Rails是一套很強大的框架,人們為了推廣RoR,錄製了不少短片用以證明RoR有多容易寫web app。其中一個demo是利用RoR加上Flickr API來寫照片搜尋功能。

PhotoSearch.app模仿了那個RoR範例(事實上我連他們的CSS都抄來用了),用來證明,只要使用Objective-C、WebKit、ObjectiveFlickr,一樣可以很快寫出具有Flickr照片搜尋功能的… 嗯… desktop app。

我現在的blog theme不適合用來說明程式碼,我也還不會錄製說明短片。這些都再再說明,我該好好努力在presentation skill上精進了。

總之,有圖有真相:

Public Photo Search with ObjectiveFlickr

以上的 demo 可以這個網址取得。ObjectiveFlickr使用New BSD License公開,程式碼均存放在Google Code上。

附錄:如何用Objective-C寫ObjectiveFlickr的應用程式(草稿)

Warning: because my blog theme isn’t good for showing code, this is going to be an aesthetically unacceptable entry.

在ObjectiveFlickr的Demos group底下,有PhotoSearch這個示範程式。這個程式的構成相當簡單,首先,用Interface Builder拉出三個元件:搜尋欄位、進度風火輪、WebView,然後透過繼承NSWindowController創建出PhotoSearchController,把該連接delegation連接起來。

接著,生成程式碼,然後在 PhotoSearchController.h 中的開頭 #import 這兩個標頭檔:

#import <WebKit/WebKit.h>
#import <ObjectiveFlickr/ObjectiveFlickr.h>

然後在 PhotoSearchController class 中加入以下成員:

OFFlickrContext *context;
OFFlickrInvocation *invoc;

接著修改 PhotoSearchController.m。

首先,我們要加入 awakeFromNib 方法。沒錯,Objective-C 的特色之一是,增加method是不需要於標頭檔宣告的。我們在 awakeFromNib 裡,建立 context 和 invoc 物件:

context = [[OFFlickrContext contextWithAPIKey:OFDemoAPIKey sharedSecret:nil] retain];
invoc = [[OFFlickrInvocation invocationWithContext:context delegate:self] retain];

然後把包在 Resource/ 目錄下的 index.html 給呼叫出來:

[[webView mainFrame] loadRequest:
    [NSURLRequest requestWithURL:
        [NSURL fileURLWithPath:
            [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@”index.html”]
        ]
    ]
];

(呼,有夠長!)

然後在開始搜尋的那一段 control action 中(method startSearch:),增加實際搜尋的程式碼。我們首先要把搜尋文字轉換成有 percent escape 的字串:

NSString *srchstr = [[sender stringValue] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

(還是一樣有夠長!)

然後把風火輪轉起來:

[progressIndicator startAnimation:self];

接著就可以呼叫 Flickr method 啦。因為 OFFlickrInvocation 都幫你做好了,因此呼叫 flickr.photos.search 只要一行:

[invoc flickr_photos_search:nil text:srchstr selector:@selector(handleSearch:errorCode:data:)];

這句話的意思是說呢,呼叫flickr.photos.search方法,userinfo參數是nil,搜尋字串是srchstr,而callback selector則是 handleSearch:errorCode:data: 這個方法。

然後我們要建立一個同名的方法:

- (void)handleSearch:(id)userinfo errorCode:(int)errorcode data:(id)data
{
    // …
}

然後在裡面填上程式碼。我們直接取用 callback 收到的 data 物件,先將 XML 轉成 NSDictionary ,然後直接取出 photo array:

NSArray *photos = [[data flickrDictionaryFromDocument] valueForKeyPath:@”photos.photo”];

我們打算使用 WebKit 來顯示這些照片,因此準備一個字串來插入 HTML 程式碼:

NSMutableString *code = [NSMutableString string];

然後把照片通通串起來:

unsigned i, c = [photos count];
for (i = 0; i < c; i++) {
    NSString *url=[context photoURLFromDictionary:[photos objectAtIndex:i] size:@"s" type:nil];
    [code appendString:[NSString stringWithFormat:@"<img src=\"%@\" />", url]];
}

其中第三行,我們呼叫 OFFlickrContext 的 photoURLFromDictionary: 方法,將 photo object 轉成 URL string。

最後我們呼叫 WebKit 的 DOM 操作介面,把 photos element 取出來,然後改變裡面的 inner HTML,再呼叫script.aculo.us著名的Effect.BlindDown(為什麼著名?因為上述 RoR 範例也這麼用),為我們的範例勾芡:

DOMHTMLElement *e = (DOMHTMLElement*)[[[webView mainFrame] DOMDocument] getElementById:@”photos”];
[e setInnerHTML:code];
[webView stringByEvaluatingJavaScriptFromString:@"new Effect.BlindDown('photos')"];

大體如此。  

3 Responses to “ObjectiveFlickr新進度:PhotoSearch Demo”

  1. [...] And I’ve added another example. This is done after Ruby on Rails’ screencast (on how to use RoR to create Flickr public photo search). I have even copied their CSS. Working with WebKit is always fun, and ObjectiveFlickr gives you the power of accessing Flickr method and return data blocks in native Objective-C. Because of limited time, I only wrote a Chinese blog entry on that, but you can always download the latest build or use the source to see for yourself. [...]

  2. on 13 Oct 2006 at 14:52b6s

    PhotoSearch 不支援 PPC?

  3. on 13 Oct 2006 at 16:36lukhnos

    糗了,忘了在 Xcode project 裡 build PPC binary 了。XD

    沒有 PPC testing environment 果然還是不行的…