2013-08-16 18 views
1

我在服务器中存储了一些图像。我使用JSON从服务器获取远程数据。当我在本地数据库中存储图像时,它正在工作。当我使用json url时,它不起作用。我得到EXC_BAD_ACCESS错误。图像没有从数据库中提取

代码:

Mysof.h文件:

@interface Mysof : NSObject{ 
    NSInteger sofaId; 
    NSString *sofa; 
    NSString *rating; 
    UIImage *photo; 
} 

@property (nonatomic,retain)NSString *sofa; 
@property (nonatomic, assign) NSInteger sofaId; 
@property (nonatomic, retain)NSString *rating; 
@property (nonatomic, retain) UIImage *photo; 

@end 

Mysof.m文件:

@implementation Mysof 

@synthesize sofId; 
@synthesize sofa; 
@synthesize rating; 
@synthesize photo; 

@end 

Sofalistsql.h文件:

@interface Sofalistsql : NSObject 

{ 
    sqlite3 *db; 
} 

- (NSMutableArray *) getMysofas; 

@end 

.m文件:

@implementation Sofalistsql 

    - (NSMutableArray *) getMysofas{ 


    NSMutableArray *sofArray = [[NSMutableArray alloc] init]; 

    NSFileManager *fileMgr = [NSFileManager defaultManager]; 
    NSError *err; 

    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Empty" ofType:@"sqlite"]; 
    //NSLog(@"bundlePath %@", bundlePath); 


    //call update function to check any data updated, 
    //if there is a version difference 
    //update the data base with all the required fileds. 



    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    //NSLog(@"docs dir is %@", documentsDirectory); 

    NSString *appFile = [documentsDirectory stringByAppendingPathComponent:@"App6.sqlite"]; 

    [fileMgr copyItemAtPath:bundlePath toPath:appFile error:&err]; 


    NSURL *URL = [NSURL URLWithString:@"http://server.net/projects/mobile/jsonstring.php"]; 

    NSLog(@"URL is %@", URL); 


    NSError *error; 
    NSString *stringFromFileAtURL = [[NSString alloc] 
    initWithContentsOfURL:URL 
    encoding:NSUTF8StringEncoding 
    error:&error]; 

    //NSLog(@"response is %@", stringFromFileAtURL); 

    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"App6.sqlite"]; 


    NSArray *userData = [stringFromFileAtURL JSONValue]; 

    // NSArray *skarray = [[NSArray alloc]init]; 



    NSLog(@"userdata is %@", userData); 

    // int i = 0; 
    BOOL notExist = TRUE; 


    for (NSArray *skarray in userData) { 

    for (NSDictionary *tuser in skarray) { 


      //if already exists in data base id then overwrite the name 

     if (sqlite3_open([path UTF8String], &db) == SQLITE_OK) { 


     const char *sql = [[NSString stringWithFormat:@"SELECT id FROM categories where id = '%@'",[tuser objectForKey:@"id"]] cStringUsingEncoding:NSUTF8StringEncoding];  

    //NSLog(@"check stmt is %s", sql); 

    sqlite3_stmt *sqlStatement,*addStmt; 

    if (sqlite3_prepare_v2(db, sql, -1, &sqlStatement, NULL) == SQLITE_OK) { 

     notExist = TRUE; 

    while (sqlite3_step(sqlStatement) == SQLITE_ROW) { 

     notExist = FALSE; 


    Mysof *Mylist = [[Mysof alloc]init]; 
    Mylist.sofaId = sqlite3_column_int(sqlStatement, 0); 
    Mylist.sofa = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,1)]; 
    Mylist.rating = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 2)]; 
    const char *raw = sqlite3_column_blob(sqlStatement, 3); 
    int rawLen = sqlite3_column_bytes(sqlStatement, 3); 
    NSData *data = [NSData dataWithBytes:raw length:rawLen]; 
    Mylist.photo = [[UIImage alloc] initWithData:data]; 
    [sofArray addObject:Mylist]; 



    } 

     if(notExist){ 
      //NSLog(@"cat id does not exist"); 

      const char *sqlInsert = [[NSString stringWithFormat:@"insert into categories (id, cat_name,order_by) values ('%@', '%@', '%@')", [tuser objectForKey:@"id"], [tuser objectForKey:@"cat_name"],[tuser objectForKey:@"order_by"]] cStringUsingEncoding:NSUTF8StringEncoding]; 
      //NSLog(@"stmt is %s", sqlInsert); 

      if(sqlite3_prepare_v2(db, sqlInsert, -1, &addStmt, NULL) != SQLITE_OK) 
       NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(db)); 

      if(SQLITE_DONE != sqlite3_step(addStmt)) 
       NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(db)); 

     } 


    } 

    } 

    } 

    } 

    return sofArray; 


} 

    @end 

在viewController.m文件:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 


    Sofalistsql * mysofs =[[Sofalistsql alloc] init]; 
    self.sofas = [mysofs getMysofas]; 



} 

按钮即可从服务器显示图像:

