Mac初心者のiPhoneアプリ開発記5 因縁のTwitterビューア

twitter

今回は難しくて挫折していた「iOS 4のSDKで、Twitterを使ったiPhoneアプリを作る」(以下 教材)に再び挑みました。

結論から言えば、前回までのObjective-Cの勉強が功を奏しTwitterビューアを作ることができました。しかし教材とXcodeのバージョンが異なるためトラブルが続出し、かなりハードルが高くなりました。

このハードルを乗り越える工程こそ糧になるとも言えますが、素直に最新のXcode向けの教材で勉強した方が良さそうなので、次回からは違う教材を探します。なのでこの記事に価値があるか微妙ですが、とりあえず記録にしました。

今回、試行錯誤した中で発見した収穫の一つはアップル公式の日本語ドキュメントの存在。きっと当然知ってるはずの存在だったんでしょうね。(;・∀・) 内容もかなり充実しているので、今後探っていきます。

それでは因縁のTwitterビューアに挑みます。

 

全体の流れ

iOS 4のSDKで、Twitterを使ったiPhoneアプリを作る

教材はXcodeのバージョンアップから始まるが当然飛ばす。プロジェクトを新規作成。

Navigation-based Application → Master-Detail Application

に名称が変わったようだ。

プロジェクト作成後すぐ実行してみると、教材の画面よりもGUIがリッチになっているのが分かる。リスト表示だけではなく詳細画面も用意されてる。とりあえず先にすすむ。

全体の流れは3つのパートに分かれる。

  1. Twitterに接続してデータ取得
  2. 取得したデータ(XML)を解析し必要な情報を抽出
  3. 結果をiPhoneに一覧表示

 

1. Twitterに接続してデータ取得

最初は通信用クラスNSURLConnectionの使い方を勉強する。厳密に全てを理解しようとするとフレームワークの中にまで踏み込むことになるので、とりあえず程々に理解していく。ここで初めてiOS5から導入されたARCの存在を知る。前回勉強したメモリ管理のRetain、Release、Autoreleaseが自動で行われるようだ。

通信用クラス NSURLConnection
このクラスは「同期通信」「非同期通信」という2種類の通信が可能。同期だと通信中は操作できなくなるので、今回は非同期通信で作成する。その為、受信が完了したら実行する処理を前もって登録しておく。
Cocoa Notification
非同期通信が終了したときの処理を登録しておく。
ARC(Automatic Reference Counting)
iOS5から導入された。Retain、Release、Autoreleaseを自動で行う機能。

NSURLConnectionを使うために、まず新しくURLLoaderクラスを作成、この中に教材のコードをコピペ。ソースと説明を読んで何をしているかを把握する。現段階ではデリゲートの言葉の意味がいまいち不透明だが、とりあえず進む。

ソースをコピペしてビルドするとエラーが。

1

ここでARCの存在を知った。とりあえずARCによって不要になった該当箇所をコメントアウト。ここまででURLLoaderクラスの作成は終わり。

 

URLLoaderクラスをMasterViewControllerにインポート

今作ったURLLoaderクラスを、教材ではRootViewControllerにインポートとあるが、RootViewControllerの代わりに MasterViewController と DetailViewController が作成されている。リスト画面はMasterViewController、詳細画面はDetailViewControllerと推測して進む。

ソースをコピペ。再びARC関連のエラー。autoreleaseを外す。

URLLoader *loder = [[[URLLoader alloc] init] autorelease];
↓
URLLoader *loder = [[URLLoader alloc] init];

ソースにURLが出てくる。ここにアクセスしてツイートを取得するわけだ。

static NSString *urlFormat = @"http://twitter.com/status/user_timeline/%@.xml";

viewDidLoadメソッド内にUIBarButtonItemクラスの定義等が増えているが、それらは削除せず

[self loadTimeLineByUserName:@"itmedia"];
を追記。

ここまでで実行してみる。コンソールがどこにあるか分からなかったがXcodeのウィンドウ下にでてた。

コンソール出力結果
2013-03-17 17:16:34.378 TwitterViewer[680:11303] <?xml version="1.0" encoding="UTF-8"?>
<errors>
  <error code="34">Sorry, that page does not exist</error>
