我正在开发一个使用ASIHTTPRequest显示各种提要的应用程序。用户可以将存储在SQLite数据库中的新源添加到应用中。目前,我在FeedsViewController的viewDidLoad方法中将提要提供给应用程序,但我希望能够检索包含源链接的数据并将其存储在数组中以使用它。
目前,该应用看起来像在当前代码的下方:
- (void)viewDidLoad
{
[super viewDidLoad];
self.title =@"Lajmet";
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
//self.tabBarController.tabBar.tintColor = [UIColor blackColor];
self.allEntries = [NSMutableArray array];
self.queue = [[NSOperationQueue alloc] init];
self.feeds = [NSMutableArray arrayWithObjects:@"http://pcworld.al/feed",@"http://geek.com/feed", @"http://feeds.feedburner.com/Mobilecrunch",@"http://zeri.info/rss/rss-5.xml",
nil];
[self.tableView reloadData];
[self refresh];
}
我的视图包含添加和删除新源的函数(AddSourcesViewController),看起来像this,下面是代码:
- (void)viewDidLoad
{
[super viewDidLoad];
arrayOfSource = [[NSMutableArray alloc]init];
[[self myTableView]setDelegate:self];
[[self myTableView]setDataSource:self];
[self createOrOpenDB];
// Display sources in table view
sqlite3_stmt *statement;
if (sqlite3_open([dbPathString UTF8String], &sourceDB)==SQLITE_OK) {
[arrayOfSource removeAllObjects];
NSString *querySql = [NSString stringWithFormat:@"SELECT * FROM SOURCES"];
const char* query_sql = [querySql UTF8String];
if (sqlite3_prepare(sourceDB, query_sql, -1, &statement, NULL)==SQLITE_OK) {
while (sqlite3_step(statement)==SQLITE_ROW) {
NSString *name = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 1)];
NSString *link = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 2)];
NSString *category = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 3)];
SourceDB *source = [[SourceDB alloc]init];
[source setName:name];
[source setLink:link];
[source setCategory:category];
[arrayOfSource addObject:source];
}
}
}
[[self myTableView]reloadData];
}
- (void)createOrOpenDB
{
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [path objectAtIndex:0];
dbPathString = [docPath stringByAppendingPathComponent:@"sources.db"];
char *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:dbPathString]) {
const char *dbPath = [dbPathString UTF8String];
//creat db here
if (sqlite3_open(dbPath, &sourceDB)==SQLITE_OK) {
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS SOURCES (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, LINK TEXT, CATEGORY TEXT)";
sqlite3_exec(sourceDB, sql_stmt, NULL, NULL, &error);
sqlite3_close(sourceDB);
}
}
}
- (IBAction)addSourceButton:(id)sender
{
char *error;
if (sqlite3_open([dbPathString UTF8String], &sourceDB)==SQLITE_OK) {
NSString *inserStmt = [NSString stringWithFormat:@"INSERT INTO SOURCES(NAME,LINK,CATEGORY) values ('%s', '%s','%s')",[self.nameField.text UTF8String], [self.linkField.text UTF8String],[self.categoryField.text UTF8String]];
const char *insert_stmt = [inserStmt UTF8String];
if (sqlite3_exec(sourceDB, insert_stmt, NULL, NULL, &error)==SQLITE_OK) {
NSLog(@"Source added");
SourceDB *source = [[SourceDB alloc]init];
[source setName:self.nameField.text];
[source setLink:self.linkField.text];
[source setCategory:self.categoryField.text];
[arrayOfSource addObject:source];
}
sqlite3_close(sourceDB);
}
}
- (IBAction)deleteSourceButton:(id)sender
{
[[self myTableView]setEditing:!self.myTableView.editing animated:YES];
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
SourceDB *s = [arrayOfSource objectAtIndex:indexPath.row];
[self deleteData:[NSString stringWithFormat:@"Delete from sources where name is '%s'", [s.name UTF8String]]];
[arrayOfSource removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
-(void)deleteData:(NSString *)deleteQuery
{
char *error;
if (sqlite3_exec(sourceDB, [deleteQuery UTF8String], NULL, NULL, &error)==SQLITE_OK) {
NSLog(@"Source deleted");
}
}
- (IBAction)showSourceButton:(id)sender
{
sqlite3_stmt *statement;
if (sqlite3_open([dbPathString UTF8String], &sourceDB)==SQLITE_OK) {
[arrayOfSource removeAllObjects];
NSString *querySql = [NSString stringWithFormat:@"SELECT * FROM SOURCES"];
const char* query_sql = [querySql UTF8String];
if (sqlite3_prepare(sourceDB, query_sql, -1, &statement, NULL)==SQLITE_OK) {
while (sqlite3_step(statement)==SQLITE_ROW) {
NSString *name = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 1)];
NSString *link = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 2)];
NSString *category = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(statement, 3)];
SourceDB *source = [[SourceDB alloc]init];
[source setName:name];
[source setLink:link];
[source setCategory:category];
[arrayOfSource addObject:source];
}
}
}
[[self myTableView]reloadData];
}
现在,我在FeedsViewConrtoller中创建了一个方法:
-(void)ReadData
{
[self createOrOpenDB];
feedsArray = [[NSMutableArray alloc] init];
const char *dbPath = [dbPathString UTF8String];
if (sqlite3_open(dbPath, &sourceDB)==SQLITE_OK)
{
const char *sqlstmt = "SELECT LINK FROM SOURCES";
sqlite3_stmt *completedstmt;
if (sqlite3_prepare_v2(sourceDB, sqlstmt, -1, &completedstmt, NULL)==SQLITE_OK)
{
while(sqlite3_step(completedstmt)==SQLITE_ROW)
{
NSString *link = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(completedstmt, 2)];
SourceDB *source = [[SourceDB alloc]init];
[source setLink:link];
[feedsArray addObject:link];
}
}
}
}
当我改变
self.feeds = [NSMutableArray arrayWithObjects:@"http://pcworld.al/feed",@"http://geek.com/feed", @"http://feeds.feedburner.com/Mobilecrunch",@"http://zeri.info/rss/rss-5.xml",
nil];
至:
self.feeds = [NSMutableArray arrayWithArray:feedsArray];
我收到以下错误:
2013-08-14 15:03:55.328 ShqipCom [3128:c07](空)
我在这里做错了什么?
非常感谢!
格兰尼特
最佳答案
在ReadData
中,您将返回一列,但随后使用以下命令检索第三列:
NSString *link = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(completedstmt, 2)];
应该是:
NSString *link = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(completedstmt, 0)];
还有其他一些想法:
if (sqlite3_prepare_v2(sourceDB, sqlstmt, -1, &completedstmt, NULL)==SQLITE_OK
{
while(sqlite3_step(completedstmt)==SQLITE_ROW)
{
NSString *link = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(completedstmt, 2)];
SourceDB *source = [[SourceDB alloc]init];
[source setLink:link];
[feedsArray addObject:link];
}
}
而您可能想要以下内容:
if (sqlite3_prepare_v2(sourceDB, sqlstmt, -1, &completedstmt, NULL)!=SQLITE_OK
{
NSLog(@"%s: prepare error: %s", __FUNCTION__, sqlite3_errmsg(sourceDB));
return;
}
int rc;
while ((rc = sqlite3_step(completedstmt)) == SQLITE_ROW)
{
NSString *link = [[NSString alloc]initWithUTF8String:(const char *)sqlite3_column_text(completedstmt, 2)];
SourceDB *source = [[SourceDB alloc]init];
[source setLink:link];
[feedsArray addObject:link];
}
if (rc != SQLITE_DONE)
{
NSLog(@"%s: step error: %s", __FUNCTION__, sqlite3_errmsg(sourceDB));
return;
}
您确实应该检查每个SQLite调用的结果,如果未成功,则报告错误消息。否则,你会失明。
?
占位符,您将使用sqlite3_prepare_v2
准备SQL,然后使用sqlite3_bind_text
进行绑定将文本值输入到这些占位符,然后输入sqlite3_step
并确认SQLITE_DONE
的返回值。 注意,检查每个
sqlite3_xxx
函数调用的返回结果并进行所有必要的sqlite3_bind_xxx
调用有点麻烦。在您的下一个项目中,如果要简化SQLite代码,则可能要考虑使用FMDB。