0

I need to save an NSMutableArray to disk in order to store my application data. I know there are a lot of similiar questions out there but none of them I found covers my question.

I do not want to integrate Core Data just for saving one NSMutableArray. Normally I would go for implementing the NSCoding protocol and using NSKeyedUnarchiver. Unfortunately, my data model class has some foreign classes from a library which do not implement the NSCoding protocol.

So what is the best way for me to store my array?

This is what I tried but because of the given reasons it won't work:

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <ForeignFramework/ForeignFramework.h>

@interface DEModelClass : NSObject <NSCoding>

@property (nonatomic,strong) ForeignFramework *foreignFramework;
@property (nonatomic,strong) UIImage *image;
@property (nonatomic,copy) NSNumber *number1;
@property (nonatomic,copy) NSNumber *number2;

@end


#define kEncodeKeyForeign   @"kEncodeKeyForeign"
#define kEncodeKeyImage      @"kEncodeKeyImage"
#define kEncodeKeyNumber1     @"kEncodeKeyNumber1"
#define kEncodeKeyNumber2     @"kEncodeKeyNumber2"


#pragma mark - NSCoding
- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.foreignFramework   forKey:kEncodeKey];
    [aCoder encodeObject:self.image  forKey:kEncodeKeyImage];
    [aCoder encodeObject:self.number1 forKey:kEncodeKeyNumber1];
    [aCoder encodeObject:self.number2 forKey:kEncodeKeyNumber2];

}

- (id)initWithCoder:(NSCoder *)aDecoder {
    if ((self = [super init]))
    {
        self.foreignFramework = [aDecoder decodeObjectForKey:kEncodeKeyForeign];
        self.image    = [aDecoder decodeObjectForKey:kEncodeKeyImage];
        self.number1   = [aDecoder decodeObjectForKey:kEncodeKeyNumber1];
        self.number2   = [aDecoder decodeObjectForKey:kEncodeKeyNumber2];

    }
    return self;
}
5
  • How about using NSUserDefaults ? Commented Apr 8, 2015 at 12:36
  • Well NSUserDefaults is not really the right location to store a whole data array, right ? Commented Apr 8, 2015 at 12:37
  • Why not? One other option would be to create a plist file programmatically and store your data in it, and retrieve when needed. Check out THIS. Apple's own code to save data to plist. Commented Apr 8, 2015 at 12:43
  • There is no standard way to "serialize" an arbitrary class. If the class is not one of those that the system knows how to deal with you must invent your own scheme, perhaps employing JSON. Commented Apr 8, 2015 at 12:44
  • 1
    The link I shared above along with THIS will handle image, number1 and number2. Can't say anything about foreignFramework . Commented Apr 8, 2015 at 12:48

1 Answer 1

2

You should use the NSCoding protocol and you can use it.

A. I assume that you know, which properties of the foreign classes to store. (Probably that data that let you re-instantiate instance objects at loading.) If not, there is no way to store them. And of course, Cocoa, NSArray, $whatever cannot know it. These are generic.

B. When you are done with selecting the properties to store, simply add a category to the foreign classes that do the job for you:

@interface ForeignClass (MyCodingAddition)
- (void)encodeWithCoder:(NSCoder*)encoder;
- (id)initWithCoder:(NSCoder*)decoder;
@end

@implementation ForeignClass (MyCodingAddition)
- (void)encodeWithCoder:(NSCoder*)encoder
{
  [coder encodeObject:self.property withKey:…]
  …
}

- (id)initWithCoder:(NSCoder*)decoder
{
  self = [super init];
  if (self)
  {
    self.property = [decode objectForKey:…];
    …
  }
  return self;
}
@end
Sign up to request clarification or add additional context in comments.

1 Comment

Keine Sache, ist allerdings in Safari getippt.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.