</errors>

なにやらエラーがでてる。通信は成功しているようだ。恐らくTwitterのアドレスが変更されたと当たりをつけググルと解法が。

TwitterのRSSが「Sorry, that page does not exist」エラーでツイート取得できなくなった場合の解決方法 | memobits

memobitsさんの記事を参考に、先ほどのurlFormatのURLを変更。

static NSString *urlFormat = @"http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=%@";

やた!ツイートが取得できた!

コンソール出力結果
2013-03-17 17:18:56.156 TwitterViewer[695:11303] <?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:georss="http://www.georss.org/georss" xmlns:twitter="http://api.twitter.com" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Twitter / itmedia</title>
    <link>http://twitter.com/itmedia</link>
    <atom:link type="application/rss+xml" href="http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=itmedia" rel="self"/>
    <description>Twitter updates from ITmedia / itmedia.</description>
    <language>en-us</language>
    <ttl>40</ttl>
  <item>
    <title>itmedia: [ねとらぼ]これぞマッチ棒の魔術師 マッチでできたミニチュア聖堂が見事 http://t.co/v7wMe5pSJF</title>
    <description>itmedia: [ねとらぼ]これぞマッチ棒の魔術師 マッチでできたミニチュア聖堂が見事 http://t.co/v7wMe5pSJF</description>
    <pubDate>Sun, 17 Mar 2013 05:20:20 +0000</pubDate>
    <guid>http://twitter.com/itmedia/statuses/313157832478449664</guid>
    <link>http://twitter.com/itmedia/statuses/313157832478449664</link>
    <twitter:source><a href="http://www.itmedia.co.jp/" rel="nofollow">ITmediaなう</a></twitter:source>
    <twitter:place/>
  </item>
以下略

 

取得したデータ(XML)を解析、必要な情報を抽出

取得したXMLを解析するのはNSXMLParserクラス。ここでもARC関係のエラーがでるが同じ方法で対処する。とりあえず教材通りに進めるが実行しても取得した内容がリスト表示されない。ここの原因究明はしんどかった。

ここでも教材のRootViewControllerはMasterViewControllerに置き換えて作業。教材の@synthesize statusesはセミコロンが抜けていた。

//(15)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
}

(15)の中に最初から記述してある部分はコメントアウトして、教材の内容をコピペした。

ここで実行するが、エミュレータには何も表示されない

2

原因を探る

コンソールを見るとXMLは取得できているので、追加したXMLの解析が失敗しているハズだ。

didStartElement内でタグを比較しているのでself.currentXpathをNSLogで出力してみる。

NSLog(@"%@", self.currentXpath);

やはりXMLのフォーマットが変わったようだ。

2013-03-17 18:27:21.268 TwitterViewer[1082:11303] rss/
2013-03-17 18:27:21.269 TwitterViewer[1082:11303] rss/channel/
2013-03-17 18:27:21.270 TwitterViewer[1082:11303] rss/channel/title/
2013-03-17 18:27:21.270 TwitterViewer[1082:11303] rss/channel/link/
2013-03-17 18:27:21.270 TwitterViewer[1082:11303] rss/channel/atom:link/
2013-03-17 18:27:21.271 TwitterViewer[1082:11303] rss/channel/description/
2013-03-17 18:27:21.271 TwitterViewer[1082:11303] rss/channel/language/
2013-03-17 18:27:21.271 TwitterViewer[1082:11303] rss/channel/ttl/
2013-03-17 18:27:21.272 TwitterViewer[1082:11303] rss/channel/item/
2013-03-17 18:27:21.272 TwitterViewer[1082:11303] rss/channel/item/title/
2013-03-17 18:27:21.272 TwitterViewer[1082:11303] rss/channel/item/description/
2013-03-17 18:27:21.273 TwitterViewer[1082:11303] rss/channel/item/pubDate/
2013-03-17 18:27:21.273 TwitterViewer[1082:11303] rss/channel/item/guid/
2013-03-17 18:27:21.273 TwitterViewer[1082:11303] rss/channel/item/link/
2013-03-17 18:27:21.273 TwitterViewer[1082:11303] rss/channel/item/twitter:source/
2013-03-17 18:27:21.274 TwitterViewer[1082:11303] rss/channel/item/twitter:place/
以下略

