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

ObjectiveFlickr Demo小更新

結果發現,PhotoSearch.app 竟然忘了建 PowerPC 版本了。已經更新(請重新下載同一個 ObjectiveFlickrDemo-latest.zip),造成大家困擾真是抱歉。m(_ _)m

關於學做人的書摘兩則

兩則摘錄。

一篇出自The Economist上看來的Obituary, Gyorgy Faludy (1910-2006):

… But when the Soviet tanks rolled in he fled west again: to Vienna, Florence, Malta, New York and Toronto, where he set up home with an American dancer called Eric Johnson.

The handsome young man had tracked him down in Malta after reading “My Happy Days in Hell”. Mr Faludy was living there after his wife died. He fell hard for Eric, writing sonnets to him. In Toronto they shared a tiny apartment with a pair of finches; the birds would perch on Mr Faludy’s typewriter, flying up each time he bell signalled the end of another line.

For more then 20 years, until 1920 when Communism fell, Mr Faludy stayed in Canada. He at last returned home, his books unbanned after four decades, to live in a spacious flat overlooking the Danube given to him by the city authorities. There, he went on shocking people. He dumped Eric for a lissom poetess more than 60 years his junior, maried her and appeared with her, almost naked, in the pages of the Hungarian edition Penthouse magazine…

讀了Steve Wozniak的iWoz。奇異的是,不管台灣的商業雜誌怎麼寫,我還是對諸如iCon一類的書提不起興趣。Steve Wozniak的說話方式有趣多了。第一次看他的網站時,覺得這人怎麼總是起頭我我我,尤其是對於Apple I/II獨力完成一事(他書中有提到他在意的原因)。iWoz一書雖然是他人代筆,大體跟他網站上的文章差距不大。

我是跳著把書看完的,書中提到了他對越戰的看法,他的求學歷程,後來怎麼用賺來的錢辦演唱會,還有喜歡教書等等。我只是很意外讀到了這一大段話,而覺得,這本書不需要再摘錄其他任何地方了:

Ethics always mattered to me, and I still don’t really understand why he [Steve Jobs] would’ve gotten paid one thing and told me he’d gotten paid another. But, you know, people are different. And in no way do I regret the experience at Atari with Steve Jobs. [...]

Steve and I were the best of friends for a very, very long time. We had the same goals for a while. They jelled perfectly at forming Apple. But we were always different people, different people from the start.

You know, it’s strange, but right round the time I started working on what later became the Apple I board, this idea popped into my mind about two guys who die on the same day. [...]

In my head, the guy who’d rather laugh than control things is going to be the one who has the happier life. That’s just my opinion. I figure happines is the most important things in life, just how much you laugh. The guy whose head kind of floats, he’s so happy. That’s who I am, who I want to be and have always wanted to be.

加下來這一段是我劃的線:

And that’s why I never let stuff like what happened with Breakout bother me. Though you can disagree–you can even split from a relationship–you don’t have to hold it against the other. You’re just different. That’s the best way to live life and be happy.

And I figured this all out even before Steve and I started Apple.

(Steve Wozniak and Gina Smith, iWoz: Computer Geek to Cult Icon. London: Headline Publishing, 2006. pp. 148-149.)

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')"];

大體如此。  

學做人

標題歸在avant lettre一類的原因是,我常常不知道該怎麼把從小學到、關於人格養成的詞彙,對應到英文裡。

例如,「做人處事的道理」。

曾經在一本寫給華人的法語學習書中讀過類似下面的句子:其實學語言跟學樂器是很像的,初學時是練習那幾個把位,學精了以後還是在練習那幾個把位。

最近聽到了一些絕交息遊的故事,那種「以後再也不想跟那種人往來」的話,溫度很是冷冽。即使日後大家在這麼小的世界見到面,還能維持成年人應該有的禮貌與哈哈,但是心裡面對絕交對象的尊重和溫度已經沒有了。

成年人說絕交,又何嘗不跟小朋友「以後再也不跟你好了」那樣,切巴斷,一刀兩斷,也許日後留待回憶時才追悔。不過,聽起來,成年人的絕交,即便很可能真的是為了對外人來說毫不足道的事,也絕對不會再有看待兒時的距離與輕鬆了──甚至更殘酷地說是不會再有生命的餘裕,來讓時間把傷害與裂痕給沖淡為平復與可笑。

放寬心來看,人與人的關係經常是在調整的。小村莊理論。然而新的關係建立困難,而太多垃圾關係太早佔滿位置絕對只是提早用掉quota。結果說來說去還是那句,交友要謹慎,慎始慎終慎獨,友直友諒友多聞。國中課本裡林良寫給孩子的交友守則依然是如此真確(現在還有收那一篇嗎?),但很不幸地因為是白話文,而大概沒什麼人有上到。

記得有種說法,朋友之間的嫌隙起於狎戲。狎戲不見得出於輕浮嬉鬧,也許更多是起於不在乎別人的在乎,或是「不明白你幹嘛生這麼大的氣」,於是對方就更火,覺得在你眼中已不把他當人看。聽起來很嚴重,但是說真的,我們對待生意上往來的顧客,可能真的還比朋友好,也難怪對方要生這麼大的氣了(顧客生氣時,我們起碼還會在話術層次上說,我們理解您的生氣云云呢)。

說多了。其實我只是好奇,西方人的人格養成,是怎麼教導這些東西的。雖然我的猜想,有許多來自《聖經》,要愛你的鄰人,要寬恕他人,而若你的右手叫你行惡,則刨去你的右手,等等、等等。

當然另外就是在那些人格養成外圍的潛規則。Somehow that’s not part of my language/ideologue, and perhaps that’s why I never understand the way it works.

回到最初的主題,我只是很好奇一個西方人會怎麼講述多年朋友惹到火大,因而起了絕交斷義,rant and curse半天,大表不滿,不吐不快,這樣的一件事而已。進場時要想到退場(”In my beginning is my end” — T. S. Eliot),或許從這些絕交息遊斷義的故事、話語、不爽與憤恨中,更能看出所隱含的對人的期待是什麼?

Update: 希臘人對朋友以及朋友之間的愛也說了很多,但是很好奇他們怎麼看待別離與斷義。看來似乎是不錯的讀書主題。

ObjectiveFlickr 框架完成

ObjectiveFlickr 的架構初步完成了,目前簡單寫了一篇英文 blog 記錄最近的變化。還有一大堆要做的documentation work,但至少已經可以check out出來用了。

另外就是真的得好好重整我的兩個 blog 所使用的 theme 了,not really suitable for showing code snippets…

詳情請參見本 blog 的英文版

結老(kiat-lāu)

一個神奇的詞。結老跟擺爛並不是同一回事,其中的奧妙(那種破百──有人說是破冬後──事情仍多事情又lâ-sái的狀態),只有親身經歷才能明白。欲辯已忘言。

ObjectiveFlickr 進度更新

這幾天繼續在改寫 ObjectiveFlickr 。幾個重要的變化:

  1. Source trunk大地震。許多檔案搬了家。新的 Xcode project file 可以一次 build 完 framework (yes! ObjectiveFlickr.framework is there!) 和 demo apps。編出來的 ObjectiveFlickr.framework 可以獨立放在 /Library/Frameworks 也可以嵌入你所寫的 app 中使用。
  2. Source code大地震。三個 class 全部重寫了一遍,主要是把 application context (API key, shared secret 及 auth token) 分成一類(連同 URL 生成),遞送 HTTP request 的工作再歸成一類(這次加入了 HTTP POST 支援了),另外 uploader 也寫得再清楚一點。
  3. 抽取 XML payload 資訊的功能,從這一版中被拿掉了。主要希望讓 request wrapper 能專心做 payload delivery,因此甚至連 Flickr error block 的解讀工作都不做了。研究了一下 BadgerFish 以及其他 XML-JSON 互轉的慣例,可能也要依樣畫葫蘆。
  4. 考慮了一圈,在目前這個層次上(「低階」的 API),一切都還是以 async 的方式撰寫。可能要到再往上一層的 API ,才會有 blocking call ,也就是做完一個 HTTP request 才做下一件事。大家都知道原因:在 GUI 程式裡寫 sync/blocking call 反而是比較困難的。
  5. 捏指一算,目前 Flickr API 竟然有 95 個 method !
  6. API method 多,傳回來的 XML payload 也是種類繁多。

