I just created 2 model class for my iOS app:
HALUserDefaults
represents the persisted data in my app. It has the ability to both retrieve persisted data and store new data.HALParseConnection
represents the connection to my Backend service Parse.com
These 2 models were made to work with each other.
HALUserDefaults.h:
#import <Foundation/Foundation.h>
@interface HALUserDefaults : NSObject
#pragma mark - Instance Methods
- (NSArray *)retrieveHalfImageMessages;
- (NSArray *)retrieveFullImageMessages;
- (void)storeHalfImageMessages:(id)halfImageMessages;
- (void)storeFullImageMessages:(id)fullImageMessages;
@end
HALUserDefaults.m:
#import "HALUserDefaults.h"
@interface HALUserDefaults ()
@end
@implementation HALUserDefaults
- (NSArray *)retrieveHalfImageMessages
{
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [standardDefaults objectForKey:@"halfImageMessages"];
NSArray *retrievedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
return retrievedArray;
}
- (NSArray *)retrieveFullImageMessages
{
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [standardDefaults objectForKey:@"fullImageMessages"];
NSArray *retreivedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
return retreivedArray;
}
- (void)storeHalfImageMessages:(id)halfImageMessages
{
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
[standardDefaults setObject:[NSKeyedArchiver archivedDataWithRootObject:halfImageMessages] forKey:@"halfImageMessages"];
[standardDefaults synchronize];
}
- (void)storeFullImageMessages:(id)fullImageMessages
{
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
[standardDefaults setObject:[NSKeyedArchiver archivedDataWithRootObject:fullImageMessages] forKey:@"fullImageMessages"];
[standardDefaults synchronize];
}
@end
HALParseConnection.h:
#import <Foundation/Foundation.h>
#import <Parse/Parse.h>
@interface HALParseConnection : NSObject
#pragma mark - Instance Methods
- (void)performQuery;
- (void)performQuery2and3;
@end
HALParseConnection.m:
#import "HALParseConnection.h"
#import "HALUserDefaults.h"
@interface HALParseConnection ()
@end
@implementation HALParseConnection
- (void)performQuery
{
// Setup and execute the query
PFQuery *query = [PFQuery queryWithClassName:@"Messages"];
[query whereKey:@"recipientIds" equalTo:[[PFUser currentUser]objectId]];
[query whereKey:@"halfOrFull" equalTo:@"half"];
[query whereKey:@"didRespond" notEqualTo:[[PFUser currentUser]objectId]];
[query orderByDescending:@"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(@"There was an error: %@", error);
} else {
// Store the returned objects and post notification
HALUserDefaults *userDefaults = [[HALUserDefaults alloc]init];
[userDefaults storeHalfImageMessages:objects];
[[NSNotificationCenter defaultCenter] postNotificationName:@"queryHasFinished"
object:self
userInfo:nil];
}
}];
}
- (void)performQuery2and3
{
// Setup and execute the query
PFQuery *query2 = [PFQuery queryWithClassName:@"Messages"];
[query2 whereKey:@"senderId" equalTo:[[PFUser currentUser]objectId]];
[query2 whereKey:@"halfOrFull" equalTo:@"full"];
PFQuery *query3 = [PFQuery queryWithClassName:@"Messages"];
[query3 whereKey:@"recipientIds" equalTo:[[PFUser currentUser]objectId]];
[query3 whereKey:@"halfOrFull" equalTo:@"full"];
PFQuery *query2and3 = [PFQuery orQueryWithSubqueries:[NSArray arrayWithObjects:query2,query3,nil]];
[query2and3 orderByDescending:@"createdAt"];
[query2and3 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(@"There was an error: %@", error);
} else {
// Store the returned objects and post notification
HALUserDefaults *userDefaults = [[HALUserDefaults alloc]init];
[userDefaults storeFullImageMessages:objects];
[[NSNotificationCenter defaultCenter] postNotificationName:@"query2and3HasFinished"
object:self
userInfo:nil];
}
}];
}
@end
Here is a small sample of my View Controller file, to show I am using my 2 new classes:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self retreiveStoredMessages];
[self parseQueries];
}
#pragma mark - Stored Data Methods
- (void)retreiveStoredMessages
{
self.halfImageMessages = [[NSArray alloc]init];
self.fullImageMessages = [[NSArray alloc]init];
HALUserDefaults *userDefaults = [[HALUserDefaults alloc]init];
// Retreive any stored messages
self.halfImageMessages = [userDefaults retrieveHalfImageMessages];
self.fullImageMessages = [userDefaults retrieveFullImageMessages];
// Reload table view
[self.tableView reloadData];
}
#pragma mark - Parse Query Methods
- (void)parseQueries
{
// Execute Parse queries
HALParseConnection *parseConnection = [[HALParseConnection alloc]init];
[parseConnection performQuery];
[parseConnection performQuery2and3];
// Register for notifications that are posted in HALParseConnection class
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(parseQueryFinished)
name:@"queryHasFinished"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(parseQuery2and3Finished)
name:@"query2and3HasFinished"
object:nil];
}
- (void)parseQueryFinished
{
// Retreive newly updated halfImageMessages and remove observer
HALUserDefaults *userDefaults = [[HALUserDefaults alloc]init];
self.halfImageMessages = [userDefaults retrieveHalfImageMessages];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:@"queryHasFinished"
object:nil];
[self.tableView reloadData];
}
- (void)parseQuery2and3Finished
{
// Retreive newly updated fullImageMessages and remove observer
HALUserDefaults *userDefaults = [[HALUserDefaults alloc]init];
self.fullImageMessages = [userDefaults retrieveFullImageMessages];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:@"query2and3HasFinished"
object:nil];
[self.tableView reloadData];
}
Here are some of the key things that I am looking for feedback on:
MVC - The main point of these 2 new classes is to move my app towards the MVC design pattern. I want to make sure that this code represents and implements MVC well.
Naming conventions - I want to make sure that the names I am choosing for my methods, classes, and properties are following best practices.
Notifications - I want to make sure that I am properly using
NSNotificationCenter
. You will notice that in theHALParseConnection
class that I am posting notifications inside my blocks when there are no errors with thefindObjectsInBackgroundWithBlock
method calls.I post these notifications because I need to know when the asynchronous method has been completed.
You will also notice that I register my View Controller for these notifications, and execute various methods in response to the notifications being posted.
In regards to my use of NSUserDefaults
to persist data, I already understand that I should be using Core Data instead.