图像不是从数据库中获取的 [英] Image is not fetching from database

查看:94
本文介绍了图像不是从数据库中获取的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I stored some images in my server. I used JSON for fetch remote data from server. When i was storing images in local database it was working. When i use json url it's not working. Im getting EXC_BAD_ACCESS error.

代码:

Mysof.h文件:

Mysof.h file:

@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文件:

Mysof.m file:

@implementation Mysof

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

@end

Sofalistsql.h文件:

Sofalistsql.h file:

@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文件中:

In viewController.m file:

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


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



}

按钮点击显示来自服务器的图片:

Button click to display images from server:

-(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文件:

jsonstring.php file:

<?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 类型中。但在我的阵列中,我什么也没有显示。应用程序正在运行但图像不是从数据库中显示的。

I stored same Table name in local database. And used overwrite database. In local database i stored images in BLOB type. But in my array i got nothing displaying. App is working. But images are not displaying from database.

推荐答案

现在你已经包含了你的JSON示例,我可以看到另一个问题:你的JSON是一个由三个数组组成的数组,一个类别数组,一个产品数组和一个版本数组。这是一个有问题的结构(通常一个数组将是相同类型的同类项)。而不是一个数组数组,我会把它变成一个数组字典。

Now that you've included your JSON sample, I can see another problem: Your JSON is an array of three arrays, an array of categories, an array of products, and an array of versions. That is a questionable structure (usually an array would be of homogeneous items of the same type). Rather than an array of arrays, I'd make it a dictionary of arrays.

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

This confusing structure in your JSON manifests itself in your Objective-C code. You're trying to iterate through the userdata array, but you can't, because each of the three item is different.

因此,我建议两个可能的修复方法。首先,如果你坚持你的阵列数组(我不是很疯狂),你不能用 for 循环遍历那个数组,但你可以提取三个它包含的数组如下:

So let me suggest two possible fixes. First you if you stick with your array of arrays (which I'm not crazy about), you cannot iterate through that array with a for loop, but you could extract the three arrays it contains like so:

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

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

Now you can iterate through each of those three arrays.

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

Personally, I'd take this a step further and change that PHP that generates the JSON to generate a top level dictionary, e.g.

<?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();
?>

如果你这样做,你可以用

And if you did that, you could then retrieve your three arrays with

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

这不是关键任务的变化,但它是三个异构项目的更合理的表示。但是这个想法是一样的:从你的JSON中提取你的三个数组,现在你可以分别迭代它们。

It's not a mission critical change, but it's a more logical representation for three heterogeneous items. But the idea is the same: Extract your three arrays from your JSON, and now you can iterate through them, respectively.

一些与SQLite相关的问题在我身上跳了出来

A couple of SQLite-related issues leap out at me


  1. 一个问题是你有一行SQL说:

  1. One issue is that you have a line of SQL that says:

SELECT id FROM categories where cat_id = '%@'

但是你继续尝试读取四列数据(即使你只返回了一列)。即使您将SQL更改为实际返回四列数据,您也应该检查 sqlite3_column_blob sqlite3_column_bytes 调用确保有一些东西填充 NSData

But you then proceed to try to read four columns worth of data (even though you only returned one). And even if you changed your SQL to actually return four columns of data, you should really check the sqlite3_column_blob and sqlite3_column_bytes calls to make sure there was something to populate the NSData.

顺便说一下,不使用<通常更安全code> stringWithFormat 在构建SQL语句时,而是使用占位符而不是printf-formatters然后使用 sqlite3_bind_xxx 函数。

As an aside, it's generally safer to not use stringWithFormat when building a SQL statement, but rather use ? placeholders instead of printf-formatters and then use sqlite3_bind_xxx functions.

getMysofas 重复打开数据库,但永远不要关闭它。每个 sqlite3_open 调用都有一个 sqlite3_close 。同样,对于每个 sqlite3_prepare_v2 行,您应该有一个 sqlite3_finalize 语句。

You getMysofas is repeatedly opening the database, but never closing it. Have one sqlite3_close for every sqlite3_open call. Likewise, you should have one sqlite3_finalize statement for each sqlite3_prepare_v2 line.






除此之外,您必须使用异常断点,在调试器中单步执行此代码,或者放入一堆那里的 NSLog 语句。请参阅Ray Wenderlich的系列我的应用程序崩溃,现在是什么?。但是您确实需要确定导致问题的代码行。


Beyond that you have to identify the source of the crash by either using an exception breakpoint, single-stepping through this code in the debugger, or putting a bunch of NSLog statements in there. See Ray Wenderlich's series My App Crashed, Now What?. But you really need to identify the line of code that is causing the problem.

这篇关于图像不是从数据库中获取的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