ページ

2013-08-05

iOSアプリ開発事始09:GitHubライブラリ「EGOTableViewPullRefresh」を実際にサンプルプログラムに実装してみました!

今回はGitHubで公開されているオープンソースのライブラリからプルリフレッシュを行なう「EGOTableViewPullRefresh」をダウンロードして、実際にサンプルアプリに実装するまでを行ってみる試みです。「EGOTableViewPullRefresh」は、プルリフレッシュしてくれる機能、例えばテーブルビューの画面でプル(引っ張る)アクションを行なうことで情報を更新してくれたりする。今回、学習教材として使用させていただいたのは、@IT(アットマーク・アイティ)生産性ガチアゲなオープンソースiOSライブラリ(2):iOSアプリのUIを爆速で激ヤバにする2つのライブラリ (1/4) 」の記事です。「習うより慣れろ」ということで、実演リポートを記します。



    GitHub(ギットハブ)はソフトウェア開発プロジェクトのための共有ウェブサービスであり、Gitバージョン管理システムを使用する。 Ruby on RailsおよびErlangで記述されており、GitHub社によって保守されている。 主な開発者はChris Wanstrath、PJ Hyett、Tom Preston-Wernerである。 GitHub商用プランおよびオープンソースプロジェクト向けの無料アカウントを提供している。 2009年のユーザー調査によると、GitHubは最もポピュラーなGitホスティングサイトとなった。
    出典:GitHub - Wikipedia
    今回のシステム環境
    OS X Mountain Lion 10.8.4
    Xcode 4.6.3

ライブラリから「EGOTableViewPullRefresh」をダウンロード

まずは、GitHubのライブラリから「EGOTableViewPullRefresh」をダウンロードします。GitHubのトップページの検索窓に「EGOTableViewPullRefresh」を入れて検索結果からダウンロードすることもできます。手順としては、今回はライブラリのタイトルが分かっているのでGitHubのトップから説明しますね。ちなみに、オープンソースソフトウェア(OSS)で公開されているものは、アカウント無しでもダウンロードができるようになっているそうです。今回はアカウント無しで行ないます。

  1. GitHubサイトへGo
  2. GitHubのトップページにアクセスします。右上にライブラリの検索窓があるので、ここに「EGOTableViewPullRefresh」と入力して「Enter」を押します。


  3. 該当タイトルをクリック
  4. 検索結果のページが表示されます。探しているライブラリ「EGOTableViewPullRefresh」に該当するタイトルを探して、タイトルをクリックします。


  5. 「Download ZIP」ボタンでダウンロード
  6. 「EGOTableViewPullRefresh」の詳細画面が表示されます。「Download ZIP」ボタンをクリックしてダウンロードします。


  7. ZIPファイルの解凍を指定して「OK」ボタンをクリック
  8. ダウンロードが終わるとファイルの処理の問い合わせダイアログが表示される。「アプリケーションで開く」のラジオボタンをオンにして「OK」ボタンをクリックします。


  9. 解凍ファイルを確認
  10. ファインダーかDockの「ダウンロード」の中を見ると、先ほどダウンロードしたZIPファイル「EGOTableViewPullRefresh-master.zip」と解凍フォルダ「EGOTableViewPullRefresh-master」があることが確認できる。


Xcodeでサンプル・プロジェクトを作成

