Quantcast
Channel: パークのソフトウエア開発者ブログ|ICT技術(Java・Android・iPhone・C・Ruby)なら株式会社パークにお任せください
Viewing all articles
Browse latest Browse all 138

[iOS] iPhoneアプリで データベース(CoreData)を作成する その2

$
0
0

こんにちわ。ゆんぼうです。

前回の続きで、今回はCoreDataを用いて、データベース検索を行います。

今回の開発環境は以下の通りです。
・OS X v10.9.3
・Xcode v5.1.1

前回作成したDAOクラス SampleEntityDAO に
名前と年齢で検索を行うインスタンスメソッドを追加します。


- (NSArray *)getSampleEntityItemList:(NSString *)name age:(NSNumber *)age
{
AppDelegate *appDeletage = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *managedObjectContext = [appDeletage managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];

NSEntityDescription *entityDes = [NSEntityDescription entityForName:@"SampleEntity" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entityDes];

if(nil != name || nil != age){
NSMutableArray *predicateCommandArray = [[NSMutableArray alloc]init];

if(nil != name){
NSString *nameWord = [NSString stringWithFormat:@"*%@*",name];
NSPredicate *predicate = [NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionForKeyPath:@"name"] rightExpression:[NSExpression expressionForConstantValue:nameWord] modifier:NSDirectPredicateModifier type:NSLikePredicateOperatorType options:0];
[predicateCommandArray addObject:predicate];
}

if(nil != age){
NSString *predicateCommand = [NSString stringWithFormat:@"(age = %@)",age];
NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateCommand];
[predicateCommandArray addObject:predicate];
}

if(nil != predicateCommandArray){
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicateCommandArray];
[fetchRequest setPredicate:predicate];
}
}

NSSortDescriptor *sortDes = [[NSSortDescriptor alloc]initWithKey:@"age" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sortDes, nil];
[fetchRequest setSortDescriptors:sortDescriptors];

NSError *error = nil;
NSArray *itemList = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
if(nil != error){
NSLog(@"SampleEntityDAO#getSampleEntityItemList error %@, %@", error, [error userInfo]);
}
return itemList;
}


検索条件は、NSPredicateクラスを使用します。
複数ある場合は、NSPredicate オブジェクトを配列にして、
NSCompoundPredicate クラスを用いて条件を纏めます。

ここでは、名前と年齢の検索条件の NSPredicate オブジェクトを作成して、
andPredicateWithSubpredicates クラスメソッドを用いて、AND条件で纏めています。

まず、年齢の検索条件を見てみると
文字列の条件式 「age = %@」を predicateWithFormat クラスメソッドで
NSPredicate オブジェクトを作成します。

次に、名前の検索条件を見てみると、
下記のように文字列の条件式「name LIKE '*%@*'」で実装することもできますが、
ここでは実装しておりません。

NSString *predicateCommand = [NSString stringWithFormat:@"name LIKE '*%@*'",name];

なぜならば、悪意を持ったユーザーがいて、
この名前の値にSQL文を指定すると、そのSQL文が実行されてしまいます。
このSQL文を利用して、データベースを不正に操作する攻撃をSQL Injectionといいます。

SQL Injection を回避するため、
「name LIKE '*%@*'」のような文字列で条件式を作成するのではなく、
NSComparisonPredicate クラスを用いて、条件式を作成します。


この検索条件の呼び出し側を実装します。
1回目は、「お」を含む名前でデータベースを検索します。
2回目は、年齢が29でデータベースを検索します。
3回目は、「さ」を含む名前、かつ年齢が29でデータベースを検索します。



NSLog(@"---------------------------------------");
NSArray *item2List = [dao getSampleEntityItemList:@"お" age:nil];
for(SampleEntity *item in item2List) {
NSLog(@"name:%@, age:%@",item.name, item.age);
}
NSLog(@"---------------------------------------");
NSArray *item3List = [dao getSampleEntityItemList:nil age:[NSNumber numberWithInt:29]];
for(SampleEntity *item in item3List) {
NSLog(@"name:%@, age:%@",item.name, item.age);
}
NSLog(@"---------------------------------------");
NSArray *item4List = [dao getSampleEntityItemList:@"さ" age:[NSNumber numberWithInt:29]];
for(SampleEntity *item in item3List) {
NSLog(@"name:%@, age:%@",item.name, item.age);
}
NSLog(@"---------------------------------------");


実行すると下記の内容になります。

出力結果
---------------------------------------
name:しおぼう, age:40
---------------------------------------
name:あさぼう, age:29
---------------------------------------
name:あさぼう, age:29
---------------------------------------

以上です。

Viewing all articles
Browse latest Browse all 138

Trending Articles