僕が作ったサービス

clanworkz

2011年8月7日日曜日

XMLパーサーの実装編〜iPhoneバーコードリーダーアプリ制作第5回〜

本日ノボットの買収をニュースで見てテンション上がりまくりです。
やはりきちんと実力のあるベンチャーが評価されるべきですよね。最近流行に便乗しただけのようなベンチャーが大量に資金を集めてたりするのはなんか違うな〜って思います。まあ日本のベンチャーを育てようってのはいい傾向なんですけどね。

んでバーコードバトラーアプリの制作過程の第5回目です。
最近Androidアプリの開発ばっかやってるんで、ちょっとObjective-C忘れ気味ですがいきましょう!

本日は楽天から取得したXMLをパースして、商品画像と商品タイトルを取得するとこまでやります。

1 XMLパーサー(SAX)
まずはXMLパーサーについて少し解説します。パーサーってのはXML文章をプログラムで扱うための方法で、XMLから要素を取得したり、値を挿入したりすることができます。
パーサーには大きく分けて二つの種類があります。
DOMとSAXです。

■DOM
DOMってのは簡単に説明すると、XMLの要素を全部読み込んで、要素のツリーを構築します。このツリー内を自由に行き来できて、要素を削除したり追加したりできるというメリットがあります。しかし一方で、XMLを全部一気に読み込むのでメモリの消費が大きいらしいです。

■SAX
SAXはXML文章を先頭から最後まで順番に読み込んでいき、タグを見つけるたびにメソッドが呼ばれる方式です。

例えば以下のようなXMLがあった場合

<itemName>PHP逆引きレシピ</itemName>
<catchcopy>【送料無料】</catchcopy>
<itemCode>book:13217617</itemCode>
<itemPrice>2730</itemPrice>


こんな感じになります

〜SAXのイメージ〜

パーススタート

<itemName> → 開始タグ発見メソッドが呼ばれる

PHP逆引きレシピ → 要素発見メソッドが呼ばれる

</itemName> → 終了タグ発見メソッドが呼ばれる

<catchcopy> → 開始タグ発見メソッドが呼ばれる

【送料無料】 → 要素発見メソッドが呼ばれる

</catchcopy> → 終了タグ発見メソッドが呼ばれる

<itemCode> → 開始タグ発見メソッドが呼ばれる

book:13217617 → 要素発見メソッドが呼ばれる

</itemCode> → 終了タグ発見メソッドが呼ばれる

<itemPrice> → 開始タグ発見メソッドが呼ばれる

2730 → 要素発見メソッドが呼ばれる

</itemPrice> → 終了タグ発見メソッドが呼ばれる

パース終了

とこんな感じで、XMLを先頭から最後まで一つひとつ見ていき、「タグ発見メソッド」「要素発見メソッド」「終了タグ発見メソッド」がアホほど呼ばれるのがSAXパーサーです。

これはメモリの消費も少なく、高速らしいので、限られたリソース内で稼働させるアプリに関しては、SAXパーサーを使うのが良さそうです。



2 SAXのフォーマット
それでは実装をする前にフォーマットを見てみましょう。

まずはこんな感じでリクエストを作成します。NSString型の「requestUrl」がURLになります。以下のコードでリクエストを送信します。(今回はバーコード読み取り直後)

//リクエストの送信方法
//----------------------------------------------------------------------------
NSString *requestUrl = @"http〜〜〜〜〜〜〜〜〜";
NSURL *url = [NSURL URLWithString:requestUrl];  
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[req addValue:0 forHTTPHeaderField:@"Content-Length"];
[req setHTTPMethod:@"GET"];
conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];

if (conn)
{
webData = [[NSMutableData data] retain];
}
//----------------------------------------------------------------------------


そしたら以下の三つのメソッドを実装しましょう。それぞれ
「レスポンスを受信したとき」
「データを受け取ったとき」
「データの転送中にエラーがあったとき」
に呼ばれます。


//レスポンスを受信したとき呼ばれるメソッド
//----------------------------------------------------------------------------
-(void) connection:(NSURLConnection *) connection
didReceiveResponse:(NSURLResponse *) response
{
[webData setLength: 0];  
}