Xcodeを起動して新しくプロジェクトを作成して、「EGOTableViewPullRefresh」をそのプロジェクトに追加します。

  1. プロジェクトの新規作成
  2. Xcodeを起動して起動画面の「Create a new Xcode project」を選択して「Open」ボタンをクリックする。起動画面が表示されない場合には「shift+cmd+N」かメニューバーの「File」→「New」→「project」でプロジェクトの新規作成。


  3. テンプレート「Empty Application」を選択
  4. 「Create a template for your new project」の画面に遷移したら、作成プロジェクトのOSが「iOS」で「Application」を選択していることを確認しましょう。画面右のテンプレートのアイコンの中から「Empty Application」を選んで「Next」ボタンをクリックします。


  5. プロジェクト情報の入力・設定
  6. プロジェクト名などの基本情報をお好みで入力・設定します。設定できたら「Next」ボタンをクリックします。


  7. プロジェクトの保存
  8. 新しいプロジェクトの保存場所を設定する画面が表示されたら、任意の場所を選んで「Create」ボタンをクリックして保存します。


  9. ワーク画面を表示
  10. 新しく作成したプロジェクトのワーク画面が表示されます。


  11. ファインダで「EGOTableViewPullRefresh」を開く
  12. ここでGitHubのライブラリからダウンロードして解凍した「EGOTableViewPullRefresh」フォルダをファインダで開きます。「EGOTableViewPullRefresh」フォルダの中にもうひとつ「EGOTableViewPullRefresh」フォルダがあります。


  13. プロジェクトに「EGOTableViewPullRefresh」を追加
  14. 「EGOTableViewPullRefresh」フォルダの中の「EGOTableViewPullRefresh」フォルダをドラッグ&ドロップで、ナビゲーター・エリアにあるプロジェクト・フォルダ(今回は「SampleApp」フォルダ)にまるごと入れます。


  15. ソースプログラム「EGOTableViewPullRefresh」の追加完了
  16. 「EGOTableViewPullRefresh」フォルダをプロジェクト・フォルダに入れると、「Choose options for adding these files」の画面が表示されます。ここは単純に「Finish」ボタンをクリックします。これでひとまず機能追加の完了です。


  17. 「Objective-C class」を追加
  18. 画面右下にあるユーティリティ・エリアにあるライブラリの一番左にあるアイコンをクリックして、「File Template Library」を表示します。


    「File Template Library」の中にある「Objective-C class」を、「EGOTableViewPullRefresh」と同様にドラッグ&ドロップで、、ナビゲーター・エリアにあるプロジェクト・フォルダ(「SampleApp」フォルダ)に入れます。


  19. 任意の保存名を記入して保存
  20. ダイアログボックスが表示され、保存名を求めてきます。ここでは「SampleAppViewController」としました。記入したら「Create」をクリックします。


  21. 「.h」と「.m」のファイルを生成
  22. 「SampleApp」フォルダの中に「SampleAppViewController.h」と「SampleAppViewController.m」の2つのファイルが生成されました。

ARC(Automatic Reference Counting)設定の変更

「EGOTableViewPullRefresh」はARCに対応していないということで、設定を変える必要があるということです。
その設定変更の手順は、表示された「Build Phases」一覧の中の「Compile Sourses」の「EGORefreshTableHeaderView.m」を一部変更、「Link Binary With Libraried」に「QuartzCore.framework」を追加します。
  1. 「Build Phases」をクリック
  2. まず、エディタ・エリアのツールバーメニュー「Build Phases」をクリックします(エディタ・エリアにプロジェクト・エディタを表示した状態でない場合は、ナビゲーター・エリアでプロジェクトを選択してプロジェクト・エディタのツールバーを表示します)。


  3. 「Build Phases」の一覧リスト表示
  4. Build Phases」をクリックすると、一覧リストに「Target Dependencies」「Compile Sources」「Link Binary With Libraries」「Copy Bundle Resources」の4項目が表示されます。


  5. EGORefreshTableHeaderView.mに「-fno-objc-arc」を追加
  6. Compile Sources」の横矢印をクリックしてリストを表示します。表示されたリストの中から「EGORefreshTableHeaderView.m」を選んで、該当行の「Compiller Flags」部分をダブルクリックします。入力枠が表示されたら、「-fno-objc-arc」を入力します。


  7. 「QuartzCore.framework」を追加
  8. 今度は「Link Binary With Libraries」に「QuartzCore.framework」を追加します。「Link Binary With Libraries」の横矢印をクリックしてリストを表示。リスト下の「」をクリックします。

    Choose frameworks and libraries to add:」の一覧リスト画面が表示されます。検索窓で「QuartzCore.framework」を入力して検索するか、リストをスクロールして「QuartzCore.framework」を探して選択します。右下の「Add」をクリックして追加終了です。


  9. 設定変更の確認
  10. Compile Sources」の「EGORefreshTableHeaderView.m」に「-fno-objc-arc」を、「Link Binary With Libraries」に「QuartzCore.framework」を追加したことを確認しましょう。

  11. iOSシュミレータを起動してみる
  12. EGORefreshTableHeaderViewライブラリを設定、設定したライブラリに合わせてARC(Automatic Reference Counting)設定も変更しました。ここでiOSシュミレータを起動してみましょう。…iPhoneには何も表示されないですね。データが表示されるようにソースコードを変更しなければいけないんですね。


ソースコードの変更・追加

  1. 「AppDelegate.m」ファイルのコード変更
  2. AppDelegate.m」のコードを変更します。下記の部分を変更します。これはSampleAppViewControllerが表示されるための処理ですね。ナビゲータ・エリアで「AppDelegate.m」を選びコード・エディタを表示します。
    #import "AppDelegate.h"
    
    @implementation AppDelegate
    @synthesize managedObjectContext = _managedObjectContext;
    @synthesize managedObjectModel = _managedObjectModel;
    @synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // Override point for customization after application launch.
        self.window.backgroundColor = [UIColor whiteColor];
        [self.window makeKeyAndVisible];
        return YES;
    }
    上記のコードを以下のように変更します。変更・追加したコードは赤字で表示しています。
    #import "AppDelegate.h"
    #import "SampleAppViewController.h"
    @implementation AppDelegate
    @synthesize managedObjectContext = _managedObjectContext;
    @synthesize managedObjectModel = _managedObjectModel;
    @synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // Override point for customization after application launch.
        self.window.backgroundColor = [UIColor whiteColor];
        self.window.rootViewController = [[SampleAppViewController alloc] init];
        [self.window makeKeyAndVisible];
        return YES;
    }
    
  3. 「SampleAppViewController.h」ファイルのコード変更
  4. 「SampleAppViewController.h」にはEGORefreshTableHeaderViewをimportするためのコードと必要なDelegateと変数を記述します。「SampleAppViewController.h」を選びコード・エディタを表示します。
    #import <Foundation/Foundation.h>
    
    @interface SampleAppViewController : NSObject
    
    @end
    上記のコードを以下のように変更します。変更・追加したコードは赤字で表示しています。
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    #import "EGORefreshTableHeaderView.h"
    @interface SampleAppViewController : UITableViewController
    <
    EGORefreshTableHeaderDelegate,
    UITableViewDelegate,
    UITableViewDataSource
    >
    {
        // 更新中を表示するViwe
        EGORefreshTableHeaderView *_refreshHeaderView;
        BOOL _reloading;
        // Cellの文字列、更新時に変更
        NSString *_cell_string;
    }
    @end
  5. 「SampleAppViewController.m」ファイルのコード変更
  6. 「SampleAppViewController.m」ファイルにEGOTableViewPullRefreshに必要なメソッド実装、テーブル内容表示、更新処理を記述します。「SampleAppViewController.m」を選びコード・エディタを表示します。表示されたコードは以下のような感じかと思います。
    #import "SampleAppViewController.h"
    
    @implementation SampleAppViewcontroller
    
    @end
    上記のコードを以下のように変更します。変更・追加したコードは赤字で表示しています。
    #import "SampleAppViewController.h"
    
    @implementation SampleAppViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        _cell_string = @"Before";
        if (_refreshHeaderView == nil) {
            // 更新ビューのサイズとデリゲートを指定する
            EGORefreshTableHeaderView *view =
            [[EGORefreshTableHeaderView alloc] initWithFrame:
             CGRectMake(
                        0.0f,
                        0.0f - self.tableView.bounds.size.height,
                        self.view.frame.size.width,
                        self.tableView.bounds.size.height
                        )];
            view.delegate = self;
            [self.tableView addSubview:view];
            _refreshHeaderView = view;
        }
        // 最終更新日付を記録
        [_refreshHeaderView refreshLastUpdatedDate];
    }
    // セルの数
    - (NSInteger)tableView:(UITableView *)tableView
     numberOfRowsInSection:(NSInteger)section {
        return 10;
    }
    // テーブルのセル表示処理
    - (UITableViewCell *)tableView:(UITableView *)tableView
             cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }
        // 表示されるセルのテキストを設定
        cell.textLabel.text = [NSString stringWithFormat:@"%@ - %d", _cell_string, indexPath.row];
        // Update後だったら文字色を変更
        if ([_cell_string isEqualToString:@"Update"]) {
            cell.textLabel.textColor = [UIColor brownColor];
        }
        return cell;
    }
    // スクロールされたことをライブラリに伝える
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        [_refreshHeaderView egoRefreshScrollViewDidScroll:scrollView];
    }
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView
                      willDecelerate:(BOOL)decelerate {
        [_refreshHeaderView egoRefreshScrollViewDidEndDragging:scrollView];
    }
    // テーブルを下に引っ張ったら、ここが呼ばれる。テーブルデータをリロードして3秒後にdoneLoadingTableViewDataを呼んでいる
    - (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{
        _reloading = YES;
        // 非同期処理
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        [queue addOperationWithBlock:^{
            // 更新処理など重い処理を書く
            // 今回は3秒待ち、_cell_stringをUpdateに変更
            [NSThread sleepForTimeInterval:3];
            _cell_string = @"Update";
            [self.tableView reloadData];
            // メインスレッドで更新完了処理
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                [self doneLoadingTableViewData];
            }];
        }];
    }
    // 更新終了
    - (void)doneLoadingTableViewData{
        // 更新終了をライブラリに通知
        _reloading = NO;
        [_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tableView];
    }
    // 更新状態を返す
    - (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView*)view{
        return _reloading;
    }
    // 最終更新日を更新する際の日付の設定
    - (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView*)view{
        return [NSDate date];
    }
    @end
    以上でコードの修正は終わりです。@IT(アットマーク・アイティ)「生産性ガチアゲなオープンソースiOSライブラリ(2):iOSアプリのUIを爆速で激ヤバにする2つのライブラリ (1/4) 」の記事をそのままにトレースしてここまで来ました。行間を読まないとというか、分かっていることを前提に書かれているようなところもあり、書かれていないことを理解、穴埋めしていかないと前に進めなかったりしますね。なんとかここまで来ました。最後の仕上げと感動を味わうために、実際に動かしてみましょう。

サンプルプロジェクトを実際に動かしてみる

  1. 最初の画面
  2. iOSシュミレータを起動してみましょう。「RUN」ボタンですね。「おおっ、最初の画面が表示されました。」


  3. リストを下に引っ張る
  4. さて、リストを下に引っ張ったときの動作が、ライブラリをダウンロードしてここまでやってきたことの目的でしたね。さあ、やってみましょう! 上↓と「Releade to refresh」の文字が表示されました。

    ちょっとすると、「Loading…」の文字。、


  5. はい! 画面がリフレッシュされました
  6. 更新処理が行なわれ、新たな画面が表示されました。サンプルでの表示はリフレッシュ処理をトリガーとしてリスト内のデータを変更しているだけということです。とりあえず、下の画面が出たので成功です。


いやぁ、長かったですね。今回の目的、GitHubのライブラリをインストールするところからプログラムへの組み込み、実際に起動して正常に動作するかということでした。一応、目的達成です。


関連記事 -iOSアプリ開発事始

NewsSource

0 件のコメント:

コメントを投稿