【问题标题】:Why saving and loading UIImages in documents folder doesn't work properly in iOS 8+?为什么在 iOS 8+ 中无法在文档文件夹中保存和加载 UIImages?
【发布时间】:2018-02-08 05:02:05
【问题描述】:

我一直在尝试将 UIImages 保存并加载到我的应用程序的 Documents 文件夹或最好的临时文件夹中(因此每次我的应用程序关闭时,图像都会被删除),但它们无法正常工作。我尝试了三种方法,但只有第三种方法有效,我想知道正确的方法是什么?我非常感谢任何帮助。

 //First Approach, to save and load later, Doesn't work.
 //Saving the image
 NSURL *documentsDirectoryURL = [[[NSFileManager defaultManager]
                                  URLsForDirectory:NSDocumentDirectory
                                   inDomains:NSUserDomainMask]
                                    lastObject];
NSString*fileDirectoryStr = [[documentsDirectoryURL path] stringByAppendingPathComponent:@"E1BG.png"];
NSURL *url = [NSURL URLWithString:fileDirectoryStr];
//Saving either as Jpeg
[UIImagePNGRepresentation(finalFG) writeToFile:fileDirectoryStr atomically:YES];
//Or as PNG, because I need the transparent part to be kept transparent but non of them work.
[UIImageJPEGRepresentation(finalFG, 1.0) writeToFile:fileDirectoryStr atomically:YES];
//Loading image
UIImage *loadedBGImg = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
//Returns nil

//Second approach.
//Saving the image
NSArray*pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsPath = [pathArray objectAtIndex:0];
NSString* fileDirectoryStr = [documentsPath stringByAppendingPathComponent:@"E1FG.png"];
//Again saving either as Jpeg
[UIImagePNGRepresentation(finalFG) writeToFile:fileDirectoryStr atomically:YES];
//Or as PNG, because I need the transparent part to be kept transparent but non of them work.
[UIImageJPEGRepresentation(finalFG, 1.0) writeToFile:fileDirectoryStr atomically:YES];
NSURL *url1 = [NSURL URLWithString:fileDirectoryStr];
//Loading image
UIImage *loadedImg = [UIImage imageWithData: [NSData dataWithContentsOfURL:url1]];

 //Third approach, Works but doesnt seem to be very efficient.
 NSString *tmpDirectory = NSTemporaryDirectory();
 //Save
 NSString *tmpFileStrFG = [tmpDirectory stringByAppendingPathComponent:@"E1FG.png"];
 NSURL *urlFG = [NSURL URLWithString:tmpFileStrFG];
 NSData *imgDataFG = UIImagePNGRepresentation(finalFG);
 [imgDataFG writeToURL:urlFG atomically:YES];
 //Load
 UIImage *ImggFG = [UIImage imageWithData: imgDataFG];

【问题讨论】:

  • 您想从文档目录中保存和检索图像。你的问题对吗?
  • 不,我的意思是为什么前两种方法不起作用?我究竟做错了什么?我是否在第三种方法中正确使用我的应用程序中的临时文件夹来做到这一点? @MikeAlter
  • 保存方法二看起来不错。请检查 fetch url 以加载图像,我不确定方法一个
  • 第二个根本不起作用。您能否提供一种适用于所有 ios 更新(包括 ios 11)的有效方法? @MikeAlter

标签: ios objective-c uiimage nsdata nsfilemanager


【解决方案1】:

在读取文件之前,请确保它存在于那里。如果确实存在,则问题出在[NSData dataWithContentsOfURL:url] 中,否则图像未转换为数据。

我建议将您的代码分成多个语句,而不是编写单个冗长的语句,以便更好地了解它的失败之处。

【讨论】:

  • 在第一种和第二种方法中,fileDirectoryStr 返回 nil 但为什么呢?它们是苹果文档告诉我们使用的地址。但是第三种方法有效,而且速度很慢!如果不是,最有效和最正确的方法是什么? @JitendraSingh
  • URL 很好,我在这两种方法中都看到了正确的值(不是 nil)。
  • 使用来自@Mike 答案的 FileUtility。您可以修改该文件以在单独的线程(主线程除外)上进行读/写操作,以便在您编写大文件时 UI 不会挂起。
  • 谢谢,它们只是 80 个小的 UIImages。
  • 你在 ios11 中试过了吗?它对我来说仍然为零。 @JitendraSingh
【解决方案2】:

我创建了class,它允许保存在文件夹中

这是.h文件

@interface FileUtility : NSObject {

}

// Folder methods
+ (NSString*)basePath;
+ (void)createFile:(NSString *)filename;
+ (void)createFile:(NSString *)filePath withData: (NSData *) imgData;

@end

和.m文件

#import "FileUtility.h"

@implementation FileUtility

// ----------------------------------------------------------------------------

#pragma mark -
#pragma mark Path methods

// -----------------------------------------------------------------------------

+ (NSString*)basePath {
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSAssert([paths count] == 1, @"");
    return [paths objectAtIndex:0];     
}

// -----------------------------------------------------------------------------




  + (void)createFile:(NSString *)filename {
    NSFileManager* manager = [NSFileManager defaultManager];
    NSString * filePath = [NSString stringWithFormat:@"%@/%@", [FileUtility basePath],filename];
    DLOG(@"filePath = %@", filePath);
    if (![FileUtility fileExists:filePath]){
        [manager createFileAtPath:filePath contents:nil attributes:nil];
    }

    }

// -----------------------------------------------------------------------------

+ (void)createFile:(NSString *)filePath withData: (NSData *) imgData {
    NSFileManager* manager = [NSFileManager defaultManager];
    DLOG(@"filePath = %@", filePath);
    if (![FileUtility fileExists:filePath]){
        [manager createFileAtPath:filePath contents:imgData attributes:nil];
    }
}

为了获取使用这个

[[FileUtility basePath] stringByAppendingPathComponent

编辑

+ (BOOL)fileExists:(NSString *)filename {
    NSFileManager* manager = [NSFileManager defaultManager];
    return [manager fileExistsAtPath:filename];
}

【讨论】:

  • 非常感谢,只是一个简单的问题,如果我想将它们保存在临时文件夹中,我应该在基本路径中使用 NSTemporaryDirectory() 而不是 NSDocumentDirectory 对吗?
  • 虽然Dlog[FileUtility fileExists:filePath] 给了我错误。表示fileExists: 不存在类方法
  • @Reza.Ab DLog 是 NSLog 和 fileExists:filePath 在编辑中添加
  • 为了使用临时文件夹,我应该在基本路径中将 NSTemporaryDirectory() 替换为 NSDocumentDirectory 对吗?我应该使用 nsfilemanager 的什么方法来加载文件?我这样做是为了加载文件+ (UIImage*)loadImageFileWithPath:(NSString*)path{ NSData *file = [[NSData alloc]initWithContentsOfFile:path]; UIImage * loadedImg = [UIImage imageWithData:file scale:1.0]; return loadedImg; } 谢谢@MikeAlter
  • 所以我最终修改了这样的代码以添加一个加载图像的方法,但随后我收到了与整个事情完全相反的内存警告。我目前正在使用 file =[NSData initWithContentsOfFile:path];然后得到像 myImage = [UIImage imageWithData:file scale:1.0]; 这样的 UIImage。我认为 imageWithData 会比 [UIImage imageNamed:]; 占用更少的内存。 @MikeAlter
猜你喜欢
  • 1970-01-01
  • 2014-12-24
  • 2012-01-30
  • 1970-01-01
  • 2017-05-07
  • 2021-10-19
  • 2015-02-22
  • 1970-01-01
  • 2019-03-23
相关资源
最近更新 更多