SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

プログラミング言語「Nu」入門

NuでMac GUIプログラミング
Twitterクライアントを作ってみよう


  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード NuTwitterClient.zip (40.0 KB)

Twitterアクセス クラス

 Twitterからタイムラインを取得するコードは前回説明したものをTwitterクラスとしてまとめました。また、Twitterにつぶやきをポストするメソッドも追加しました。

  • basic-auth-tokenには前回の記事を参照し、自分のログイン、パスワードを設定してください。
  • タイムラインを取得する time-lineメソッドではGUIの都合もあり、リストから配列に変換しています。このようにNuにはリストから配列、配列からリストに変換するメソッドが用意されています。
  • つぶやきメソッド post-tweet: はAPIを呼び出しているだけです。APIの詳細はCocoa APIリファレンスを参照してください。
(set basic-auth-token      "XXXXXXXXXXXXXXXXX")
(set twitter-time-line-url "http://twitter.com/statuses/friends_timeline.xml?count=100")
(set twitter-update-url    "http://twitter.com/statuses/update.xml")

(function string-list-from-xml (xml path)
    (map (do (e) (e stringValue)) ((xml nodesForXPath:path error:nil) list)))

(function twitter-timeline-xml ()
    (let  (http-req (NSMutableURLRequest
                                 requestWithURL:(NSURL URLWithString:twitter-time-line-url)))
          (http-req setHTTPMethod:"GET")
          (http-req setValue:"Basic #{basic-auth-token}" forHTTPHeaderField:"Authorization")
          ((NSXMLDocument alloc) initWithData:(NSURLConnection
                                                         sendSynchronousRequest:http-req
                                                         returningResponse:nil error:nil)
                                                         options:0 error:nil)))
(function twitter-timeline ()
    (let  (xml (twitter-timeline-xml))
          (zip3 (string-list-from-xml xml "/statuses/status/user/screen_name")
                (string-list-from-xml xml "/statuses/status/text")
                (string-list-from-xml xml "/statuses/status/user/profile_image_url"))))

(class Twitter is NSObject
    (+ time-lines is  
        ((twitter-timeline) array))
        
    (+ post-tweet: message is
        (let  (http-req (NSMutableURLRequest
                                     requestWithURL:(NSURL URLWithString:twitter-update-url)))
              (http-req setHTTPMethod:"POST")
              (http-req setValue:"Basic #{basic-auth-token}" forHTTPHeaderField:"Authorization")
              (http-req setHTTPBody:("status=#{(message stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding)}"
                                     dataUsingEncoding:NSASCIIStringEncoding))
              (NSURLConnection sendSynchronousRequest:http-req returningResponse:nil error:nil)))    
)

 今回は汎用的なLisp関数を別ファイルにしました。これも前回説明したものです。

(function caar (e) (car (car e)))
(function cadr (e) (car (cdr e)))
(function cdar (e) (cdr (car e)))
(function cddr (e) (cdr (cdr e)))
(function cadar (e) (car (cdr (car e))))


(function null (x) (== x ()))
(function zip3 (l1 l2 l3)
    (cond ((null l1) ())
        (else (cons (list (car l1) (car l2) (car l3))
                    (zip3 (cdr l1) (cdr l2) (cdr l3))))))

(function map (f l)
    (cond ((null l) nil)
          (else (cons (f (car l)) (map f (cdr l)) ))))

(function tl-name (e) (car e))
(function tl-text (e) (car (cdr e)))
(function tl-icon (e) (car (cdr (cdr e))))

