Persistence(11)〜SQLite3への保存(5)

2011. 03. 08
3)applicationWillResignActive:の編集

applicationWillResignActive:では、テキストフィールドのデータを取得し、SQLiteのテーブルに入力し、データベースファイルを保存します。

最初にsqlite3のオブジェクトdatabaseを作成し、4つのテキストフィールドからデータを取得するためのforループを作成します。

データの取得は、まずinitWithFormat:メソッドでテキストフィールドのプロパティ名field*を作成し、NSString文字列のfieldNameとして保持します。

そして『Persistence(10)〜SQLite3への保存(4)』で説明したviewDidLoadと同様に、fieldNameをキーとしてvalueForKey:メソッドを呼び出し、UITextFieldのインスタンスfieldとします。

次にinitWithFormat:メソッドで、テーブルにデータを挿入/置換を行うSQLステートメントを作成します。

INSERTステートメントはテーブルに単一行を作成するもので、REPLACEステートメントは既存の行を置換します。

REPLACEステートメントは後方互換のため単独での利用もできますが、INSERTステートメントと合わせて『INSERT OR REPLACE』として使用することが推奨されています。

今回のINSERTステートメントは、VALUESキーワードを使用して列リストに値を挿入します。

『INSERT OR REPLACE INTO FIELDS (ROW, FIELD_DATA) VALUES (%d, '%@');』の場合、テーブルFIELDS内にある列ROWと列FIELD_DATAにそれぞれ整数(forループ変数のi)と文字列(テキストフィールドのテキストfield.text)を挿入ないし置換を行うことになります。

データの挿入/置換を行うNSStringオブジェクトのSQLステートメントupdateを使って、sqlite3_exec()内でUTF8StringメソッドでC文字列に変換して実行されます。

挿入/置換に失敗した場合、NSAssert1でアサーションを生成し、sqlite3_free()でエラーメッセージの解放をしています。

このsqlite3_free()での解放ですが、viewDidLoadでのアサーションの時は行っていませんし、iPhone OS 3.x版iOS 4.x版のサンプルコードでは記述されていないので不要なのかもしれません。

4つのテキストフィールドの文字列を行に納めたら、sqlite3_close()でsqlite3オブジェクトを破棄し、データベースファイルを閉じます。


●実行

Persistence(9)〜SQLite3への保存(3)』で説明しましたが、この旧版のサンプルコードはデータベースファイルの読み込みはできますが、書き込みはできません。

理由の1つは、applicationWillResignActive:のINSERTステートメントで文字列を挿入する際、(SQLステートメントはC文字列にする必要があるのに)変数をC文字列に変換していないためです。

実際にこのサンプルコードを実行してアプリケーションを非アクティブにすると、デバッガコンソールに『Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error updating tables: 8”ˇøD6'』というテーブル更新時のアサーションが出力されます。

このエラーはテキストフィールドの文字列field.textをUTF8StringメソッドでC文字列に変換すると解消されます。
(太字が修正した部分)

- (void)applicationWillResignActive:(UIApplication *)application {
    sqlite3 *database;
    for (int i = 1; i <= 4; i++) {
        NSString *fieldName = [[NSString alloc] initWithFormat:@"field%d", i];
        UITextField *field = [self valueForKey:fieldName];
        [fieldName release];

        NSString *update = [[NSString alloc]
        initWithFormat:@"INSERT OR REPLACE INTO FIELDS (ROW, FIELD_DATA)
        VALUES (%d, '%@');", i, [field.text UTF8String]];
        char *errorMsg;
        if (sqlite3_exec (database, [update UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK) {
            NSAssert1(0, @"Error updating tables: %s", errorMsg);
            sqlite3_free(errorMsg);
        }
    }
    sqlite3_close(database);
}

2031.jpg

この修正で例外エラーは発生しなくなりますが、SQLデータベースファイルへの保存はできません。

その理由は、旧版がINSERTステートメントでの変数の組み込みをNSStringオブジェクトで行っているのに対し、(正常に書き込みができる)iPhone OS 3.x版iOS 4.x版のサンプルコードsqlite3_bind()を使用していることに起因していると思われます。



参考文献

はじめてのiPhone3プログラミングはじめてのiPhone3プログラミング
(2009/12/17)
Dave Mark、Jeff LaMarche 他

商品詳細を見る

Beginning Ios 6 Development: Exploring the Ios SdkBeginning Ios 6 Development: Exploring the Ios Sdk
(2012/12/26)
David Mark、Jack Nutting 他

商品詳細を見る






Bose Solo 5 TV sound system
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
07 | 2017/08 | 09
Sun Mon Tue Wed Thu Fri Sat
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

ボーズ・オンラインストア
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR