★ 外部の関数を取り入れる場合のいろいろ
json-framework
SimpleHttpClient
-----------------------------------------------------------------------------------
buildの設定のところで
    Link Binary With Libraries
        libxml2.dylib 追加する
    Other Linker Flags
        -xml2 を追加する
    Header Search Paths
        /usr/include/libxml2 を追加する
-----------------------------------------------------------------------------------
・SimpleHttpClient
    https://github.com/cooldaemon/SimpleHttpClient
   
    http://d.hatena.ne.jp/cooldaemon/20100122/1264137498#
    ↑大変ありがとうございます。
    ・DDXML+HTML
        https://gist.github.com/185012
——————————————————————————————————
・json-framework
    http://code.google.com/p/json-framework/
    単に"Classes"というfolderごとコピーする方法が簡単
    使いたいところで
    ・ #import "JSON.h"
-----------------------------------------------------------------------------------
・SimpleHttpClientの説明
    https://github.com/cooldaemon/SimpleHttpClient
    JSON と XML のフィルタを追加
    HTML フィルタも追加
    (HTML に対して XPath が使えます)
    NSOperationQueue を外部から与えられるようにしました。
    スレッドを管理するキューは、
    一つの iPhone アプリに対して、一つで十分
-----------------------------------------------------------------------------------
・テストコードの解説
    ・初期化
    SimpleHttpClient *client = [[SimpleHttpClient alloc] initWithDelegate:self];
    まずは、SimpleHttpClient のオブジェクトを作ります。
    引数として delegate を渡していますが、
    リクエスト毎に delegate を変更する事も出来ます。
-----------------------------------------------------------------------------------
    ・GET リクエスト
    例えば、下記のような GET リクエストを発行したいとします。
    http://foo.bar/search?q=iphone&q=osx&lr=lang_en
    その場合は、下記のような辞書オブジェクトを作成し・・・
    NSMutableDictionary *params = [NSMutableDictionary
        dictionaryWithObject:[NSArray arrayWithObjects:@"iphone", @"osx", nil]
                      forKey:@"q"
    ];
   
    [params setObject:@"lang_en" forKey:@"lr"];
    辞書オブジェクトを JSON 風に表現すると下記のような感じです。
    {
        q  : ['iphone', 'osx'],
        lr : 'lang_en'
    }
    Value は、NSArray と NSString 以外は無視されます。
    これを、先ほど作成した SimpleHttpClient のオブジェクトに登録します。
    [client
               get        :@"http://foo.bar/search"
        parameters    :params
           context    :@"iphone"
    ];
    context は、後ほど説明します。
    この時点で、別スレッド上で GET リクエストが実行されます。
    実際には、負荷が高ければキューに積まれ、
    負荷が下がるのを待ってから実行されるのですが、
    この辺りは、NSOperation と NSOperationQueue 任せです。
-----------------------------------------------------------------------------------
    ・POST リクエスト
    上記の 'get' を 'post' に変更します。
    [client
                post    :@"http://foo.bar/search"
        parameters    :params
               context    :@"iphone"
    ];
-----------------------------------------------------------------------------------
    ・データの受信
    NSURLConnection でよく使われるメソッドだけラップしてあります。
    気をつけるべき点は、別スレッドで同時に動いているので、
    一つの delegate にメッセージが集中する事です。
    (リクエスト時、個別に delegate を指定した場合は別です。)
    その為、リクエスト時に指定した context を利用して処理を分岐させます。
    例えば、didReceiveResponse を受け取る場合は、下記のようにします。
    - (void)simpleHttpClientOperation:(SimpleHttpClientOperation *)operation
        didReceiveResponse:(NSHTTPURLResponse *)response
    {
            [_response setObject:response forKey:operation.context];
    } 
    operation.context には、
    リクエストを登録する際に引数として渡した context が入っています。
    これを利用して、処理を分岐させて下さい。
-----------------------------------------------------------------------------------
    その他
    GET、POST 共に priority を指定できます。
    緊急度の高いリクエストを優先的に行ったり、
    暇な時に行えば良いリクエストを後回しにしたりできます。
    詳細は、NSOperation のマニュアルをご参照ください。
-----------------------------------------------------------------------------------
    iPhone アプリのサンプルプロジェクト
    http://github.com/cooldaemon/TestSimpleHttpClient
-----------------------------------------------------------------------------------
    ・SimpleHttpClient に JSON と XML のフィルタ
    WSSE に対応した際と同じくドメイン毎にフィルタを設定できるので、
    reader.livedoor.com から取得したデータは JSON フィルタを通す、
    b.hatena.ne.jp から取得したデータは XML フィルタを通す
    ・・・という使い方が可能です。
    具体的には、下記のように設定を行ないます。
    SimpleHttpClient *client = [[[SimpleHttpClient alloc] initWithDelegate:self] autorelease];
    [client
        setFilter    :SimpleHttpClientFilterJSON
        forHost    :@"reader.livedoor.com"
    ];
    [client
        setFilter    :SimpleHttpClientFilterXML
        forHost    :@"b.hatena.ne.jp"
    ];
    もし、http://reader.livedoor.com/api/subs に対してリクエストを送ったのであれば、
    フィルタ済みのデータを受け取るには下記のようにします。
    - (void)simpleHttpClientOperationDidFinishLoading
                        :    (SimpleHttpClientOperation *)operation
        filteredData    :    (id)data
    {
        _subs = (NSArray *)[data retain];
    }
    http://reader.livedoor.com/api/subs は、Array 型の JSON を返すので NSArray * にキャストします。
    data は autorelease 済みであり、
    simpleHttpClientOperationDidFinishLoading:filteredData: 
    メッセージは、サブスレッドの中で呼ばれるので、retain しておかないと、
    サブスレッド終了時に NSAutoreleasePool に release されてしまいます。
-----------------------------------------------------------------------------------
    ・SimpleHttpClient に KissXML+HTML を組み込んだHTML フィルタ
    下記のように、SimpleHttpClient のオブジェクトを作成し・・・
    SimpleHttpClient *client = [[SimpleHttpClient alloc] initWithDelegate:self];
    HTML 用のフィルタを設定し・・・
    [client
        setFilter:SimpleHttpClientFilterHTML
          forHost:@"d.hatena.ne.jp"
    ];
    リクエストを送ると・・・
    [client
          get            :@"http://d.hatena.ne.jp/cooldaemon/20090911/1252637257"
        parameters    :nil
          context    :nil
    ];
   
    DDXMLDocument のオブジェクトが受け取れます。
    - (void)simpleHttpClientOperationDidFinishLoading:(SimpleHttpClientOperation *)operation
                                     filteredData:(id)data
    {
        [_html release];
        _html = (DDXMLDocument *)[data retain];
    }
    XPath を使うには、下記のようにします。
    NSError *error = nil;
    NSArray *body = [_html
        nodesForXPath:@"id(\"days\")//div[@class=\"body\"]//h3/following-sibling::*|id(\"days\")//div[@class=\"body\" and not(.//h3)]"
            error:&error
    ];
    NSLog("%@", [body componentsJoinedByString:@""]);
        詳しくは、test/TestHatenaDiaryHTML.mを参照
 
0 件のコメント:
コメントを投稿