2010年9月30日木曜日

Objective-C + libxml2 を使ってフィードを取り込みたいんだ (1)

理解するのにかなり苦しみました。
しかもその理解が正しいのかどうか今ひとつ確信がもてず。
でもまぁ気にせずに書いていこう。


前準備
  1. プロジェクト作成
  2. Frameworksにlibxml2.dylibを追加する。
  3. 「プロジェクト設定を編集」でビルドタブの設定の「ヘッダ検索パス」に/usr/include/libxml2を指定する。
  4. 「アクティブターゲット"hoge"を情報」でビルドタブの設定の「ヘッダ検索パス」に${SDKROOT},を指定(}の後ろのカンマも入れること)
  5. 新規ファイル作成でクラスファイル作成(NSObjectのサブクラス、ファイル名をRSSImporter)する。


では始める。
  • 4.で作ったRSSImporterの.h/.mファイルを使った説明がほとんどになる。
  • まずは、libxml2を使うときに定形文みたいに扱われるだろう関数とメソッドを書き上げてみる。
  • 見てみるとわかると思うけど、.mファイルがちょっと変わってる。
  • .mファイルには、C関数の定義と関数自体と構造体、それとクラスエクステンションが余分に書かれてる。
  • これから説明をしていこうと思うけど、あっち行ったりこっち行ったりしながらの話になるから、今どこのこと説明してるのか自分で分からなくなると思うけど、なるべく分かるようにやっていきたいな。



//
// RSSImporter.h
//

#import <Foundation/Foundation.h>
#import <libxml/tree.h>

@interface RSSImporter : NSObject {
}

@end



//
// RSSImporter.m
//

#import "RSSImporter.h"
#import <libxml/tree.h>

//
// libxml2 (XMLのパーサライブラリ) を使うための準備
// libxml2もlibxml2のAPIもC言語で書かれているのでここはC言語で記述することになる
//

static void startElementSAX(
void *context,
const xmlChar *localname,
const xmlChar *prefix,
const xmlChar *URI,
int nb_namespaces,
const xmlChar **namespaces,
int nb_attributes, int nb_defaulted,
const xmlChar **atrributes);
static void endElementSAX(
void *context,
const xmlChar *localname,
const xmlChar *prefix,
const xmlChar *URI);
static void charactersFoundSAX(
void *context,
const xmlChar *characters,
int lenght);
static xmlSAXHandler simpleSAXHandlerStruct;

static void startElementSAX(
void *context,
const xmlChar *localname,
const xmlChar *prefix,
const xmlChar *URI,
int nb_namespaces,
const xmlChar **namespaces,
int nb_attributes, int nb_defaulted,
const xmlChar **atrributes) {
// 要素開始の通知を受けたときの処理
}

static void endElementSAX(
void *context,
const xmlChar *localname,
const xmlChar *prefix,
const xmlChar *URI) {
// 要素終了の通知を受けたときの処理
}

static void charactersFoundSAX(
void *context,
const xmlChar *characters,
int lenght) {
// 要素間のテキストの通知を受けたときの処理
}

// SAXハンドラが定義されたxmlSAXHandler構造体に対して、使いたいハンドラを登録する
// (XMLパース中にXMLの要素や属性を発見したときに通知してほしいハンドラを登録する)
//
// 要素間のテキスト
// エラー
// 要素の開始
// 要素の終了
static xmlSAXHandler simpleSAXHandlerStruct = {
NULL, /* internalSubset */
NULL, /* isStandalone */
NULL, /* hasInternalSubset */
NULL, /* hasExternalSubset */
NULL, /* resolveEntity */
NULL, /* getEntity */
NULL, /* entityDecl */
NULL, /* notationDecl */
NULL, /* attributeDecl */
NULL, /* elementDecl */
NULL, /* unparsedEntityDecl */
NULL, /* setDocumentLocator */
NULL, /* startDocument */
NULL, /* endDocument */
NULL, /* startElement*/
NULL, /* endElement */
NULL, /* reference */
charactersFoundSAX, /* characters */
NULL, /* ignorableWhitespace */
NULL, /* processingInstruction */
NULL, /* comment */
NULL, /* warning */
NULL, /* error */
NULL, /* fatalError //: unused error() get all the errors */
NULL, /* getParameterEntity */
NULL, /* cdataBlock */
NULL, /* externalSubset */
XML_SAX2_MAGIC, //
NULL,
startElementSAX, /* startElementNs */
endElementSAX, /* endElementNs */
NULL, /* serror */
};

//
// クラスエクステンションを利用することで、
// プロパティとメソッドへのアクセスをプライベートからに制限できる
//

@interface RSSImporter ()
@end


//
// ここから普通に@implementationです
//

@implementation RSSImporter

- (void)dealloc {
[super dealloc];
}

#pragma mark NSURLConnection Delegate methods

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// データ受信
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// 受信完了
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// 受信エラー
}

@end


続く。

0 件のコメント:

コメントを投稿