StatusXMLParserクラス内の記述を変更。

  • statuses/status/ → rss/channel/item/
  • statuses/status/text/ → rss/channel/item/title/
  • statuses/status/user/name/ → rss/channel/item/description/

ビンゴ!リスト表示されました。

3

 

結果をiPhoneに一覧表示

しかし表示はされましたが、Xcodeのバージョンが違うのを無理に進めているので教材と表示が異なる。

ユーザー名は表示されていないし(といっても今回はdescriptionが入る)、タップで詳細画面に移動するという教材よりもリッチなGUIになっている。ちなみに詳細画面には”Detail view content goes here”という固定メッセージが表示されている。

教材では、次にリストの表示枠を広げてツイートの全文を表示するが、ちと教材を離れ、詳細画面で全文を見れるようにしたいと思い立つ。しかし、どうすればいいか検討もつかない。


詳細画面はDetailViewControllerクラスでコントロールするはず。なので、とりあえず”MasterViewController DetailViewController”などでググッてリサーチを重ねると、2つの画面を行き来する方法が分かってくる。

Xcode4.2 でテーブルビューの遷移 : てるてる坊主

てるてる坊主さんの記事を参考に、 DetailViewController.hに橋渡しとなる変数を定義し、configureViewでそれを表示。didSelectRowAtIndexPathで変数に値をセットする。という流れでいけそうだったが、うまくいかない。

具体的にはdidSelectRowAtIndexPathで値のセットができていないよう。ここでかなり時間を使ったが、さらにリサーチを重ね、遷移時に変数を渡すにはprepareForSegueに記述すれば良いことが分かる。

StoryboardとSegueの基本 - Kesin’s memo

StoryBoards - iOS Developerの道

Storyboard
画面レイアウトと画面間の遷移を管理するためにXcode4.2から導入されたUIビルダー。
セグエ( Segue )
シーンとシーンをくっつけるためのオブジェクト。

ここまでを参考に、受け渡し用の変数を定義し、

DetailViewController.h
@property (nonatomic, assign) NSString *tweet;
DetailViewController.m
@synthesize tweet;
- (void)configureView
{
    // Update the user interface for the detail item.
    self.detailDescriptionLabel.text = [NSString stringWithFormat:@"%@", tweet];
}

さらにprepareForSegueを下のように変更。

MasterViewController.h
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"showDetail"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        NSDate *object = _objects[indexPath.row];
        [[segue destinationViewController] setDetailItem:object];

        // 下の内容を追加
        DetailViewController *viewController = (DetailViewController*)[segue destinationViewController];
        viewController.tweet =  [[statuses objectAtIndex:indexPath.row] objectForKey:@"text"];
     }
}

すると、詳細画面にツイートが表示された!

4

文字が切れているので、StoryboardでLinesを4に修正し、望みどおりの結果になりました。

5

6

後半は独自の改造となりましたが、長くなったので今回はここまでとします。Xcodeのバージョンの違いにより苦しみましたが収穫も多かった。次回はこのTwitterビューアを改造していくか、もしくは力量にあった教材を見つけて学習を続けます。