-(void)click:(id)sender{ 


scrollview=[[UIScrollView alloc]initWithFrame:CGRectMake(0,500,320,200)]; 

     scrollview.showsVerticalScrollIndicator=NO; 
      scrollview.showsHorizontalScrollIndicator=NO; 

     scrollview.scrollEnabled=YES; 

     int Width = 0;  

    // Width = Width + 20+(i*74); 


    for (int i = 0; i<[self.sofas count]; i++) { 
      NSLog(@"index %d",i); 



      // imgView1=[[UIButton alloc]initWithFrame:CGRectMake(20+(i*74), 500, 72, 72)]; 

      imgView1=[[UIButton alloc]initWithFrame:CGRectMake(20+(i*74), 0, 72, 72)]; 

      Width = Width + 20+(i*74); 

      [imgView1 setTag:i+1]; 

      [imgView1 addTarget:self action:@selector(dbsofaClicked:) forControlEvents:UIControlEventTouchUpInside]; 

      [imgView1 setImage:((Mysof *)[self.sofas objectAtIndex:i]).photo forState:UIControlStateNormal]; 

      [scrollview addSubview:imgView1]; 

      // [myScroll addSubview:imgView1]; 



     } 

     [scrollview setContentSize:CGSizeMake(Width,imgView1.frame.size.height+20)]; 

     [self.view addSubview:scrollview]; 



} 

jsonstring.php文件:

<?php 
    require_once('database_connection.php'); 
    $i = 0; 
    $j = 0; 
    $k = 0; 
    $l = 0; 
    mysql_query('SET CHARACTER SET utf8') or die("MYSQL character set error: ".mysql_error()); 
    $result = array(); 
     $sql=mysql_query("SELECT * FROM categories ORDER BY id ASC") or die(mysql_error()); 
     if(mysql_num_rows($sql) > 0) { 
      while($res=mysql_fetch_array($sql, MYSQL_ASSOC)){ 
       $result[0][$i] = $res; 

       $art_sql=mysql_query("SELECT * FROM product WHERE cat_id=" .$res['id']. " ORDER BY id ASC") or die(mysql_error()); 
       if (mysql_num_rows($art_sql) > 0){ 
        while($art_res=mysql_fetch_array($art_sql, MYSQL_ASSOC)){ 
         //$art_res['art_details'] = (utf8_encode(htmlentities($art_res['art_details']))); 
         //$art_res['art_details'] = htmlentities($art_res['art_details']); 
         //echo $art_res['art_details']; 
         $result[1][$k] = $art_res; 
         //print_r($art_res);  
         $k = $k+1; 
        } 
       } 
       $i= $i+1; 
      } 
      $version_sql = mysql_query("SELECT * FROM version_app order by product_id desc limit 1") or die(mysql_error()); 
      $row = mysql_fetch_array($version_sql); 
      $last_version = $row['product_id']; 
      $result['2'][$l] = array('product_id' => $last_version); 
      $l = $l+1; 
     } 


     /*echo "<pre>"; 
      print_r($result); 
     echo "</pre>";exit;*/ 

    $str_enc = json_encode($result); 
    //print_r($str_enc); exit; 
    $str=str_replace('\r','',$str_enc); 
    $str=str_replace('\t','',$str); 
    $str=str_replace('\n','',$str); 
    $str = stripslashes($str); 
    //$str_renc = json_encode(json_decode($str)); 

    echo $str; 

mysql_close(); 
?> 

的NSLog:

userdata is (
     (
       { 
      "cat_name" = Table1; 
      id = 1; 
      "order_by" = 1; 
     }, 
       { 
      "cat_name" = Table2; 
      id = 2; 
      "order_by" = 2; 
     }, 
       { 
      "cat_name" = test; 
      id = 3; 
      "order_by" = 3; 
     } 
    ), 
     (
       { 
      "cat_id" = 1; 
      id = 2; 
      "order_by" = 1; 
      "product_image" = "img.png"; 
     }, 
       { 
      "cat_id" = 1; 
      id = 3; 
      "order_by" = 2; 
      "product_image" = "img1.png"; 
     }, 
       { 
      "cat_id" = 1; 
      id = 4; 
      "order_by" = 3; 
      "product_image" = "img2.png"; 
     }, 
       { 
      "cat_id" = 1; 
      id = 5; 
      "order_by" = 4; 
      "product_image" = "img3.png"; 
     }, 
       { 
      "cat_id" = 1; 
      id = 6; 
      "order_by" = 5; 
      "product_image" = "img4.png"; 
     }, 
       { 
      "cat_id" = 1; 
      id = 7; 
      "order_by" = 6; 
      "product_image" = "img5.png"; 
     }, 

    ) 
) 


array (
) 
2013-08-16 13:19:53.044 App[3395:c07] scroll is <UIScrollView: 0x9de7cb0; frame = (0 300; 320 200); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x9de60e0>; layer = <CALayer: 0x9de4bc0>; contentOffset: {0, 0}> 

我在本地数据库中存储了相同的表名。并用覆盖数据库。在本地数据库中,我以BLOB类型存储图像。但在我的阵列中,我什么也没有显示。应用正在工作。但图像不从数据库中显示。

+0