//データを受け取ったとき呼ばれるメソッド
//----------------------------------------------------------------------------
-(void) connection:(NSURLConnection *) connection
didReceiveData:(NSData *) data
{
[webData appendData:data];
}


//データの転送中にエラーがあったとき
//----------------------------------------------------------------------------

-(void) connection:(NSURLConnection *) connection
  didFailWithError:(NSError *) error
{
[webData release];
        [connection release];
}


そしてデータの受信がすべて完了したときに呼ばれるメソッドが以下の「connectionDidFinishLoading]です。
ここでXMLパーサーの実装をします。

//データ受信終了後に呼ばれる(パースをここで開始する
//----------------------------------------------------------------------------
-(void) connectionDidFinishLoading:(NSURLConnection *) connection
{
    [[NSURLCache sharedURLCache] setMemoryCapacity:0];
    [[NSURLCache sharedURLCache] setDiskCapacity:0];
    xmlParser = [[NSXMLParser alloc] initWithData: webData];
    [xmlParser setDelegate: self];
    [xmlParser setShouldResolveExternalEntities:YES];
    [xmlParser parse];   
    [xmlParser release];
    ////////////////////////////
    //ここにパース終了後の記述(D)
    ////////////////////////////
}

//パーサーがスタートタグを見つけたら呼び出される(A)
//----------------------------------------------------------------------------
-(void) parser:(NSXMLParser *) parser
didStartElement:(NSString *) elementName
  namespaceURI:(NSString *) namespaceURI
 qualifiedName:(NSString *) qName
attributes:(NSDictionary *) attributeDict
{
   
}

//パーサーが要素のテキストを検出すると呼び出される(B)
//----------------------------------------------------------------------------
-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string
{
   
}

//パーサーがエンドタグを見つけたら呼び出される(C)
//----------------------------------------------------------------------------
-(void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
 namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
}



上記のABC三つのメソッドはタグ、要素を見つけるたびに何度も呼ばれるメソッドです。
このABC内に取得したい情報を入手する内容を記述して、最後に(D)の部分でパース終了後の内容を記述します。全体的な流れはこんな感じです。

2 楽天APIからのXMLをパース
いざ実装開始です。前回まで使用してきたコードに書き加えます。
まずは、
今回使用するXMLパーサー xmlParser
パースの最中にフラグの役割を果たす elementkey
そのデリゲート NSXMLParserDelegate
取得した情報を一時的に保管する soapResultArray
最終的に取得した商品タイトルと商品画像URLを格納する itemName、imageUrl
を宣言します。こんな感じ。

//MonsterShowViewController.h

//----------------------------------------------------------------------------


@interface MonsterShowViewController : UIViewController <NSXMLParserDelegate>
{
 
    IBOutlet UIImageView *imageView;
    IBOutlet UILabel *itemNameLabel;
    NSString *jancode;
 
    NSMutableData *webData;
    NSURLConnection *conn;
 
    NSXMLParser *xmlParser;
    int elementkey;
    NSMutableArray *soapResultArray;
    NSString *itemName;
    NSString *imageUrl;
 
}
@property(nonatomic,retain)UIImageView *imageView;
@property(nonatomic,retain)NSString *jancode;
@property(nonatomic,retain)UILabel *itemNameLabel;

-(void) parseTag:(NSString*)requestUrl;
@end
//----------------------------------------------------------------------------

これで宣言はオーケー
次に実装です。先ほど示したフォーマットに、楽天のXMLから商品名と画像URLを取得するコードを書いていきます。

まずは楽天へのリクエストURLをブラウザで直接見てみましょう。

itemNameタグの中に商品タイトルが、
mediumImageUrlタグの中に、サムネイル画像へのリンクURLが
それぞれ入っていることがわかります。

ここで注意点があります。要素を発見した際に呼ばれる「foundCharacters」メソッドですが、発見した要素によっては、数回にわかれて呼ばれることがあります。

どういうことかと言いますと。例えば書籍タイトルが「PHP逆引きレシピ」だった場合には、「PHP」と「逆引きレシピ」にわかれて「foundCharacters」が呼ばれます。これを知らないと、なぜか取得したタイトルが「逆引きレシピ」だけになってしまうという自体に陥ります。僕はずっとこの謎が解けずに悩んでいた時期がありました。

取得したタイトルを配列に保存することで、この問題は解決します。

よって実装は以下のようにします。
始めに楽天にリクエストを投げる部分の処理は前回を見て下さい。

//MonsterShowViewController.h

//----------------------------------------------------------------------------
-(void) connectionDidFinishLoading:(NSURLConnection *) connection 
{
    
    [[NSURLCache sharedURLCache] setMemoryCapacity:0];
    [[NSURLCache sharedURLCache] setDiskCapacity:0];
    //パーサー生成
    xmlParser = [[NSXMLParser alloc] initWithData: webData];
    [xmlParser setDelegate: self];
    [xmlParser setShouldResolveExternalEntities:YES];
    soapResultArray = [[NSMutableArray alloc]init];
    imageUrl = [[NSString alloc]init];
    itemName = [[NSString alloc]init];
    //パース開始
    [xmlParser parse];    
    [xmlParser release];
    
    
    //ここにパース終了後の記述(D)
    //ラベルと画像を描画
    itemNameLabel.text = itemName;
    imageView.image = [self getImage:imageUrl];
    
    
}

//パーサーがスタートタグを見つけたら呼び出される(A)
//----------------------------------------------------------------------------
-(void) parser:(NSXMLParser *) parser 
didStartElement:(NSString *) elementName 
  namespaceURI:(NSString *) namespaceURI 
 qualifiedName:(NSString *) qName
attributes:(NSDictionary *) attributeDict 
{
    //パーサーが開始タグ「itemName」「mediumImageUrl」を見つけたらフラグ「mediumImageUrl」を1に
    if([elementName isEqualToString:@"itemName"] | [elementName isEqualToString:@"mediumImageUrl"])
    {
        elementkey = 1;
        
        [soapResultArray removeAllObjects];
        
        printf("発見\n");
    }
}

//パーサーが要素のテキストを検出すると呼び出される(B)
//----------------------------------------------------------------------------
-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string
{
    if (elementkey == 1) {
        //開始タグを見つけた直後に要素を発見した場合、文字列を保管
        //要素によっては、このメソッドが数回呼ばれることがあるので、
        //配列に保管する。こうしないとタイトルが切れて保存されることも…
        [soapResultArray addObject:string];
        
    }
}

//パーサーがエンドタグを見つけたら呼び出される(C)
//----------------------------------------------------------------------------
-(void)parser:(NSXMLParser *)parser 
didEndElement:(NSString *)elementName 
 namespaceURI:(NSString *)namespaceURI 
qualifiedName:(NSString *)qName
{
    //エンドタグ「itemName」を見つけ、文字列をitemNameに格納
    if ([elementName isEqualToString:@"itemName"]) {
        NSString *str = @"";
        for (int i = 0; i<[soapResultArray count]; i++) {
            //配列に入ってる要素を文字列に直す処理
            str = [NSString stringWithFormat:@"%@%@",str, [soapResultArray objectAtIndex:i]];
        }
        NSLog(@"取得した要素%@",str);
        itemName = str;
        }else if ([elementName isEqualToString:@"mediumImageUrl"]){
        //上記と同様。画像URlを取得
        NSString *str = @"";
        for (int i = 0; i<[soapResultArray count]; i++) {
            NSLog(@"%d",[soapResultArray count]);
            str = [NSString stringWithFormat:@"%@%@",str, [soapResultArray objectAtIndex:i]];
        }
        
        NSLog(@"取得した要素%@",str);
        imageUrl = str;
        
    }
    elementkey = 0;
    
}

//NADataから画像を取得するメソッド
- (UIImage *)getImage:(NSString *)url {
    return [UIImage imageWithData:[self getData:url]];
}

//画像URLからNSDataを取得するメソッド
- (NSData *)getData:(NSString *)url {
    NSURLRequest *request = [NSURLRequest requestWithURL:
                             [NSURL URLWithString:[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]
                                             cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
    NSURLResponse *response;
    NSError       *error;
    NSData *result = [NSURLConnection sendSynchronousRequest:request 
                                           returningResponse:&response error:&error];
    if (result == nil) {
        NSLog(@"NSURLConnection error %@", error);
    }
    
    return result;
}

@end

これでバーコド画像を撮影した後に、商品タイトルと画像が表示されるようになったと思います。


2011年7月17日日曜日

バーコードバトラーiPhoneアプリ制作過程〜第4回楽天APIの利用、XMLパーサーとか〜

バーコードバトラーアプリ制作過程の第四回目です。(第三回はこちら


1 楽天デベロッパーIDの取得
2 戦士情報画面の表示
3 リクエストURLの生成→XMLの取得
4 XMLパーサーの実装
5 結果(画像とテキスト)の表示



前回はバーコードリーダを実装して、バーコードからJANコードを取得するところまでやりました。今回はJANコードから商品情報を取得する部分まで実装します。

どうやってJANコードから商品情報を取得するのか?
※JANコードってバーコードの下に書いてある数字のことね

それはショッピングサイトのAPIを利用します。
楽天、ヤフー、アマゾン何でもいいのですが、ECサイトが提供している商品検索APIをもちいてJANコード検索を行います。

では楽天、ヤフー、アマゾンどれを使うのが一番いいのでしょうか?
アマゾンは書籍がメインで、しかも商品マスタを持っており、ほぼすべての商品がJANコードを持っています。普通に考えたらアマゾンでしょう。

が、しかしアマゾンAPIはアプリには利用できません。
規約により、アマゾンAPIのモバイル端末での利用は、書面での許可なしでは利用してはいけないことになっています。アマゾンに顧客を誘導するなどメリットを与えるなら別ですが、バーコードバトラーアプリでは全くもって論外ですね。

ちなみにこの規約によって話題のアプリが消え去ったケースもあります。
Amazonが、同社のデータを使うモバイルアプリを抹殺しようとしている


じゃあヤフーか楽天ですね。
「jan」で検索して見ましょう
ヤフー:1,268,298
楽天 :全 5,243,555件

楽天のが多そうですね。とりあえず楽天のAPIを利用することにしましょう。一番いいのは、楽天で検索したあとに商品が見つからなかった場合のみ、再度ヤフー検索を実施するのがいいとは思うのですが、今回は楽天のみに絞ります。

1 楽天デベロッパーIDの取得
楽天のAPIの利用方法についてはここを参照して下さい。
楽天商品検索APIとは

デベロッパーIDが必要のようです。ここはなんの問題もないと思います。
楽天に登録すればメールでデベロッパーIDを送信してくれます。

早速リクエストURLを生成してみましょう。
以下のURLの赤文字部分を自分自身のユーザーIDにして、ウェブブラウザで見てみましょう!

http://api.rakuten.co.jp/rws/3.0/rest?developerId=[あなたのdeveloperID]&operation=ItemSearch&version=2010-09-15&keyword=9784344016897

こんな感じでXMLが表示されればオーケーです。


このXMLのなかからタグ<itemName>と<smallImageUrl>の要素を取得します。
本来検索キーワードを使用する場合、日本語をエンコードしたりしなければならないのですが、JANコードは半角数字なので、そのまま検索可能です!!これはらくちんでありがたいですな。



2 戦士情報画面の表示
取得した商品(戦士)情報を表示するために、商品(戦士)表示画面を実装します。
編集画面とかで下からニュ〜って出てくるあの画面のことです。

全体的な流れは以下の通り。

商品(戦士)表示画面にJANコードを渡す
リクエストURLの生成
xmlのパース
商品情報表示
戦闘力の算出(次回)
戦士の端末への登録処理(次回以降)

商品情報表示までを今回やります。
ではでは早速、商品(戦士)表示画面の実装を始めます。

適当にUIViewControllerのサブクラスを作成して下さい。クラス名は適当にMonsterShowViewControllerとでもしましょうか。

前回の「4つのtabに対するビューコントローラーを作成する」と全く一緒です。今回は折角ですのでXibファイルも一緒につくりましょう。

File→New→New File→UIViewController subclassを選択→NEXTをクリック→UIViewControllerを選択してWith Xib〜チェックボックスにチェック→名前をMonsterShowViewControllerにして保存

こんな感じになればオーケー。


次にMonsterShowViewController.xibファイルを編集します。
まあこんな感じで、商品名表示用のlabelと、画像表示用のUIImageViewを貼付ければオーケー
MonsterShowViewController.xib


次にMonsterShowViewController.hで使用する変数やらを宣言します。

MonsterShowViewController.h
---------------------------------------------------------------

@interface MonsterShowViewController : UIViewController {
    
    IBOutlet UIImageView *imageView; 
    IBOutlet UILabel *itemName;
    NSString *requestUrl;
}
@property(nonatomic,retain)UIImageView *imageView;
@property(nonatomic,retain)NSString *jancode;
@property(nonatomic,retain)UILabel *itemName;

@end
---------------------------------------------------------------

リクエスト用のURLも一緒に宣言しておきます。ちなみにIBOutletはInterfaceBuilderで使用してまっせという意味です。

.mファイル側の@synthesizeも忘れずに。まあ注意出るから言わんでもわかると思うけど。



MonsterShowViewController.h
---------------------------------------------------------------


#import "MonsterShowViewController.h"

@implementation MonsterShowViewController
@synthesize imageView;
@synthesize itemName;
@synthesize jancode;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}
---------------------------------------------------------------


そしたら次にIB(InterfaceBuilder)を使用して、nibファイルとつなぎます。
MonsterShowViewController.xibを開いて、File's Ownerを右クリック。
imageViewとImage View
itemNameとLavel
の二つを接続。

これでオーケー!!

次にこのモンスター表示画面(戦士とか呼ぶよりモンスターのがしっくりきたので)をバーコード撮影後に呼び出します。

まず呼び出し側(BarcodeScanViewController)で呼び出される側(MonsterShowViewController)のクラスをインポートします。

そしたらBarcodeScanViewControllerの撮影完了後に呼び出されるメソッド内で、MonsterShowViewControllerを呼び出してみましょう。

以下のようにします。

BarcodeScanViewController.m (didFinishPickingMediaWithInfoメソッド内)
---------------------------------------------------------------

- (void)imagePickerController:(UIImagePickerController *)reader
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    id results = [info objectForKey:ZBarReaderControllerResults];
    ZBarSymbol *symbol = nil;
    
    for (symbol in results)
        break;

    [reader dismissModalViewControllerAnimated:YES];
    NSLog(@"%@",symbol.data);
    
    
    MonsterShowViewController *monsterShow = [[MonsterShowViewController alloc]initWithNibName:@"MonsterShowViewController" bundle:nil];
    
    [self.view addSubview:monsterShow.view];
    [monsterShow release];
}
---------------------------------------------------------------

これでバーコード撮影後に商品(モンスター)表示画面が表示されると思います。一応テストしてみて下さい。

3 リクエストURLの生成→XMLの取得
リクエストURLを作成して、楽天からxmlを取得してみましょう。
まず、モンスター表示クラス(MonsterShowViewController)に取得したJANコードを渡します。BarcodeScanViewController.m のdidFinishPickingMediaWithInfoメソッド内に以下のコードを付け足します。

BarcodeScanViewController.m (didFinishPickingMediaWithInfoメソッド内)
---------------------------------------------------------------
- (void)imagePickerController:(UIImagePickerController *)reader
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    id results = [info objectForKey:ZBarReaderControllerResults];
    ZBarSymbol *symbol = nil;
    
    for (symbol in results)
        break;

    [reader dismissModalViewControllerAnimated:YES];
    NSLog(@"%@",symbol.data);
    
    
    MonsterShowViewController *monsterShow = [[MonsterShowViewController alloc]initWithNibName:@"MonsterShowViewController" bundle:nil];
    monsterShow.jancode = symbol.data;
    [self.view addSubview:monsterShow.view];
    [monsterShow release];
}
---------------------------------------------------------------

