在聊天中加载图像,本地保存更快,如whatsapp

时间:2016-04-01 10:42:04

标签: ios objective-c mobile chat

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

首先我在第一次下载文档目录中保存图像。然后我检查它已经存在。如果是,那么我从后台线程本地获取该图像,这使得我的滚动速度快但是当桌面的deque方法工作时然后imageview得到白色背景,过了一会儿,图像反映在imageview中,这意味着从本地获取图像需要时间。 。 。 。

所以请帮助我,我需要它和whatsapp messanger app一样。

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];

                        });

                    });

                }

            }

2 个答案:

答案 0 :(得分:2)

尝试制作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];

这段代码对我有用

答案 1 :(得分:2)

快速转换: -

func download(fromURL url: String, withPlaceholder placeholder: UIImage?) {
    if placeholder != nil{
        image = placeholder!
    }
    if url != "" {
        if ((url as NSString).range(of: "/Caches/")).location != NSNotFound {
            if let img = UIImage(contentsOfFile: url){
                self.image = img
                setNeedsLayout()
            }
            return
        }

        let str: String = (url as NSString).addingPercentEscapes(using: 4)!//NSUTF8StringEncoding
        let strImg = str.components(separatedBy: "/").last!
        let imagePath = "\(applicationCacheDirectoryString())/\(strImg)"
        let fileManager = FileManager.default
        let aURL = (url as NSString).addingPercentEscapes(using: 4)!

        if fileManager.fileExists(atPath: imagePath) == false{
            let queue = DispatchQueue.global(qos: .default)
            queue.async(execute: {(_: Void) -> Void in

                do{
                    let imageData = try Data(contentsOf: URL(string: aURL)!)
                    do{
                        let url = URL(fileURLWithPath: imagePath)
                        try imageData.write(to: url, options: .atomic)
                        if let img = UIImage(data: imageData){
                            DispatchQueue.main.async(execute: {() -> Void in
                                self.image = img
                                self.setNeedsLayout()
                            })
                        }
                    }catch{
                        print("Not able to save image in cache directory from url:\(aURL)")
                    }
                }catch{
                    print("Not able to convert into Data from url:\(aURL)")
                }
            })
        }else{
            if let img = UIImage(contentsOfFile: imagePath){
                self.image = img
                setNeedsLayout()
            }
        }
    }
}

func applicationCacheDirectoryString() -> String {
    let paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)
    let cacheDirectory: String? = (paths.count > 0) ? paths[0] : nil
    return cacheDirectory ?? ""
}