ios - 在聊天中加载图像,像 whatsapp 一样在本地保存得更快

标签 ios objective-c mobile chat

我有一个聊天应用程序。它发送消息和文本。目前我遇到一个问题,即从本地加载图像到表格单元格的速度问题。

首先,我将第一次下载的图像保存在文档目录中。然后我检查它是否已经存在。如果是,那么我在后台线程上从本地获取该图像,这使得我的滚动速度很快,但是当表的双端队列方法正在工作时然后 imageview 得到白色背景,片刻之后图像反射(reflect)在 imageview 中,这意味着从本地获取图像需要时间...... . . .

所以帮助我,我需要它和 whatsapp messanger 应用程序一样。

static NSString *simpleTableIdentifier = @"ZImageChatCell";

        ZImageChatCell *cell = (ZImageChatCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

        if (cell == nil)
        {
            NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ZImageChatCell" owner:self options:nil];
            cell = [nib objectAtIndex:0];
        }
            ChatMessageModel *messagemodel = [chatArray objectAtIndex:indexPath.row];

        if([messagemodel.ismymessage boolValue])
        {


            NSData *imgdata = [Base64 decode:messagemodel.previewimage];
            UIImage *effectImage = [UIImageEffects imageByApplyingLightEffectToImage:[UIImage imageWithData:imgdata]];
            [cell.rightimageview setImage:effectImage];


            BOOL imageexist = [self checkImageExistsInLocal:messagemodel.message];
            if(imageexist)
            {

                dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
                dispatch_async(queue, ^{
                UIImage *tempimage = [self fetchImageFromLocal:messagemodel.message];
                UIImage *newimage = [APPDELEGATE imageWithImage:tempimage scaledToFillSize:CGSizeMake(175, 175)];
                    dispatch_async(dispatch_get_main_queue(), ^{

                        cell.rightimageview.image = newimage;

                    });
                });
            }
            else
            {

                if(messagemodel.message.length>0)
                {
                    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

                        UIImage * imggot = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:messagemodel.message]]];
                        UIImage *newimage = [APPDELEGATE imageWithImage:imggot scaledToFillSize:CGSizeMake(175, 175)];
                        [self saveImageLocally:imggot withUrlString:messagemodel.message];

                        dispatch_async(dispatch_get_main_queue(), ^{

                            cell.rightimageview.image = newimage;
                            [cell.rightactivityloader stopAnimating];

                        });

                    });
                }

            }

        }
        else
        {

            NSData *imgdata = [Base64 decode:messagemodel.previewimage];
            UIImage *effectImage = [UIImageEffects imageByApplyingLightEffectToImage:[UIImage imageWithData:imgdata]];
            [cell.leftimageview setImage:effectImage];


            BOOL imageexist = [self checkImageExistsInLocal:messagemodel.message];
            if(imageexist)
            {
                dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
                dispatch_async(queue, ^{
                UIImage *tempimage = [self fetchImageFromLocal:messagemodel.message];
                UIImage *newimage = [APPDELEGATE imageWithImage:tempimage scaledToFillSize:CGSizeMake(SCREEN_WIDTH, SCREEN_WIDTH)];
                    dispatch_async(dispatch_get_main_queue(), ^{

                        cell.leftimageview.image = newimage;

                    });
                });
            }
            else
            {


                if(messagemodel.message.length>0)
                {
                    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

                        UIImage * imggot = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:messagemodel.message]]];
                        UIImage *newimage = [APPDELEGATE imageWithImage:imggot scaledToFillSize:CGSizeMake(175, 175)];
                        [self saveImageLocally:imggot withUrlString:messagemodel.message];

                        dispatch_async(dispatch_get_main_queue(), ^{

                            cell.leftimageview.image = newimage;
                            [cell.leftactivityloader stopAnimating];

                        });

                    });

                }

            }

最佳答案

尝试制作 UIImageView 类别文件以从 url 下载图像,它会将文件保存在设备的缓存内存中,当你想再次加载该图像时,它将从缓存内存加载该图像。

UIImageView+Download.h

-(void)downloadFromURL:(NSString *)url withPlaceholder:(UIImage *)placehold;

UIImageView+Download.m

-(void)downloadFromURL:(NSString *)url withPlaceholder:(UIImage *)placehold
{
    if (placehold) {
        [self setImage:placehold];
    }
    if (url) {

        //
        if ([url rangeOfString:@"/Caches/"].location != NSNotFound) {
            NSData *imageData=[NSData dataWithContentsOfFile:url];
            UIImage* image = [[UIImage alloc] initWithData:imageData];
            if (image) {
                [self setImage:image];
                [self setNeedsLayout];
            }
            return;
        }

        NSString *strImgName = [[[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] componentsSeparatedByString:@"/"] lastObject];

        NSString *imagePath = [NSString stringWithFormat:@"%@/%@",[self applicationCacheDirectoryString],strImgName];

        NSFileManager *fileManager = [NSFileManager defaultManager];

        NSString *aURL=[url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

        if ([fileManager fileExistsAtPath:imagePath]==NO)
        {
            dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
            dispatch_async(queue, ^(void) {

                NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:aURL]];
                [imageData writeToFile:imagePath atomically:YES];

                UIImage* image = [[UIImage alloc] initWithData:imageData];
                if (image) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [self setImage:image];
                        [self setNeedsLayout];

                    });
                }
            });
        }
        else{
            NSData *imageData=[NSData dataWithContentsOfFile:imagePath];
            UIImage* image = [[UIImage alloc] initWithData:imageData];
            if (image) {
                [self setImage:image];
                [self setNeedsLayout];
            }
        }
    }
}

- (NSString *)applicationCacheDirectoryString
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cacheDirectory = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    return cacheDirectory;
}

在这里你只需要从你的类中调用这个方法

[cell.imageView downloadFromURL:YOUR_IMAGE_URL withPlaceholder:PLACEHOLDER_IMAGE];

这段代码对我有用

关于ios - 在聊天中加载图像,像 whatsapp 一样在本地保存得更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36354256/

相关文章:

ios - UITextField 切断了文本的右侧,并且没有在正确的位置显示光标

c# - Xamarin.Forms DatePicker 时间

objective-c - 使用 XMLParser 访问正确的 XML 节点

ios - UICollectionViewController 在升级后的 XCode 7 项目中不起作用

objective-c - iOS Touch 而不是 touchDown?

jquery - 是否可以使用 jquery mobile 按降序列出输入类型 ="range"值

java - LWUIT Gui 构建器

ios - 社交框架 ios5

objective-c - SEL 和@selector 是如何工作的?

iphone - 类中的变量