開発」カテゴリーアーカイブ

アプリ開発雑記[10]

2週間ぶりのアプリ開発雑記です。開発作業もこの日曜日に2週間ぶりにやりました。
まずは前回のエントリで挙げた今後の課題を再掲します。新しい課題も追加しました。

  1. SQLite(データベースの作成、データの登録・抽出)
  2. 画面の切り替えをかっこよく
  3. マルチタッチの使い方
  4. TabBarでタブを選んだ時にタブバーを表示させない。
  5. テーブルのソート
  6. 列を複数持つテーブルを作る
今回は、5と6をやっつけました。


<テーブルのソートが解決>

ソートがなんともあっさり解決しました。NSDictonaryとか小難しいこと言っていましたが、SQLiteでデータを読み出す時にQueryでソートしてしまえば何の苦労もなかったです。サンプルコードのSQLitebooksで言えば、


const char *sql = "SELECT title FROM book WHERE pk=?";
const char *sql = "SELECT title FROM book WHERE pk=?
ORDER BY title";

とします。ちなみに、新しいデータを追加した場合はソートされたデータの最後尾に新しいデータが追加されます。サンプルコードでは起動時に一度データを抽出してテーブルを作っていて、あとの処理では並びかえをしていないためです。追加後も並び替えたいという場合は、テーブルのデータソースとなっている配列を破棄してもう一度新しいQueryで読み出し直すか、上記のNSDictionaryが必要ということになります。

今のところは目標が最低限達成されたので次の課題に移ることにしました。


<列を複数持つテーブルを作る>

SQLitebooksをベースに作ったオリジナルDBを使ったプログラムで、SQLitebooksのように1行にひとつの情報だけでなく、1行に複数の列を持たせて多くの情報を表示させるように改変しました。参考にしたサンプルコードは、「TableViewCellSubviews」です。

1行の場合は、cellForRowIndexPath内でUITableViewCellを生成して、そのセルに、

cell.text = book.title;

のようにcell内に表示するテキストを指定していました。複数の列を持たせる場合は、ここで行の中の子セルを作って挙げる処理を記述します。サンプルコード「TableViewCellSubviews」では、tableviewCellWithReuseIdentifierというメソッドを定義してそれを呼び出す格好で、子セルを生成しています。ここの記述はdefineマクロを使って、サイズを制御しています。お絵描きしているだけなので難しい記述ではありません。子セルはUILableやUIImageViewの箱を載せることで実現し、defineマクロで定義されたTAGを各箱に与えて(TIME_TAGなど)、各箱の中身へアクセスします。こんな感じ。

label = (UILabel *)[cell viewWithTag:DATE_TAG];

label.text = [dateFormatter stringFromDate:training.date];

cell.text = book.title の部分がcell内の各箱(LabelやImageView)になるわけです。サンプルコード「TableViewCellSubviews」では、別メソッドconfigureCellにこの処理を定義しています。

さて、SQLitebooksを改造したプログラムに、これらの処理を書き加えることで1行を2列にしてみましたが、実は最初はうまくいきませんでした。作った箱に表示したいデータが反映されていないんです。そして、その行を選択してDetailViewを表示させると中身はちゃんとある。さらには、DetailViewからMasterViewControllerのビュー(一覧)に戻ってくると、さっきまで表示されていなかったデータがちゃんと入っている。そんなバグを埋め込んでしまいました。

その原因は、SQLitebooksの起動時の処理にありました。

実はSQLitebooksの起動時のqueryでは、表示させる必要最低限のデータ、すなわち、"title"しか読み込んでないのでした。なので、箱を作っても入れるデータを読み込んでいないので、表示されないのは当たり前でした。行が選択されDetailViewを表示するときになって、残りの情報(copyright, author)を読み出すという方法をとられています。こうすることで、起動時に余計な処理をしないようにしているんですね。それはそれで勉強になりました。


<今後の課題>


芋づる式にいろいろ課題が出てきます。たまる一方。

  1. SQLite(データベースの作成、データの登録・抽出)
  2. 画面の切り替えをかっこよく
  3. マルチタッチの使い方
  4. TabBarでタブを選んだ時にタブバーを表示させない。
  5. テーブルのソート
  6. 列を複数持つテーブルを作る
  7. ダイアログ表示
  8. 起動時のSplash画面表示

