When you store an array or dictionary into NSUserDefaults it gets condensed into a plist on disk. This means your custom object needs to be converted into a format that can be stored in a plist. There are lots of ways to do this depending on the type of data your object holds but this method will work with pretty much any custom object and should be pretty robust.
Thanks to Apple's well designed frameworks, its pretty simple to achieve :)
In your Program.h add the <NSCoding> protocol.
@interface Program : NSObject <NSCoding>
Then in your Program.m make sure you implement the following methods.
#pragma mark - NSCoding
-(void)encodeWithCoder:(NSCoder *)encoder
{
// For each of the Program's properties that needs to be stored.
[encoder encodeObject:self.property forKey:@"PropertyKey"];
}
-(id)initWithCoder:(NSCoder *)decoder
{
if (self=[super init]) {
self.property = [decoder decodeObjectForKey:@"PropertyKey"];
}
return self;
}
This protocol and its methods allow your custom object for be encoded and decoded on the fly. This is important so we can get your objects into the right format.
Next we are going to archive your array before storing it. So replace your code with this:
// Old Line
// [defaults setObject:tempArrayOfPrograms forKey:@"arrayOfPrograms"];
// New Lines
id archivedObject = [NSKeyedArchiver archivedDataWithRootObject:tempArrayOfPrograms];
[defaults setObject:archivedObject forKey:@"arrayOfPrograms"];
Now the final step is to make sure you're unarchiving on the way out. So anywhere you load the array from NSUserDefaults make sure you unarchive it.
// Get the archived array.
id archivedObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"arrayOfPrograms"];
// Unarchive the array.
NSArray *unarchivedArray = [NSKeyedUnarchiver unarchiveObjectWithData:archivedObject];
// Its already a mutable array if you put a mutable array in but just to be safe.
NSMutableArray *arrayFromDefaults = [NSMutableArray arrayWithArray:unarchivedArray];