4

I now try to update my app. and saw unarchiveobjectwithdata:' is deprecated. How i can fix it?

I have class

@interface Favorite : NSObject <NSSecureCoding> //NSCoding NSSecureCoding

@property (nonatomic) NSDate *wikiDate;

@property (nonatomic) FavoriteType type;

- (id) initWithDate:(NSDate *) date type:(FavoriteType) type;

- (id) initNilFavorite;

- (BOOL) isNilFavorite;
- (id) initWithCoder:(NSCoder *)aDecoder;
- (void) encodeWithCoder:(NSCoder *)aCoder;
@end

and i have second class

@interface Settings : NSObject 

+ (Settings *) sharedInstance;
        
@property (nonatomic) NSMutableArray *favorites;

// favorites part

- (BOOL) isFavorite:(NSDate *) date type:(FavoriteType) type;
- (void) addToFavorites:(NSDate *) date type:(FavoriteType) type;
- (void) removeFromFavorites:(NSDate *) date type:(FavoriteType) type;

- (void) groupFavorites;   
- (void) saveSettings;

@end

when i save favorite in settigns

- (void) saveFavorites{
    NSString* filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"favorites"];
    NSError* error;
    NSData* codedData = [NSKeyedArchiver archivedDataWithRootObject:self.favorites requiringSecureCoding:NO error:&error];
    if(error!=nil) {
        NSLog(@"Eror when try to archive favorites!!!!");
    }
    else {
        [codedData writeToFile:filePath atomically:YES];
    }
}

and i try to load

- (void) loadFavorites{
    NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"favorites"];
    NSData *data = [NSData dataWithContentsOfFile:filePath];
    if (data) {
       self.favorites = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    }   
}

All working, but now i must to replace unarchiveObjectWithData to unarchivedArrayOfObjectsOfClass

self.favorites is MuttableArray of Favorite class!

I tryed veriants:

NSSet *allowedClasses = [NSSet setWithObjects:[NSMutableArray  class],[Favorite class], nil];
NSMutableArray *encodedData = [NSKeyedUnarchiver unarchivedObjectOfClasses:allowedClasses fromData:data error:&error];

and

NSData *encodedData = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSArray class]  fromData:data error:&error];

and

NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:&error];
[unarchiver setRequiresSecureCoding:NO];
[unarchiver decodeObjectOfClass:[Favorite class] forKey:@""];
[unarchiver finishDecoding];

noting to work :(

Please help me

BeattleJeuse
  • 41
  • 1
  • 2
  • 1
    Does this answer your question? [iOS 12.0 Alternative to Using Deprecated archiveRootObject:toFile:](https://stackoverflow.com/questions/53580240/ios-12-0-alternative-to-using-deprecated-archiverootobjecttofile) – Himanshu Patel Dec 08 '20 at 10:33
  • yes, i see this post. but 1. unarchivedObjectOfClass is deprecated too :) 2. i try decodeTopLevelObjectForKey, but not work, or i understand how neet to use it remarks - i decode MuttableArray of elements class Favorite. 'self.favorites[0] - Favorite[data1][type1] self.favorites[1] - Favorite[data2][type2] ..... self.favorites[n] - Favorite[dataN][typeN] ' then need: 1. Unarhive MuttableArray 2. Decode each elements of Array as Favorite Class – BeattleJeuse Dec 08 '20 at 13:31
  • I found solution. Need use **superclass** `id encodedData = [NSKeyedUnarchiver unarchivedObjectOfClass:[Favorite superclass] fromData:data error:&error]; if(error!=nil) { } else { self.favorites = encodedData;` – BeattleJeuse Dec 08 '20 at 14:20

1 Answers1

1

You can use

[ NSKeyedUnarchiver unarchivedObjectOfClass:[ NSObject class ] fromData:data error:&error ];

It work with warning in log

[Foundation] *** -[NSKeyedUnarchiver validateAllowedClass:forKey:]: NSSecureCoding allowed classes list contains [NSObject class], which bypasses security by allowing any Objective-C class to be implicitly decoded. Consider reducing the scope of allowed classes during decoding by listing only the classes you expect to decode, or a more specific base class than NSObject. This will become an error in the future. Allowed class list: {( "'NSObject' (0x1d9e91e08) [/usr/lib]" )}

Better would be using

[ NSKeyedUnarchiver unarchivedObjectOfClasses:[ NSSet setWithObjects:[ NSArray class ], [ Favorite class ], nil ] fromData:data error:&error ];

You may need [ NSDate class ] or something, that contains in your class "Favorite"