まもなく、iPhone3.0へのバージョンアップが来ると予想されていますね。
当初は3.0公開前にひとつアプリ出してやるぜーと思ってましたけど、このペースでは全然無理でしたー(’д`;)ノもっとがんばらなきゃ。

アプリ開発雑記[9]

今週はダウンしてたのと、良質なゲームアプリStoneLoopsにはまったのとで、あんまりアプリ開発のお勉強は進んでいませんが、週に一度くらいは現状と今後の課題をまとめて置きたいと思います。

前回記事アプリ開発雑記[8]で挙げていた課題のうち、

  1. SQLite(データベースの作成、データの登録・抽出)
  2. 画面の切り替えをかっこよく
  3. マルチタッチの使い方
  4. TabBarでタブを選んだ時にタブバーを表示させない。
SQLiteはサンプルコードをベースになんとか操れるようになりました。Google CodeにあるようなObjective-C用のSQLite access libraryは使用しませんでした、逆に敷居高そうで。サンプルコードの解読には、SQLite本家サイトのFuction Listが一番役に立ちました。

http://www.sqlite.org/c3ref/funclist.html

sqlite3_prepareでqueryを作って、queryの"?"の数だけsqlite3_bindで引数を与えて、sqlite3_stepで実行という流れでした。以下のリンク先で検討されているような高速化云々は今のところノータッチです。

というわけで、SQLiteを操ってテーブルへのデータの追加ができるようになったのですが、ここで新しい課題が発生。テーブルのソートです。サンプルコードの"TheElement"を見る限りではNSDisctionaryとNSSortDescriptorが鍵のようです。まだアプリ完成への道は遠いな(;’д`)

今後の課題を再掲。

  1. SQLite(データベースの作成、データの登録・抽出)
  2. 画面の切り替えをかっこよく
  3. マルチタッチの使い方
  4. TabBarでタブを選んだ時にタブバーを表示させない。
  5. テーブルのソート
たまに他のアプリを触ってUIを参考にしながら、あるいはゲームで息抜きしながら、ぼちぼち進めます。

アプリ開発雑記[8]

平日はあんまり進められませんでした。今抱えている課題は以下のようなもの。

  1. SQLite(データベースの作成、データの登録・抽出)
  2. 画面の切り替えをかっこよく
  3. マルチタッチの扱い方
  4. TabBarでタブを選んだ時にタブバーを表示させない。("TheElement"で実現されている)

ここ最近やったこと。

  1. moto_makaさんのチュートリアルを参考に、タイマーと画像表示をお試し。
  2. SQLiteの参考サイト集め
    • ゲームつくろー>SQLite超入門
      • http://marupeke296.com/SQLITE_main.html
    • MASATOの開発日記>SQLite性能評価
      • http://www.sutosoft.com/room/archives/000454.html
    • Google Code > pldatabase (SQLite access library for Objective-C)
      • http://code.google.com/p/pldatabase/
    • iPhoneディベロッパーのためのSQLite12の情報源
      • http://blog.sohaya.com/2008/11/13/iphoneデベロッパーのための12のsqlite情報源/
ようは全然進んでないということです(汗)
がんばりまする。

アプリ開発雑記[7] SQLiteBooks その2

前回の続きです。
TabBarの中に、サンプルコード"SQLiteBooks"を埋め込んだ手順をまとめてます。

(4) やったこと(後編)

(4-1) Xcodeで作業します。SQLiteBooksからコピーしてきたコードに手を加えます。まずはAppDelegate.hから。プロジェクトに元々あったHogehogeAppDelegate
を使用するよりソースコードの編集量が少なくて済むのでこちらを使います。ハイライトしている部分が編集した部分で、コメントアウトされているのが変更前です。

UIApplicationDelegateプロトコルとUITabBarControllerDelegateプロトコルに従います。もとのAppDelegateがなぜにUIApplicationDelegateに準拠してないのかは謎。他の変更はもとのソースがNavigationControllerを持っているのをTabBarControllerに変えるのに伴ったものです。実に簡単な変更です。


#import <UIKit/UIKit.h>
// This includes the header for the SQLite library.
#import <sqlite3.h>

// Inform the compiler that the following classes are defined in the project:
@class Book, MasterViewController, DetailViewController, AddViewController, EditingViewController;

//@interface AppDelegate : NSObject {
@interface AppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
    IBOutlet UIWindow *window;
    //IBOutlet UINavigationController *navigationController;

  IBOutlet UITabBarController *tabBarController;
    NSMutableArray *books;
    // Opaque reference to the SQLite database.
    sqlite3 *database;
}

