提前感谢您阅读本文并尝试帮助解决我的问题。
我使用sqlite 3构建数据库,我希望创建一个应用程序,我可以输入产品的信息(应该发送到数据库),然后在UIViewTable中查看。
但是,在创建了所有类和方法之后 - 我的UIViewTable没有显示我数据库中的相关信息 - 它是完全空的吗?
我有一些反馈意见说问题可能在于数据库没有正确连接?
由于我的声誉很低,我只能附加2个链接,所以我试图展示我认为会提供最有用的截图信息。他们处于这个问题的最底层。
以下是我的所有相关文件;
调用sqlite3数据库" StockControl.db"
// Data.h
#import <Foundation/Foundation.h>
@interface Data : NSObject
{
NSString *name;
NSNumber *price;
NSNumber *quantity;
}
@property (strong, nonatomic) NSString *name;
@property (nonatomic, strong) NSNumber *price;
@property (nonatomic, strong) NSNumber *quantity;
-(id)initWithData:(NSString*)n thePrice:(NSNumber*)p theQuantity:(NSNumber*)q;
@end
// Data.m
#import "Data.h"
@implementation Data
@synthesize name, price, quantity;
-(id)initWithData:(NSString*)n thePrice:(NSNumber*)p theQuantity:(NSNumber*)q{
if(self = [super init])
{
[self setName:n];
[self setPrice:p];
[self setQuantity:q];
}
return self;
}
@end
// SiteCell.h
#import <UIKit/UIKit.h>
@interface SiteCell : UITableViewCell
{
UILabel *primaryLabel;
UILabel *secondaryLabel;
UIImageView *myImageView;
}
@property (strong, nonatomic) UILabel *primaryLabel;
@property (strong, nonatomic) UILabel* secondaryLabel;
@property (strong, nonatomic) UIImageView *myImageView;
@end
// SiteCell.m
#import "SiteCell.h"
@implementation SiteCell
@synthesize primaryLabel, secondaryLabel, myImageView;
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self){
primaryLabel = [[UILabel alloc] init];
primaryLabel.textAlignment = NSTextAlignmentLeft;
primaryLabel.font = [UIFont systemFontOfSize:18];
primaryLabel.backgroundColor = [UIColor clearColor];
primaryLabel.textColor = [UIColor whiteColor];
secondaryLabel = [[UILabel alloc] init];
secondaryLabel.textAlignment = NSTextAlignmentLeft;
secondaryLabel.font = [UIFont systemFontOfSize:12];
secondaryLabel.backgroundColor = [UIColor clearColor];
secondaryLabel.textColor = [UIColor whiteColor];
myImageView = [[UIImageView alloc]init];
[self.contentView addSubview:myImageView];
[self.contentView addSubview:primaryLabel];
[self.contentView addSubview:secondaryLabel];
}
return self;
}
-(void)layoutSubviews{
[super layoutSubviews];
CGRect frame;
frame = CGRectMake(5, 5, 40, 40);
myImageView.frame = frame;
frame = CGRectMake(110, 5, 260, 20);
primaryLabel.frame = frame;
frame = CGRectMake(110, 30, 260, 20);
secondaryLabel.frame = frame;
}
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end
// StockPizza.h - 持有UITableView的ViewController
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "SiteCell.h"
@interface StockPizza : UIViewController
<UITableViewDataSource, UITableViewDelegate>
{
AppDelegate *mainDelegate;
}
@property (strong, nonatomic) AppDelegate *mainDelegate;
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@end
// StockPizza.m - 持有UIViewTable的ViewController
#import "StockPizza.h"
#import <UIKit/UIKit.h>
#import "Data.h"
#import "SiteCell.h"
@interface StockPizza ()
@end
@implementation StockPizza
@synthesize mainDelegate;
#pragma mark Table Methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [mainDelegate.stock count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 60;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *cellIdentifier = @"Cell";
SiteCell *cell = (SiteCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil){
cell = [[SiteCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
NSInteger row = indexPath.row;
Data *d = [mainDelegate.stock objectAtIndex:row];
cell.primaryLabel.text = d.name;
cell.secondaryLabel.text = [d.price stringValue];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSInteger row = indexPath.row;
Data *person = [mainDelegate.stock objectAtIndex:row];
NSString *title = person.name;
NSString *msg = [person.quantity stringValue];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:(UIAlertControllerStyleAlert)];
UIAlertAction *ok = [UIAlertAction actionWithTitle:@"Ok" style:(UIAlertActionStyleDefault) handler:nil];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
}
#pragma mark View Methods
- (void)viewDidLoad {
[super viewDidLoad];
self.mainDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
UITabBar *tabBar = self.tabBarController.tabBar;
[tabBar setBarTintColor: [UIColor blackColor]];
[tabBar setTintColor: [UIColor whiteColor]];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
// AppDelegate.h
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
NSString *databaseName;
NSString *databasePath;
NSMutableArray *stock;
}
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) NSString *databaseName;
@property (strong, nonatomic) NSString *databasePath;
@property (strong, nonatomic) NSMutableArray *stock;
-(void)checkAndCreateDatabase;
-(void)readDataFromDatabase;
@end
// AppDelegate.m
#import "AppDelegate.h"
#import <sqlite3.h>
#import "Data.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
@synthesize databaseName, databasePath, stock;
#pragma mark Database Methods
-(void)checkAndCreateDatabase{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:self.databasePath];
if (success)
return;
NSString *dataBasePathFromApp = [[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:self.databaseName];
[fileManager copyItemAtPath:dataBasePathFromApp toPath:self.databasePath error:nil];
}
-(void)readDataFromDatabase{
[self.stock removeAllObjects];
sqlite3 *database;
if (sqlite3_open([self.databasePath UTF8String], &database) == SQLITE_OK) {
char *sqlStatement = "select * from entries";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK){
while(sqlite3_step(compiledStatement) == SQLITE_ROW){
char *n = (char*)sqlite3_column_text(compiledStatement, 1);
float p = sqlite3_column_int(compiledStatement, 2);
int q = sqlite3_column_int(compiledStatement, 3);
NSString *name = [NSString stringWithUTF8String:n];
NSNumber *price = [NSNumber numberWithFloat:p];
NSNumber *quantity = [NSNumber numberWithInt:q];
Data *data = [[Data alloc] initWithData:name thePrice:price theQuantity:quantity];
[self.stock addObject:data];
}
}
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
#pragma mark App Methods
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.stock = [[NSMutableArray alloc]init];
self.databaseName = @"StockControl.db";
NSArray * documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDir = [documentPaths objectAtIndex:0];
self.databasePath = [documentsDir stringByAppendingPathComponent: self.databaseName];
[self checkAndCreateDatabase];
[self readDataFromDatabase];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end
截图
答案 0 :(得分:0)
我认为 Mridul 是正确的,而您只是错过了一个插座,但您可以采取一些措施来帮助自己完成调试过程。
也许您已经确认您实际上正在获得您期望的数据 - 但您还没有说过您已经检查过了。我认为总是值得进行一些调试检查或打印语句,以确保您实际获得所需的数据。
另一件事是,看起来您将为每个表视图分别创建单独的类 - 您可以通过使用一个表示类来处理所有的tableview开销来简化操作,并简单地加载数据你需要从5个不同的来源。
答案 1 :(得分:0)
行:
float p = sqlite3_column_int(compiledStatement,2);
它应该读取float p = sqlite3_column_float(compiledStatement,2);
答案 2 :(得分:0)
感谢你们的努力!
原来这是我自己的错,因为数据库中的表被命名为“stock”而我的sqlStatement试图调用名为entries的表。更改了这个错误后,它显示为我想要的!
我为此道歉,但我感谢你的洞察力。