2017-08-30 8 views
0

J'ai essayé d'enregistrer et de charger des UIImages dans le dossier Documents de mon application ou de préférence dans le dossier temporaire (donc chaque fois que mon application est fermée, les images seront supprimées) mais elles ne fonctionnent pas correctement. J'ai essayé trois approches mais seule la troisième approche fonctionne et je me demande quelle est la bonne façon de le faire? J'apprécie hautement toute aide.Pourquoi la sauvegarde et le chargement des UIImages dans le dossier de documents ne fonctionnent pas correctement avec iOS 8+?

//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]; 
+1

Vous souhaitez sauvegarder et récupérer l'image à partir du répertoire de documents. c'est ta question Correct? –

+0

Non, je veux dire pourquoi les deux premières approches ne fonctionnent pas? Qu'est-ce que je fais mal? et suis-je bien dans la troisième approche pour utiliser le dossier temporaire dans mon application pour faire cela? @MikeAlter –

+1

économiser pour l'approche de deux est bon. pls vérifier chercher l'URL pour le chargement de l'image et je ne suis pas sûr de l'approche un –

Répondre

1

J'ai créé class qui permet d'enregistrer dans le document dossier

Voici .h

@interface FileUtility : NSObject { 

} 

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

@end 

et fichier .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]; 
    } 
} 

Pour chercher utiliser ce

[[FileUtility basePath] stringByAppendingPathComponent

EDIT

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

Merci beaucoup, Juste une question rapide, Si je voulais les enregistrer dans le dossier temporaire, je devrais utiliser NSTemporaryDirectory() au lieu de NSDocumentDirectory dans le chemin de base droite? –

+0

Bien que 'Dlog' et' [FileUtility fileExists: filePath] 'me donne des erreurs. dit aucune méthode de classe existe pour 'fileExists:' –

+1

@ Reza.Ab DLog est NSLog et 'fileExists: filePath' ajouté dans Modifier –

2

avant de lire le fichier, assurez-vous qu'il existe. Si cela existe, le problème se trouve dans [NSData dataWithContentsOfURL:url] sinon l'image n'est pas convertie en données.

Je recommanderais, cassez votre code dans plusieurs déclaration au lieu d'écrire une seule déclaration longue pour mieux comprendre où il échoue.

+0

Dans la première et la seconde approche, fileDirectoryStr renvoie nil mais pourquoi? ils sont l'adresse que la documentation d'Apple nous dit d'utiliser. Mais la troisième approche fonctionne et c'est lent! Quelle serait la manière la plus efficace et la plus correcte de le faire s'ils ne le sont pas? @JitendraSingh –

+0

Les URL sont correctes, je vois la valeur correcte (pas nulle) dans les deux approches. –

+1

Utilisez FileUtility de la réponse @Mike. Vous pouvez modifier ce fichier pour effectuer l'opération de lecture/écriture sur un thread distinct (autre que le thread principal) afin que l'interface utilisateur ne se bloque pas si vous écrivez un fichier volumineux. –