Ist es möglich, Bilder NSUserDefaults
als Objekt zu speichern und zur weiteren Verwendung abzurufen?
BEACHTUNG! WENN SIE UNTER iOS8 / XCODE6 ARBEITEN, SEHEN SIE MEIN UPDATE UNTEN
Für diejenigen, die hier noch nach einer Antwort suchen, gibt es den Code "ratsam", um Bilder in NSUserDefaults zu speichern. Sie sollten Bilddaten NICHT direkt in NSUserDefaults speichern!
Daten schreiben:
// Get image data. Here you can use UIImagePNGRepresentation if you need transparency
NSData *imageData = UIImageJPEGRepresentation(image, 1);
// Get image path in user's folder and store file with name image_CurrentTimestamp.jpg (see documentsPathForFileName below)
NSString *imagePath = [self documentsPathForFileName:[NSString stringWithFormat:@"image_%f.jpg", [NSDate timeIntervalSinceReferenceDate]]];
// Write image data to user's folder
[imageData writeToFile:imagePath atomically:YES];
// Store path in NSUserDefaults
[[NSUserDefaults standardUserDefaults] setObject:imagePath forKey:kPLDefaultsAvatarUrl];
// Sync user defaults
[[NSUserDefaults standardUserDefaults] synchronize];
Daten lesen:
NSString *imagePath = [[NSUserDefaults standardUserDefaults] objectForKey:kPLDefaultsAvatarUrl];
if (imagePath) {
self.avatarImageView.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:imagePath]];
}
documentsPathForFileName:
- (NSString *)documentsPathForFileName:(NSString *)name {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
return [documentsPath stringByAppendingPathComponent:name];
}
Für iOS8 / XCODE6 Wie in den Kommentaren unten erwähnt, gibt es ein Problem mit xcode6 / ios8. Der Unterschied zwischen dem Installationsprozess von xcode5 und xcode 6 besteht darin, dass xcode6 die UUID von Apps nach jeder Ausführung in xcode ändert (siehe hervorgehobenes Teil im Pfad: / var / mobile / Container / Daten / Anwendung / B0D49CF5-8FBE-4F14-87AE-FA8C16A678B1 / Documents / image.jpg).
Es gibt also zwei Problemumgehungen:
Hier ist eine schnelle Version des Codes als Bonus (mit 2. Ansatz):
Daten schreiben:
let imageData = UIImageJPEGRepresentation(image, 1)
let relativePath = "image_\(NSDate.timeIntervalSinceReferenceDate()).jpg"
let path = self.documentsPathForFileName(relativePath)
imageData.writeToFile(path, atomically: true)
NSUserDefaults.standardUserDefaults().setObject(relativePath, forKey: "path")
NSUserDefaults.standardUserDefaults().synchronize()
Daten lesen:
let possibleOldImagePath = NSUserDefaults.standardUserDefaults().objectForKey("path") as String?
if let oldImagePath = possibleOldImagePath {
let oldFullPath = self.documentsPathForFileName(oldImagePath)
let oldImageData = NSData(contentsOfFile: oldFullPath)
// here is your saved image:
let oldImage = UIImage(data: oldImageData)
}
documentsPathForFileName:
func documentsPathForFileName(name: String) -> String {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true);
let path = paths[0] as String;
let fullPath = path.stringByAppendingPathComponent(name)
return fullPath
}
So speichern Sie ein Bild in NSUserDefaults:
[[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation(image) forKey:key];
So rufen Sie ein Bild von NSUserDefaults ab:
NSData* imageData = [[NSUserDefaults standardUserDefaults] objectForKey:key]; UIImage* image = [UIImage imageWithData:imageData];
quelle
Das Speichern von
UIImage
to ist zwar möglichNSUserDefaults
, wird jedoch häufig nicht empfohlen, da dies nicht die effizienteste Methode zum Speichern von Bildern ist. Eine effizientere Möglichkeit besteht darin, Ihr Bild in der Anwendung zu speichernDocuments Directory
.Für die Zwecke dieser Frage habe ich die Antwort an Ihre Frage angehängt, zusammen mit der effizienteren Methode zum Speichern von a
UIImage
.NSUserDefaults (nicht empfohlen)
Speichern in NSUserDefaults
Diese Methode ermöglicht es Ihnen , alle retten
UIImage
zuNSUserDefaults
.-(void)saveImageToUserDefaults:(UIImage *)image ofType:(NSString *)extension forKey:(NSString *)key { NSData * data; if ([[extension lowercaseString] isEqualToString:@"png"]) { data = UIImagePNGRepresentation(image); } else if ([[extension lowercaseString] isEqualToString:@"jpg"]) { data = UIImageJPEGRepresentation(image, 1.0); } NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setObject:data forKey:key]; [userDefaults synchronize]; }
So nennt man es:
[self saveImageToUserDefaults:image ofType:@"jpg" forKey:@"myImage"]; [[NSUserDefaults standardUserDefaults] synchronize];
Laden aus NSUserDefaults
Mit dieser Methode können Sie beliebige
UIImage
von ladenNSUserDefaults
.-(UIImage *)loadImageFromUserDefaultsForKey:(NSString *)key { NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults]; return [UIImage imageWithData:[userDefaults objectForKey:key]]; }
So nennt man es:
UIImage * image = [self loadImageFromUserDefaultsForKey:@"myImage"];
Eine bessere Alternative
Speichern im Dokumentenverzeichnis
Mit dieser Methode können Sie alle
UIImage
inDocuments Directory
der App speichern .-(void)saveImage:(UIImage *)image withFileName:(NSString *)imageName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath { if ([[extension lowercaseString] isEqualToString:@"png"]) { [UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]] options:NSAtomicWrite error:nil]; } else if ([[extension lowercaseString] isEqualToString:@"jpg"] || [[extension lowercaseString] isEqualToString:@"jpeg"]) { [UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]] options:NSAtomicWrite error:nil]; } else { NSLog(@"Image Save Failed\nExtension: (%@) is not recognized, use (PNG/JPG)", extension); } }
So nennt man es:
NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; [self saveImage:image withFileName:@"Ball" ofType:@"jpg" inDirectory:documentsDirectory];
Laden aus dem Dokumentenverzeichnis
Mit dieser Methode können Sie alle
UIImage
aus der Anwendung ladenDocuments Directory
.-(UIImage *)loadImageWithFileName:(NSString *)fileName ofType:(NSString *)extension inDirectory:(NSString *)directoryPath { UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.%@", directoryPath, fileName, [extension lowercaseString]]]; return result; }
So nennt man es:
NSString * documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; UIImage * image = [self loadImageWithFileName:@"Ball" ofType:@"jpg" inDirectory:documentsDirectory];
Eine andere Alternative
Speichern von UIImage in der Fotobibliothek
Diese Methode ermöglicht das Speichern
UIImage
auf dem GerätPhoto Library
und wird wie folgt aufgerufen:UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
Speichern mehrerer UIImages in der Fotobibliothek
Mit dieser Methode können Sie mehrere
UIImages
auf dem Gerät speichernPhoto Library
.-(void)saveImagesToPhotoAlbums:(NSArray *)images { for (int x = 0; x < [images count]; x++) { UIImage * image = [images objectAtIndex:x]; if (image != nil) UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); } }
So nennt man es:
[self saveImagesToPhotoAlbums:images];
Wo
images
ist IhrNSArray
bestehend ausUIImages
.quelle
inDirectory:(NSString *)directoryPath
- können Sie es einfach so nennen, wie Sie möchten, wie "myAppData"?Für Swift 4
Ich habe fast alles in dieser Frage versucht, aber niemand ist für mich gearbeitet. und ich fand meine Lösung. Zuerst habe ich eine Erweiterung für UserDefaults wie unten erstellt und dann einfach get and set Methoden aufgerufen.
extension UserDefaults { func imageForKey(key: String) -> UIImage? { var image: UIImage? if let imageData = data(forKey: key) { image = NSKeyedUnarchiver.unarchiveObject(with: imageData) as? UIImage } return image } func setImage(image: UIImage?, forKey key: String) { var imageData: NSData? if let image = image { imageData = NSKeyedArchiver.archivedData(withRootObject: image) as NSData? } set(imageData, forKey: key) } }
Um das Bild als Hintergrund in settingsVC festzulegen, habe ich den folgenden Code verwendet.
let croppedImage = cropImage(selectedImage, toRect: rect, viewWidth: self.view.bounds.size.width, viewHeight: self.view.bounds.size.width) imageDefaults.setImage(image: croppedImage, forKey: "imageDefaults")
in mainVC:
let bgImage = imageDefaults.imageForKey(key: "imageDefaults")!
quelle
Für schnelle 2.2
Lagern:
NSUserDefaults.standardUserDefaults().setObject(UIImagePNGRepresentation(chosenImage), forKey: kKeyImage)
So rufen Sie ab:
if let imageData = NSUserDefaults.standardUserDefaults().objectForKey(kKeyImage), let image = UIImage(data: imageData as! NSData){ // use your image here... }
quelle
Ja, technisch möglich wie in
[[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation(image) forKey:@"foo"];
Dies ist jedoch nicht ratsam, da Plists keine geeigneten Orte für große Blobs von Binärdaten sind, insbesondere für Benutzereinstellungen. Es ist besser, das Bild im Ordner "Benutzerdokumente" zu speichern und den Verweis auf dieses Objekt als URL oder Pfad zu speichern.
quelle
Für Swift 3 und JPG- Format
Standardbild registrieren:
UserDefaults.standard.register(defaults: ["key":UIImageJPEGRepresentation(image, 100)!])
Bild speichern :
UserDefaults.standard.set(UIImageJPEGRepresentation(image, 100), forKey: "key")
Bild laden :
let imageData = UserDefaults.standard.value(forKey: "key") as! Data let imageFromData = UIImage(data: imageData)!
quelle
Aus der Apple-Dokumentation,
Sie können das Bild folgendermaßen speichern: -
[[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation([UIImage imageNamed:@"yourimage.gif"])forKey:@"key_for_your_image"];
Und lesen Sie so: -
NSData* imageData = [[NSUserDefaults standardUserDefaults]objectForKey:@"key_for_your_image"]; UIImage* image = [UIImage imageWithData:imageData];
quelle
Es ist technisch möglich, aber nicht ratsam. Speichern Sie das Image stattdessen auf der Festplatte. NSUserDefaults ist für kleine Einstellungen gedacht, nicht für große Binärdatendateien.
quelle
Bild in NSUserDefault speichern:
NSData *imageData; // create NSData-object from image imageData = UIImagePNGRepresentation([dic objectForKey:[NSString stringWithFormat:@"%d",i]]); // save NSData-object to UserDefaults [[NSUserDefaults standardUserDefaults] setObject:imageData forKey:[NSString stringWithFormat:@"%d",i]];
Bild von NSUserDefault laden:
NSData *imageData; // Load NSData-object from NSUserDefault imageData = [[NSUserDefaults standardUserDefaults] valueForKey:[NSString stringWithFormat:@"%d",i]]; // get Image from NSData [image setObject:[UIImage imageWithData:imageData] forKey:[NSString stringWithFormat:@"%d",i]];
quelle
Ja, du kannst verwenden. Da es sich jedoch um die Speicherung von Einstellungen handelt, können Sie Bilder besser im Dokumentordner speichern.
Und Sie können den Pfad
NSUserDefaults
bei Bedarf in der haben.quelle
Da diese Frage einen hohen Google-Suchindex hat, finden Sie hier die Antwort von @ NikitaTook in der heutigen Zeit, dh Swift 3 und 4 (mit Ausnahmebehandlung).
Hinweis: Diese Klasse dient ausschließlich zum Lesen und Schreiben von Bildern im JPG-Format in das Dateisystem. Das
Userdefaults
Zeug sollte außerhalb davon gehandhabt werden.writeFile
Nimmt den Dateinamen Ihres JPG-Bildes (mit der Erweiterung .jpg) und dasUIImage
selbst auf und gibt true zurück, wenn es speichern kann, oder false, wenn es das Bild nicht schreiben kann. An diesem Punkt können Sie das Bild inUserdefaults
welchem speichern wäre Ihr Backup-Plan oder versuchen Sie es einfach noch einmal. DiereadFile
Funktion nimmt den Namen der Bilddatei auf und gibt a zurückUIImage
. Wenn der an diese Funktion übergebene Bildname gefunden wird, gibt sie das Bild zurück. Andernfalls wird nur ein Standard-Platzhalterbild aus dem Asset-Ordner der App zurückgegeben (auf diese Weise können Sie böse Abstürze oder andere vermeiden seltsame Verhaltensweisen).import Foundation import UIKit class ReadWriteFileFS{ func writeFile(_ image: UIImage, _ imgName: String) -> Bool{ let imageData = UIImageJPEGRepresentation(image, 1) let relativePath = imgName let path = self.documentsPathForFileName(name: relativePath) do { try imageData?.write(to: path, options: .atomic) } catch { return false } return true } func readFile(_ name: String) -> UIImage{ let fullPath = self.documentsPathForFileName(name: name) var image = UIImage() if FileManager.default.fileExists(atPath: fullPath.path){ image = UIImage(contentsOfFile: fullPath.path)! }else{ image = UIImage(named: "user")! //a default place holder image from apps asset folder } return image } } extension ReadWriteFileFS{ func documentsPathForFileName(name: String) -> URL { let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) let path = paths[0] let fullPath = path.appendingPathComponent(name) return fullPath } }
quelle
Swift 4.x
Xcode 11.x.
func saveImageInUserDefault(img:UIImage, key:String) { UserDefaults.standard.set(img.pngData(), forKey: key) } func getImageFromUserDefault(key:String) -> UIImage? { let imageData = UserDefaults.standard.object(forKey: key) as? Data var image: UIImage? = nil if let imageData = imageData { image = UIImage(data: imageData) } return image }
quelle