總之,目前還需要再往上架一層,才可能看到更多簡單的 demo app 出現。目前是希望把 Flickr authentication 也做成一個 sheet package ,只要把 sheet window (註)調出來用就可以處理掉 Flickr 複雜的 authentication work 。不過這個部份的 abstraction and wrapping 遠比寫框架困難就是了。UI 真不是件容易的工作。

註:OS X 的 sheet window ,最近研究才知,並不是嚴格意義上的 modal window。因為 sheet 在 on focus 時,並不真的 block 住 parent window 的 run loop (event loop) …… OS X 的 run loop 架構,其實也挺亂七八糟的 -_-。

另一個相關的問題是

我們願意花多少錢來取得這種虛擬的實體感(註一),以及有多少人會願意誠實地付錢?

有時候會很希望看到有人利用Freakonomics的方法來考察iTunes Music Store或者就是paid legal music download in general。以至於推廣到e.g. Shareware buying, online software purchase等行為。

問題是一樣的:在有不投錢而取得東西,因此而被逮機會又微乎其微的情況下(如同Freakonomics裡那個靠榮譽制販賣bag的人),到底有多少人願意付錢取得東西?

不過,Freakonomics的案例,簡化掉了其中一個因素:交易摩擦。或者說是交易過程所需經過的「層層險阻」。販賣bagel的過程,只有投錢入箱和拿走bagel而已。但是買音樂就不是那麼簡單,要開帳號(還得在能開帳號的國家開)、要有信用卡、要能值得信任地付錢……

最近遇到的悽慘例子是,在台北的計程車上聽到1976的《耳機裡的新浪潮》。結果找了幾家台北主流的唱片行,都說「我們不進他們的CD」。orz之一。然後上網查,發現要上網訂購。要上網訂購還要很多天後取貨,這也就算了,還要些註冊會員、回覆確認、blah blah blah……

在交易摩擦這麼大的情況下,我相信很多人會寧願選擇:1. 打開 P2P 軟體開始找,2. 花一點時間等待下載下來不知伊於胡底的音樂檔。或者願意忍受的話,3. 也可以去某些國家不知伊於胡底的音樂網站「試聽」……

In the end, 我既沒有買CD(因為我那時已離開台北),也沒有選擇 1. 2. 3. (因為我懶)。

我真正希望的是,點選 PayPal ,購買單單這一首歌,收到下載通知信下載(或者就直接下載),匯入 iTunes,結案。

所以問題在於,有行無市(註二)。

註一:其實在英文裡,virtual的確實意義是「實際上被當為真實的」(effective),所以virtual reality其實也是一種reality,是「被視為的」真實。不過再查字典,驚覺New Oxfoard American Dictionary竟然用這麼淺顯的話來解釋先前被英英字典解釋得很玄的virtual: “adjective; almost or nearly as described, but not completely or according to strict definition”…

註二:一直在想,有沒有可能用小額付款機制付錢給喜歡的artist,然後他們可以直接把打上了浮水印的作品(例如 mp3 檔?浮水印可以突顯這是personalized item/transaction)直接 mail 到信箱裡啊……

當CD封面可以在電腦裡翻的時候

我知道,我從此不會想再買任何一張實體CD了。

前不久,Apple發表新的iTunes 7。Steve Jobs說「這會改變你聽音樂的方式」。誠哉斯言。事實上iTunes 7的CD封面檢閱模式,可能是在為了OS X 10.5的CoreAnimation做準備(OmniGroup的OmniDazzle搶先學去)──當然,根據討論,很可能這只是個非常簡單的OpenGL view就能做出的效果,其中絕無任何高深之處。