GUIハンドリング

 GUIとのやり取りを行う main.nu コードです。最初の (load "...") でNuやCocoaのクラス、そして上で説明したクラスを読み込んでいます。最後の3行がGUIとやり取りするApplicationDelegateクラスを生成し、実行する定型処理です。

 ApplicationDelegateクラスではインスタンス変数を3つ定義していますが、最初の tableView と textField は画面のタイムライン表示用 NSTableView、つぶやき入力用の NSTextField らと、InterfaceBuilderで対応付けされています。timeLines はタイムラインの保持用変数です。

 以下のメソッドは各イベント等で呼び出されるメソッドで、pushRefreshButton:・pushPostButton: はそれぞれRefresh・Postボタンが押された時に呼び出されるようにInterfaceBuilderで対応付けされています。

 各メソッドを解説すると、

  • awakeFromNib はGUI定義が読み込まれた後で呼び出されます、ここではテーブルに画像を表示するために列の要素を NSImageCell に入れ替えています。
  • applicationDidFinishLaunching: は画面が表示された後に呼び出されます、こではタイムラインを取得し timeLinesインスタンス変数に代入し、テーブルを再表示しています。
  • pushRefreshButton: はrefreshボタンが押された時に呼び出されます、上と同様にタイムラインを取得・表示しています。
  • pushPostButton: はpostボタンが押された時に呼び出されます、つぶやきを textField から取得し post-tweet: を呼び出しています。
  • numberOfRowsInTableView: はテーブル表示時に呼び出されます。このメソッドはテーブルに表示するデータの件数を戻します。
  • tableView: objectValueForTableColumn: row: もテーブル表示時に呼び出されます、このメソッドはテーブルに表示するデータを戻します。引数には列情報 aTableColumn と行インデックス rowIndex が渡ってくるので対応する表要素のデータを戻します。アイコンの表示はタイムラインに含まれる画像URLを使って、initWithContentsOfURL:メソッドを使い画像データを取得しています。
  • applicationShouldTerminateAfterLastWindowClosed: は画面のクローズボタンを押した際にアプリが終了するようにするおまじないです。
(load "Nu:nu")
(load "Nu:cocoa")
(load "Nu:menu")
(load "functions")
(load "twitter")

(class ApplicationDelegate is NSObject
    (ivar (id) tableView
          (id) textField
          (id) timeLines)
          
    (- (void) awakeFromNib is
        (let (theColumn (@tableView tableColumnWithIdentifier:"icon"))
             (theColumn setDataCell:((NSImageCell alloc) initImageCell:nil))))

    (- (void) applicationDidFinishLaunching:(id) sender is
        (set @timeLines (Twitter time-lines))
        (@tableView reloadData)
         )

    (- (void) pushRefreshButton:(id) sender is 
        (set @timeLines (Twitter time-lines))
        (@tableView reloadData)
        )
    
    (- (void) pushPostButton:(id) sender is
        (Twitter post-tweet:(@textField stringValue)))
    
    (- (int) numberOfRowsInTableView:(id) aTableView is
        (@timeLines count))

    (- (id) tableView:(id) aTableView objectValueForTableColumn:(id) aTableColumn row:(int) rowIndex is
        (case (aTableColumn identifier)
            ("icon"  
                ((NSImage alloc) initWithContentsOfURL:
                (NSURL URLWithString:(tl-icon (@timeLines objectAtIndex:rowIndex)))))
            ("name"  (tl-name (@timeLines objectAtIndex:rowIndex)))
            ("text"  (tl-text (@timeLines objectAtIndex:rowIndex)))
            (else "")))

    (- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(id) theApplication is YES)
 )

((NSApplication sharedApplication) setDelegate:(set delegate ((ApplicationDelegate alloc) init)))
((NSApplication sharedApplication) activateIgnoringOtherApps:YES)
(NSApplicationMain 0 nil)

まとめ

 今回はNuでMacのGUIアプリを作ってみました。速度がそれほど必要でないGUIアプリを作る際にはLispの俊敏なプログラミングが活かせるのではないかと思います。

 また、Objective-Cの中にあるC言語と [...] のオブジェクト指向部分のギャップに比べ、同じ () を使っているNuはオブジェクト指向部分とうまく調和していてコードが読みやすい気がします、このへんもS式の良さでしょうか。

 今回のコードはここからダウンロードできますので、ぜひ皆さんもNuに挑戦してみてください。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
プログラミング言語「Nu」入門連載記事一覧

もっと読む

この記事の著者

吉田裕美(ヨシダユウミ)

有限会社 EY-Office 取締役CADのベンチャー企業でCADのコア部分や図面管理システムなどの開発に従事した後、独立しJava,Ruby,PerlでWebアプリを中心に開発してきた。現在は殆どの開発はRuby on Rails。ここ数年はソフトウェアエンジニアの教育に興味をもち、従来の知識偏重な教育ではなく現実の問題を解決できるエンジニアを育てる教育に注力している。またLisp等に関心...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4976 2010/04/19 19:50

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング