Storing ALAsset URLs in NSUserDefaults

Hi, I have an ALAsset URL saving NSMutableArray ,

 "ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=119A0D2D-C267-4B69-A200-59890B2B0FE5&exโ€Œโ€‹t=JPG", "ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=92A7A24F-D54B-496E-B250-542BBE37BE8C&exโ€Œโ€‹t=JPG", "ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=77AC7205-68E6-4062-B80C-FC288DF96F24&exโ€Œโ€‹t=JPG 

I could not save NSMutableArray in NSUserDefaults due to an error with the error Note that dictionaries and arrays in property lists must also contain only property values. I am thinking about using this:

  - (void)encodeWithCoder:(NSCoder *)encoder { //Encode properties, other class variables, etc [encoder encodeObject:self.selectedPhotos forKey:@"selectedPhotos"]; } - (id)initWithCoder:(NSCoder *)decoder { if((self = [super init])) { //decode properties, other class vars self.selectedPhotos = [decoder decodeObjectForKey:@"selectedPhotos"]; } return self; } 

then save and extract it with this code:

  - (void)saveCustomObject:(MyCustomObject *)obj { NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:obj]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:myEncodedObject forKey:@"myEncodedObjectKey"]; } - (MyCustomObject *)loadCustomObjectWithKey:(NSString *)key { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSData *myEncodedObject = [defaults objectForKey:key]; MyCustomObject *obj = (MyCustomObject *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject]; return obj; } 

But somehow I didnโ€™t quite understand, it still crashed in my code. Do not know how. And I could not save it to NSUserDefaults. Hope someone helps. In fact, there was a problem with this. I hope someone NSUserDefaults me on the right path to salvation and returns me the right path from NSUserDefaults . Then go back to NSMutableArray .

+4
source share
3 answers

NSUserDefaults accepts only a limited set of classes as objects. See the documentation . You only need to take care of storing the values โ€‹โ€‹of these types (NSData, NSString, NSNumber, NSDate, NSArray or NSDictionary, and of course it is applied recursively) in the dictionary.

To save URLs to NSUserDefaults , save them as strings, and then read them as URLs. If you need a dictionary in the current format, you may need to convert it before saving.

 - (void) saveMyUrls { NSMutableArray* urls = [NSMutableArray arrayWithCapacity:self.myUrls.count]; for(NSURL* url in self.myUrls) { [urls addObject:[url absoluteString]]; } [[NSUserDefaults standardUserDefaults] setObject:urls forKey:@"myUrls"]; } - (void) loadUrls { NSArray* urls = [[NSUserDefaults standardUserDefaults] objectForKey:@"myUrls"]; self.myUrls = [NSMutableArray arrayWithCapacity:urls.count]; for(NSString* urlString in urls) { [self.myUrls addObject:[NSURL URLWithString:urlString]]; } [[NSUserDefaults standardUserDefaults] setObject:urls forKey:@"myUrls"]; } 

If you need to save more information than just a URL, say a user-specified label, you can save the object as an NSDictionary instead, for example.

 - (void) saveMyUrlsWithLabels { NSMutableArray* objs = [NSMutableArray arrayWithCapacity:self.myObjects.count]; for(MyObject* obj in self.myObjects) { [objs addObject:[NSDictionary dictionaryWithKeys:@"url", @"label" forObjects:obj.url.absoluteString, obj.userSpecifiedLabel]; } [[NSUserDefaults standardUserDefaults] setObject:objs forKey:@"myObjects"]; } 
+3
source

Maybe you should do it like this:

 - (MyCustomObject *)loadCustomObjectWithKey:(NSString *)key { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults synchronize]; // note this NSData *myEncodedObject = [defaults objectForKey:key]; MyCustomObject *obj = nil; // it would be even better // to wrap this into @ try-@catch block if(myEncodedObject) { obj = (MyCustomObject *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject]; } return obj; } 

Also note that if you want to use NSKeyedArchiver and NSKeyedUNarchiver , your MyCustomObject class must conform to the NSCoding protocol. Check out the NSCoding protocol link and Programming and Serialization Guide .

+1
source

This is another way to do this, and you can use NSUserDefaults. Basically you get the URL of the resource, save it and then convert it back to an object / image

 //SET IT ALAsset *asset3 = [self.assets objectAtIndex:[indexPath row]]; NSMutableString *testStr = [NSMutableString stringWithFormat:@"%@", asset3.defaultRepresentation.url]; //NSLog(@"testStr: %@ ...", testStr); [[NSUserDefaults standardUserDefaults] setObject:testStr forKey:@"userPhotoAsset"]; [[NSUserDefaults standardUserDefaults] synchronize]; //GET IT NSString *assetUrlStr = [[NSUserDefaults standardUserDefaults] objectForKey:@"userPhotoAsset"]; NSURL* aURL = [NSURL URLWithString:assetUrlStr]; NSLog(@"aURL: %@ ...", aURL); ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; [library assetForURL:aURL resultBlock:^(ALAsset *asset) { UIImage *copyOfOriginalImage = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage] scale:1.0 orientation:UIImageOrientationUp]; imgVwPortrait.image = copyOfOriginalImage; } failureBlock:^(NSError *error) { // error handling NSLog(@"failure-----"); }]; 
+1
source

All Articles