この連載の一覧

  1. Mac初心者のiPhoneアプリ開発記

    この記事は先日購入したMacBook Air(略してMBA)でiPhoneアプリ...

  2. Mac初心者のiPhoneアプリ開発記2 Xcodeの闇の中で

    iPhoneアプリ開発するぞ!と意気込んでMBAを購入したのは1年前。でもAnd...

  3. Mac初心者のiPhoneアプリ開発記3 Objective-Cの壁

    手探りで進めているiPhoneアプリ開発記。前回は@ITの記事を参考に、Xcod...

  4. Mac初心者のiPhoneアプリ開発記4 Objective-Cの復讐

    前回から10日もたってしまい、ほとんど忘れてる状態からの再開です。今回も引き続き...

  5. Mac初心者のiPhoneアプリ開発記5 因縁のTwitterビューア

    今回は難しくて挫折していた「iOS 4のSDKで、Twitterを使ったiPho...

  6. Mac初心者のiPhoneアプリ開発記6 画像処理はじめました

    前回から随分時間が経ってしまいました。iPhoneアプリ市場は激戦なので、果たし...

  7. Mac初心者のiPhoneアプリ開発記7 設定画面を作る

    今回はツール系アプリなら装備しておきたい、いわゆる設定画面を作ります。今後アプリ...

  8. iOSの進化とフラットデザイン

    iKuracさんが作成したiOSの比較画像。先日発表されたiOS7のデザインの路...

  9. Mac初心者のiPhoneアプリ開発記8 設定画面を動的に作る

    前回は設定画面を作るためにストーリーボードやTableViewの仕組みを勉強しま...

  10. Mac初心者のiPhoneアプリ開発記9 アプリ申請までの道

    ようやく!初のiPhoneアプリ申請までたどり着きました。名前は『Screens...

  11. Mac初心者のiPhoneアプリ開発記 リリース後の反応

    実は先日8/9に『Screenshot Maker Pro』がリリースしました。...

  12. 大人センスなiPhone壁紙『A new world』

    NYで活躍中のドイツ人デザイナーTobias van Schneiderさんの作...

  13. ReynoldsさんのiPhone壁紙

    渋い色調のポリゴン地形がお洒落。Timothy J. Reynoldsさんの作品...

  14. シンプルの美学アンソニーさんのiPhone壁紙

    Anthony Zinonosさんの壁紙。青と黒、シンプルに色分けされた海上にオ...

  15. iPhoneアプリ開発記 iOS7対応で必要だったこと

    公開中のiPhoneアプリ『Screenshot Maker Pro』をiOS7...

  16. Cocos2d-xでiPhone&Androidアプリ開発記1

    そろそろ次のアプリ開発と日々考えていたんですが、私は個人開発なので今後は小粒なゲ...

  17. Cocos2d-xでiPhone&Androidアプリ開発記2 バージョン3.x系挫折

    『ドラゴンクエストモンスターズ スーパーライト』がCocos2d-xで開発とのこ...

  18. Cocos2d-xでiPhone&Androidアプリ開発記3 初心者TIPS

    今回で3回目のCocos2d-x連載。自作アプリを製作中ですが7割ほど完成してき...

  19. Cocos2d-xでiPhone&Androidアプリ開発記4 AdMobメディエーションでAdMob+iAd iOS編

    Cocos2dxで広告を表示するにはiOSとAndroid別々に設定が必要です。...

  20. Cocos2d-xでiPhone&Androidアプリ開発記5 AdMob Android編

    iOSに続きAndroidにAdmodを導入します。とりあえずAdModだけ表示...

  21. Cocos2d-xでiPhone&Androidアプリ開発記6 Android対応

    Androidアプリ開発経験は全くない状態で始めたCocos2dx。ここまでの開...

  22. Cocos2d-xでiPhone&Androidアプリ開発記7 ローカライズとアイコン組み込み

    ようやく初めてのcocos2dxアプリが完成しました! アルファベットを組み合わ...

  23. Cocos2d-xでiPhone&Androidアプリ開発記8 開発の流れとアプリ申請

    Cocos2d-xで初めてのアプリを公開しました。AndroidとiPhone両...

  24. Cocos2d-xでiPhone&Androidアプリ開発記9 SQLiteの注意点

    Cocos2d-xからSQLiteを使うには、iOSとAndroidそれぞれにラ...

  25. Cocos2d-xでiPhone&Androidアプリ開発記10 アプリ高速化

    Cocos2d-xで2本目をリリースしました。前回の英語パズルの続編『英単語ギズ...

  26. Cocos2d-xでiPhone&Androidアプリ開発記11 Androidのデバッグ

    Cocos2d-xによるアプリの新作をほぼ作り終えました。開発はXCode主体で...

  27. iOS/Androidアプリ『英単語RPG ワード・オブ・ザ・リング』

    iPhone/Androidアプリ『英単語RPG ワード・オブ・ザ・リング』を公...

  28. 人にも読めるQRコード

    人にも読めるQRコード『Human Readable Quick Respons...

  29. Xcode7にiOS 8 Simulatorがインストールできない

    Xcode 7.0.1に、iOS 8.1 Simulatorをインストールしよう...

 

 

広告