图片未从数据库中获取 [英] Image is not fetching from database

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

问题描述

我在我的服务器中存储了一些图像.我使用 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('
','',$str_enc);
    $str=str_replace('	','',$str);
    $str=str_replace('
','',$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('
','',$str_enc);
    // $str=str_replace('	','',$str);
    // $str=str_replace('
','',$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_blobsqlite3_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.

顺便说一句,在构建 SQL 语句时不使用 stringWithFormat 通常更安全,而是使用 ? 占位符而不是 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天全站免登陆