@property (nonatomic, retain) UIWindow *window;
//@property (nonatomic, retain) UINavigationController *navigationController;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;

// Makes the main array of book objects available to other objects in the application.
@property (nonatomic, retain) NSMutableArray *books;

// Removes a book from the array of books, and also deletes it from the database. There is no undo.
– (IBAction)removeBook:(Book *)book;
// Creates a new book object with default data. 
– (void)addBook:(Book *)book;

 

@end



(4-2) 次はAppDelegate.m。長いソースですが変更箇所はわずかです。ここもTabBarControllerに絡む変更のみ。


#import "AppDelegate.h"
#import "MasterViewController.h"
#import "DetailViewController.h"
#import "AddViewController.h"
#import "EditingViewController.h"
#import "Book.h"

// Private interface for AppDelegate – internal only methods.
@interface AppDelegate (Private)
– (void)createEditableCopyOfDatabaseIfNeeded;
– (void)initializeDatabase;
@end

@implementation AppDelegate

// Instruct the compiler to create accessor methods for the property. It will use the internal 
// variable with the same name for storage.
//@synthesize books, window, navigationController;
@synthesize books, window, tabBarController;

– (void)applicationDidFinishLaunching:(UIApplication *)application {
    // The application ships with a default database in its bundle. If anything in the application
    // bundle is altered, the code sign will fail. We want the database to be editable by users, 
    // so we need to create a copy of it in the application's Documents directory.     
    [self createEditableCopyOfDatabaseIfNeeded];
    // Call internal method to initialize database connection
    [self initializeDatabase];
    // Add the navigation controller's view to the window
    //[window addSubview:navigationController.view];
[window addSubview:tabBarController.view];

    [window makeKeyAndVisible];
}

– (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    // "dehydrate" all data objects – flushes changes back to the database, removes objects from memory
    [books makeObjectsPerformSelector:@selector(dehydrate)];
}

– (void)dealloc {
    //[navigationController release];   
    [tabBarController release];   
[window release];
    [books release];
    [super dealloc];
}

(中略)

@end



(4-3) 次にもうひとつだけInterface Builderで作業をします。ApplicationDelegateになるクラスをもともとプロジェクト作成時にデフォルトで生成されていたクラスからAppDelegateクラスに変更したので、それを教えてあげなければなりません。本当は昨日加えた変更とまとめてやってしまって良いのですが、昨日書くのを忘れていたのでここで書きます(汗)。まぁ、今日関連する作業をXcodeでやった後なので、あながち悪くないのですが。

TableTry_MainWindowxib2.png
<fig. 5>
(4-4) 最後にビルドですが、もうひとつ、SQLiteを使用するには専用のフレームワークを読み込まなければなりません。グループとファイルの下のFrameworksを右クリックして”追加”から”既存のフレームワーク”を選び、数あるフレームワークの中から、libsqlite3.0.dylibを追加します。
(4-5) ビルドして実行!で完成です。わたしは実機にインストールしてます。実機だと達成感があります。
IMG_0034.PNG
<fig. 6>
(5) 最後に
今日、なにげにもう一度なにも見ずに最初からやってみましたが、またひっかかりました。ひっかかりやすいポイントをあげるならば以下の3点でしょうか。
  • NavigationViewController.xibでFile's OwnerにTable Viewを接続し忘れる
  • ApplicationDelegateをMainWindow.xibで古いままにしている(今回追記したポイントw)
  • libsqlite3.0.dylibフレームワークを追加し忘れている

3つ目はコンパイル時にエラーが出るのでわかりますが、上2つはでません。アプリの動作が止まっ
たらコンソールで確認するとヒントがでてます。

以上!

<<免責事項>>
ここに紹介した方法を参考にしてアプリケーション開発を行ったことで発生しうる如何なる問題についても、当ブログ管理者は一切責任を負いません。

アプリ開発雑記[6] SQLiteBooks(その1)

今日は、前回記事までの成果であるNavigation ControllerをTab Bar内のタブに実装したものの発展系として、Navigation Controller以下にサンプルコード"SQLiteBooks"を埋め込むことにトライしました。作りたいアプリではユーザーが入力したデータを追加したり、削除したりする機能がある予定でして、SQLiteが唯一の方策かどうかはさっぱりわかりませんが、サンプルコードにあるようなデータの管理をイメージしていたので取り入れてみることにしました。備忘のために、作業内容+αをまとめます!
前回記事:アプリ開発雑記[5] Navigation Controller + TabBar その3
続きを読む