これでオーケー。
次に、取得したJANコードからURLを生成するメソッドを追加します。

http://api.rakuten.co.jp/rws/3.0/rest?developerId=[あなたのdeveloperID]&operation=ItemSearch&version=2010-09-15&keyword=

の末尾にjanコードをつけ足せばいいだけですね。以下のようにします。
MonsterShowViewController.m viewDidLoadメソッド
---------------------------------------------------------------

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"monsterShowに渡されたjancode %@",jancode);
    NSString *requestUrl;
    requestUrl = [@"http://api.rakuten.co.jp/rws/3.0/rest?developerId=[あなたのdeveloperID]&operation=ItemSearch&version=2010-09-15&keyword="stringByAppendingString:jancode];
}
---------------------------------------------------------------

こんなんでオーケーなんですな。

それではリクエストを投げてみましょう。ここからは面倒ですぜ兄さん。
まず、ヘッダーファイル(MonsterShowViewController.h)で色々宣言しましょう。

MonsterShowViewController.h
---------------------------------------------------------------

@interface MonsterShowViewController : UIViewController {
    
    IBOutlet UIImageView *imageView; 
    IBOutlet UILabel *itemNameLabel;
    NSString *jancode;
    
    NSMutableData *webData;
    NSURLConnection *conn;
  
}
@property(nonatomic,retain)UIImageView *imageView;
@property(nonatomic,retain)NSString *jancode;
@property(nonatomic,retain)UILabel *itemNameLabel;
-(void) parseTag:(NSString*)requestUrl;
@end
---------------------------------------------------------------



あたらしく二つのインスタンス変数と、一つのメソッドが宣言されました。
次に実装です。以下のコードをぐばっとコピー&ペーストしちゃって下さい。

MonsterShowViewController.m 
---------------------------------------------------------------

-(void) parseTag:(NSString*)requestUrl;
{
    NSURL *url = [NSURL URLWithString:requestUrl];    
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[req addValue:0 forHTTPHeaderField:@"Content-Length"];
[req setHTTPMethod:@"GET"];
conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
    if (conn)
    {
webData = [[NSMutableData data] retain];
}
}

-(void) connection:(NSURLConnection *) connection 
didReceiveResponse:(NSURLResponse *) response 
{
[webData setLength: 0];    
}

-(void) connection:(NSURLConnection *) connection 
didReceiveData:(NSData *) data 
{
[webData appendData:data];
}

-(void) connection:(NSURLConnection *) connection 
  didFailWithError:(NSError *) error 
{
    //伝送中にエラーが生じた場合
[webData release];
    [connection release];
}

-(void) connectionDidFinishLoading:(NSURLConnection *) connection 
{
    //接続が終了し、レスポンスのダウンロードに成功すると、次のconnectionDidFinishLoading:メソッドが呼び出される。
    
     NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes]
                                                 length:[webData length] 
                                               encoding:NSUTF8StringEncoding];
     //---shows the XML---
     NSLog(@"%@",theXML);
     [theXML release];    
     
}

---------------------------------------------------------------

んで、呼び出しはこんな感じ。
MonsterShowViewController.m viewDidLoadメソッド
---------------------------------------------------------------
- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"monsterShowに渡されたjancode %@",jancode);
    NSString *requestUrl;
    requestUrl = [@"http://api.rakuten.co.jp/rws/3.0/rest?developerId=[あなたのdeveloperID]&operation=ItemSearch&version=2010-09-15&keyword="stringByAppendingString:jancode];
 [self parseTag:requestUrl];
}
---------------------------------------------------------------

これで完了です。(あれ意外と一瞬で終わってもうたぞ)

早速実行してみましょう。
カメラでの撮影が終了すると、コンソール上にxmlの内容が大量に表示されるはずです。
コンソールってどこー??って人は、xcodeの右上にある
の真ん中をクリックしてみて下さい。


これでXML情報を取得するところまでは実装できました。
当初の予定ではXML内容を解析するところまでやる予定だったのですが、字数がやたら多くなってしまったので、XMLの解析は次回にまわします。

ではでは。