ネットワーク経由でxmlフィードを取得し、それを解析してsqlite dbに保存し、ユーザーに表示するiosアプリを作成しています。
私の xml フィードの長さは約 1700 行です: http://www.paulshin.ca/yunatube/res/en.xml
これが私のアプリの動作方法です。
- ユーザーがアプリを実行します
- アプリはネットワーク経由で xml を取得します
- xmlパーサーを使用してxmlオブジェクトをループし、各アイテムをsqlite dbに保存します
- 完了したら、テーブルビューにアイテムを表示します..
ただし、ステップ 2 には 5 秒もかからず、ステップ 3 には約 20 秒かかることがわかりました。その理由は、各項目をデータベースに格納するのに時間がかかるためです。
以下は、ステップ3で使用するものです。
TBXMLElement *elemRoot = nil, *youtube = nil, *maincateg = nil, *categ = nil, *clip = nil;
// maincatg
NSString *mcTitle = nil;
// catge
NSString *cTitle = nil;
// clip
NSString *title = nil, *url = nil, *note = nil;
elemRoot = tbxml.rootXMLElement;
if (elemRoot) {
youtube = [TBXML childElementNamed:@"youtube" parentElement:elemRoot];
maincateg = [TBXML childElementNamed:@"maincateg" parentElement:youtube];
while (maincateg) {
mcTitle = [TBXML valueOfAttributeNamed:@"type" forElement:maincateg];
categ = [TBXML childElementNamed:@"category" parentElement:maincateg];
while (categ) {
cTitle = [TBXML valueOfAttributeNamed:@"title" forElement:categ];
clip = [TBXML childElementNamed:@"clip" parentElement:categ];
while (clip) {
title = [TBXML valueOfAttributeNamed:@"title" forElement:clip];
url = [TBXML valueOfAttributeNamed:@"url" forElement:clip];
note = [TBXML valueOfAttributeNamed:@"note" forElement:clip];
//TODO
if (![note isEqualToString:@"0"]) {
// save pared data to persistent
title = [title stringByReplacingOccurrencesOfString:@"&"
withString:@"&"];
cTitle = [cTitle stringByReplacingOccurrencesOfString:@"&"
withString:@"&"];
DatabaseManager *database = [DatabaseManager getInstance];
**[database addDataToTable:mcTitle title:title url:url category:cTitle];**
}
clip = clip -> nextSibling;
}
categ = categ -> nextSibling;
}
maincateg = maincateg -> nextSibling;
}
ご覧のとおり、いくつかのネストされたループがあり、addDataToTAble(); を呼び出して各アイテムを DB に保存します。* で行を削除すると(つまり、各ループの後にアイテムを保存しない場合)、非常に高速に動作します。しかし、*の行をそのままにしておくと、とても時間がかかります。
この関数は次のとおりです。
-(void) addDataToTable: (NSString*)table
title: (NSString*)title
url:(NSString*)url
category:(NSString*)category
{
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_yunatubeDB) == SQLITE_OK) {
NSString *insertSQL = [NSString stringWithFormat: @"INSERT INTO %@ (TITLE, URL, CATEGORY) VALUES (\"%@\", \"%@\", \"%@\")", table, title, url, category];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(_yunatubeDB, insert_stmt,
-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE) {
// NSLog(@"Successfully added to DB");
} else {
NSLog(@"Failed to add data to DB");
}
sqlite3_finalize(statement);
sqlite3_close(_yunatubeDB);
}
}
この機能は、アイテムごとの収納に時間がかかるようで、収納時間が積み重なるため、最終的には最大20秒かかる。Android にも同様のアルゴリズムを使用していますが、高速に動作しますが、ios でなぜそんなに時間がかかるのかわかりません。この処理時間は、アプリ ストアでのアプリ レビューに悪影響を及ぼすのではないかと思います。私はAndroidでも同様の方法を使用していますが、そこでは非常に高速に動作します..4秒未満です。iOSでなぜそんなに時間がかかるのかわかりません。私は何か間違っていますか?
どんな助けでも大歓迎です!