但是,這麼簡單的一個UI上的變化,到底為何能發生這麼大的效用?在此之前,MP3 對我一直是很虛無的存在。不愛去大量下載、去「嘿嘿嘿」音樂,因為那樣弄下來的音樂,都很不真實、很不連貫。

用album art可能是有幫助的。事實上有些「嘿嘿嘿」網站,幫人把整套CD封面封底小冊,通通掃描起來,供人自行印製或存檔留念。但是那樣好像還是沒辦法解決MP3的不真實感。

iTunes 7的那個介面,卻補足了一個實體CD盒存在的理由:它們是拿來翻的。並且,這樣一個實體的存在,把CD中的音樂牽在一起,做為一種記憶的單元,畢竟我們還是熟悉「唱片」這種原型吧,即便是單曲也還是用一張兩張在量數的啊。

每每我拿到CD,首先要先剝去外頭紙盒,再來剝去側標。以往還會翻閱小冊內文,如今往往也省去此儀式。CD的存在就是為了在一堆CD中被人翻找。觸覺和視覺的聯覺如此重要。

而如今透過電腦繪圖,一張張的CD也可以被翻找。用視覺補償了觸感的不足──事實上,如果不久有人把Smackbook hack成可以拿來「翻」iTunes的CD櫃,那就更像可以摸的東西了。

CD如此,同樣的事情會不會發生在書本上?雖然閱讀的觸感與視覺聯覺更為重要,但如今的現實是有越來越多東西得在線上閱讀,紙本變成一種奢侈。而且不可否認,電子書架真的也越做越棒了。也許將來只會剩下長時間移動時,還會想讀紙本的東西。還有文學作品(雖然像詩這樣的文類,其實是非常、非常、非常適合拿來當RSS feed來讀的)。

所以,請不要用李伯伯式的口吻說,現在的年輕人都不看書。他們也許螢幕上已經看得太多(更何況,要知道什麼是《悲慘世界》,google不就好了嗎?),想要在坐捷運的時候,享受城市的風景與空氣,去感受那些不會也不想被OpenGL取代的實體世界。

至少我是這麼覺得的。

(update: 結果發現一年前寫過這篇,orz)

來函轉載:OV Podcast, semantic web, 按tab賺錢

單中杰指出上一次OV/ilyastorming podcast中一個討論的盲點:

現場錄音中好像沒有提到 Semantic Web, 讓我有點驚訝。

討論 Semantic Web 常提到的一個問題是,如何讓大眾能夠且願意把自己的創作標上機器可讀的標籤,讓搜尋引擎把資訊整合起來,以便我找「位於捷運站一公里以內、有寫過輸入法的人推薦的、並且有賣兩百元以下素食主餐的聚會場所」等。有沒有辦法把輸入法改裝成為標籤的通路呢?

也就是說,以「加快打字速度」為號召,引誘使用者多跟電腦說明一下自己在做什麼事。最簡單的例子,就是把注音輸入法的詞彙與通訊錄的姓名整合起來,輸入人名加詞的時候順便輸入地址電話,以後打「某人的地址是」之後按 Tab 就跳出地址來,或是打「某人家從捷運」之後按 Tab 就跳出「某站二號出口右轉……即到」。有人 IM 給我「請趕快來這裡」,我回電「好,騎車預計」按 Tab 跳出「12 分鐘抵達」。有人 email 問我白菜怎麼賣,我回答「一把」按 Tab……。最終的目的當然是一個人坐在電腦前面只要一直按 Tab 就有錢賺。

另有相關:Remembrance Agent(中譯建議:「記念杯」)

My footnote: 其實我們那天後來有聊到「一直按 tab 就可以寫完整篇論文」(這是貫串 OV agent 的主題之一,經常被提到)──如同我們聊到聊天機器人可以幫你解決食衣住行育樂的各種問題那般。我是比較喜歡這組杯子啦……

Thanks, Ken.

« Previous PageNext Page »