你没有从getMysofas方法传递mutableArray的第一件事。第二,为什么你要初始化scrollview两次,一次是viewDidLoad和其他点击操作。要查看完整的代码并找出问题的位置非常困难,请调试并显示实际崩溃的位置。错误意味着它是一些内存问题,你正试图访问一些已经释放的对象。 –

+0

使用ARC的Im。所以我评论发布在JSON文件。它导致错误? – user2674668

+0

如何从getMySofas方法传递mutuableArray? – user2674668

回答

0

既然您已经包含了您的JSON示例,我可以看到另一个问题:您的JSON是一个由三个数组组成的数组,一组数组,一组产品和一组数组。这是一个有问题的结构(通常一个数组将是同类型的同类项目)。而不是数组的数组,我将它作为数组的字典。

您的JSON中的这个令人困惑的结构体现在您的Objective-C代码中。你试图遍历userdata数组,但是你不能,因为这三个项目中的每一个都不相同。

因此,让我提出两个可能的修复方案。首先你,如果你坚持你的阵列(我不是疯了约)的阵列,您无法通过阵列与for循环迭代,但你可以提取三个数组包含像这样:

NSArray *categories = userdata[0]; 
NSArray *products = userdata[1]; 
NSArray *versions = userdata[2]; 

现在您可以遍历这三个数组中的每一个。

就我个人而言,我会更进一步,并更改生成JSON的PHP以生成顶级字典,例如,

<?php 
    require_once('database_connection.php'); 
    $i = 0; 
    $j = 0; 
    $k = 0; 
    $l = 0; 
    mysql_query('SET CHARACTER SET utf8') or die("MYSQL character set error: ".mysql_error()); 
    $result = array(); 
     $sql=mysql_query("SELECT * FROM categories ORDER BY id ASC") or die(mysql_error()); 
     if(mysql_num_rows($sql) > 0) { 
      while($res=mysql_fetch_array($sql, MYSQL_ASSOC)){ 
       $result['categories'][$i] = $res; 

       $art_sql=mysql_query("SELECT * FROM product WHERE cat_id=" .$res['id']. " ORDER BY id ASC") or die(mysql_error()); 
       if (mysql_num_rows($art_sql) > 0){ 
        while($art_res=mysql_fetch_array($art_sql, MYSQL_ASSOC)){ 
         $result['products'][$k] = $art_res; 
         $k = $k+1; 
        } 
       } 
       $i= $i+1; 
      } 
      $version_sql = mysql_query("SELECT * FROM version_app order by product_id desc limit 1") or die(mysql_error()); 
      $row = mysql_fetch_array($version_sql); 
      $last_version = $row['product_id']; 
      $result['versions'][$l] = array('product_id' => $last_version); 
      $l = $l+1; 
     } 

    $str_enc = json_encode($result); 

    // note, these str_replace lines are not needed 

    // $str=str_replace('\r','',$str_enc); 
    // $str=str_replace('\t','',$str); 
    // $str=str_replace('\n','',$str); 

    // this stripslashes is a really bad idea, though 

    // $str = stripslashes($str); 

    // you echoed `$str`, but I'll obviously echo @str_enc  
    echo $str_enc; 

    mysql_close(); 
?> 

如果你这样做,你可以接着用

NSArray *categories = userdata[@"categories"]; 
NSArray *products = userdata[@"products"]; 
NSArray *versions = userdata[@"versions"]; 

检索您的三个数组这不是一个关键任务的变化,但它的三个异质的商品更逻辑表示。但这个想法是一样的:从你的JSON中提取你的三个数组,现在你可以分别遍历它们。


一对夫妇的SQLite的相关问题跳出我

  1. 的一个问题是,你有一个行SQL的,上面写着:

    SELECT id FROM categories where cat_id = '%@' 
    

    但是你继续尝试阅读四栏的数据(即使你只返回一栏)。即使您更改了SQL以实际返回四列数据,您应该确实检查sqlite3_column_blobsqlite3_column_bytes调用,以确保有一些内容可以填充NSData。另外,构建SQL语句时不使用stringWithFormat,而是使用?占位符代替printf格式化程序,然后使用sqlite3_bind_xxx函数,通常更安全。

  2. getMysofas重复打开数据库,但从不关闭它。每拨打一个sqlite3_open电话都有一个sqlite3_close。同样,您应该为每个sqlite3_prepare_v2行声明一个sqlite3_finalize声明。


除此之外,你必须要么使用exception breakpoint,以确定飞机坠毁的来源,单步通过这个代码在调试器中,或把一堆的NSLog声明在那里。请参阅Ray Wenderlich的系列My App Crashed, Now What?。但是你确实需要确定导致问题的代码行。

+0

我在本地数据库中存储了相同的表名。并用覆盖数据库。在本地数据库中,我以“BLOB”类型存储图像。但在我的阵列中,我什么也没有显示。应用正在工作。但图像不从数据库中显示。 – user2674668

+0

@ user2674668你是否修复了SQL(我的第一点)?您的SELECT语句不检索图像数据,因此您对'sqlite3_column_bytes'和'sqlite3_column_blob'的调用将失败。 – Rob

+0

我真的很困惑。在哪里更改代码? – user2674668