Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 3 commits
  • 11 files changed
  • 0 commit comments
  • 1 contributor
View
47 Homepwner/Homepwner/BNRImageStore.m
@@ -11,6 +11,8 @@ @interface BNRImageStore () {
NSMutableDictionary *_dictionary;
}
+- (NSString *)imagePathForKey:(NSString *)key;
+
@end
@implementation BNRImageStore
@@ -40,13 +42,56 @@ - (id)init {
- (void)setImage:(UIImage *)i forKey:(NSString *)key {
[_dictionary setObject:i forKey:key];
+
+ // Create full path for image
+ NSString *imagePath = [self imagePathForKey:key];
+
+ // Turn image into JPEG data
+ NSData *d = UIImageJPEGRepresentation(i, 0.8);
+
+ // Write it to full path
+ [d writeToFile:imagePath atomically:YES];
+
}
- (UIImage *)imageForKey:(NSString *)key {
- return [_dictionary objectForKey:key];
+
+ // If possible, get it from the dictionary
+ UIImage *result = [_dictionary objectForKey:key];
+
+ if (!result) {
+ // Create UIImage object fro file
+ result = [UIImage imageWithContentsOfFile:[self imagePathForKey:key]];
+
+ // If we found an image on the file system, place it into the cache
+ if (result) {
+ [_dictionary setObject:result forKey:key];
+ }
+ else {
+ NSLog(@"Error: unable to find %@", [self imageForKey:key]);
+ }
+ }
+
+ return result;
}
- (void)removeImageForKey:(NSString *)key {
+ if (!key) {
+ return;
+ }
+
[_dictionary removeObjectForKey:key];
+
+ NSString *path = [self imagePathForKey:key];
+ [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
}
+
+- (NSString *)imagePathForKey:(NSString *)key {
+ NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+
+ NSString *documentdirectory = [documentDirectories objectAtIndex:0];
+
+ return [documentdirectory stringByAppendingPathComponent:key];
+}
+
@end
View
16 Homepwner/Homepwner/BNRItem.h
@@ -8,15 +8,7 @@
#import <Foundation/Foundation.h>
-@interface BNRItem : NSObject
-{
-}
-
-+ (id)randomItem;
-
-- (id)initWithItemName:(NSString *)name
- valueInDollars:(int)value
- serialNumber:(NSString *)sNumber;
+@interface BNRItem : NSObject <NSCoding>
@property (nonatomic, strong) BNRItem *containedItem;
@property (nonatomic, weak) BNRItem *container;
@@ -27,4 +19,10 @@
@property (nonatomic, readonly, strong) NSDate *dateCreated;
@property (nonatomic, copy) NSString *imageKey;
++ (id)randomItem;
+
+- (id)initWithItemName:(NSString *)name
+ valueInDollars:(int)value
+ serialNumber:(NSString *)sNumber;
+
@end
View
28 Homepwner/Homepwner/BNRItem.m
@@ -26,8 +26,8 @@ + (id)randomItem {
// Note: The % operator, called the modulo operator, gives
// you the remainder. So adjectiveIndex is a random number
// from 0 to 2 inclusive.
- NSUInteger adjectiveIndex = (NSUInteger)(rand() % [randomAdjectiveList count]);
- NSUInteger nounIndex = (NSUInteger)(rand() % [randomNounList count]);
+ NSUInteger adjectiveIndex = (NSUInteger) (rand() % [randomAdjectiveList count]);
+ NSUInteger nounIndex = (NSUInteger) (rand() % [randomNounList count]);
// Note that NSInteger is not an object, but a type definition
// for "unsigned long"
@@ -91,6 +91,30 @@ - (NSString *)description {
return descriptionString;
}
+- (void)encodeWithCoder:(NSCoder *)aCoder {
+ [aCoder encodeObject:[self itemName] forKey:@"itemName"];
+ [aCoder encodeObject:[self serialNumber] forKey:@"serialNumber"];
+ [aCoder encodeObject:[self dateCreated] forKey:@"dateCreated"];
+ [aCoder encodeObject:[self imageKey] forKey:@"imageKey"];
+
+ [aCoder encodeInt:[self valueInDollars] forKey:@"valueInDollars"];
+}
+
+- (id)initWithCoder:(NSCoder *)aDecoder {
+ self = [super init];
+ if (self) {
+ [self setItemName:[aDecoder decodeObjectForKey:@"itemName"]];
+ [self setSerialNumber:[aDecoder decodeObjectForKey:@"serialNumber"]];
+ [self setImageKey:[aDecoder decodeObjectForKey:@"imageKey"]];
+
+ [self setValueInDollars:[aDecoder decodeIntForKey:@"valueInDollars"]];
+
+ dateCreated = [aDecoder decodeObjectForKey:@"dateCreated"];
+ }
+
+ return self;
+}
+
- (void)dealloc {
NSLog(@"Destroyed: %@ ", self);
}
View
7 Homepwner/Homepwner/BNRItemStore.h
@@ -6,18 +6,23 @@
#import <Foundation/Foundation.h>
+
@class BNRItem;
@interface BNRItemStore : NSObject
+ (BNRItemStore *)sharedStore;
-@property (nonatomic, strong, readonly) NSArray *allItems;
+@property(nonatomic, strong, readonly) NSArray *allItems;
- (BNRItem *)createItem;
- (void)removeItem:(BNRItem *)item;
- (void)moveItemAtIndex:(int)from toIndex:(int)to;
+- (NSString *)itemArchivePath;
+
+- (BOOL)saveChanges;
+
@end
View
34 Homepwner/Homepwner/BNRItemStore.m
@@ -7,6 +7,7 @@
#import "BNRItemStore.h"
#import "BNRItem.h"
+#import "BNRImageStore.h"
@interface BNRItemStore () {
NSMutableArray *_allItems;
@@ -33,21 +34,28 @@ + (id)allocWithZone:(NSZone *)zone {
- (id)init {
self = [super init];
if (self) {
- _allItems = [[NSMutableArray alloc] init];
+ NSString *path = [self itemArchivePath];
+ _allItems = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
+
+ // If the array hadn't been saved previously, create a new empty one
+ if (!_allItems) {
+ _allItems = [[NSMutableArray alloc] init];
+ }
}
return self;
}
- (BNRItem *)createItem {
- BNRItem *p = [BNRItem randomItem];
-
+ BNRItem *p = [[BNRItem alloc] init];
[_allItems addObject:p];
-
return p;
}
- (void)removeItem:(BNRItem *)item {
+ NSString *key = [item imageKey];
+ [[BNRImageStore sharedStore] removeImageForKey:key];
+
// We don't use "removeObject" here as that the message "isEqual" is sent to each object which the object can override
// Using removeObjectIdenticalTo ensures we're removing the same object passed in
[_allItems removeObjectIdenticalTo:item];
@@ -65,4 +73,22 @@ - (void)moveItemAtIndex:(int)from toIndex:(int)to {
}
+- (NSString *)itemArchivePath {
+ NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,
+ YES);
+
+ // Get one and only document directory from that list
+ NSString *documentDirectory = [documentDirectories objectAtIndex:0];
+
+ return [documentDirectory stringByAppendingPathComponent:@"items.archive"];
+}
+
+- (BOOL)saveChanges {
+ // returns success or failure
+ NSString *path = [self itemArchivePath];
+
+ return [NSKeyedArchiver archiveRootObject:_allItems toFile:path];
+}
+
+
@end
View
7 Homepwner/Homepwner/DetailViewController.h
@@ -12,5 +12,10 @@
@interface DetailViewController : UIViewController <UIImagePickerControllerDelegate, UITextFieldDelegate,
UINavigationControllerDelegate, UIPopoverControllerDelegate>
-@property (nonatomic, strong) BNRItem *item;
+
+@property(nonatomic, strong) BNRItem *item;
+@property (nonatomic, copy) void (^dismissBlock)(void);
+
+- (id)initForViewItem:(BOOL)isNew;
+
@end
View
58 Homepwner/Homepwner/DetailViewController.m
@@ -9,6 +9,7 @@
#import "DetailViewController.h"
#import "BNRItem.h"
#import "BNRImageStore.h"
+#import "BNRItemStore.h"
@interface DetailViewController () {
UIPopoverController *_imagePickerPopover;
@@ -21,6 +22,7 @@ @interface DetailViewController () {
@property(weak, nonatomic) IBOutlet UIToolbar *toolbarView;
@property(weak, nonatomic) IBOutlet UIImageView *imageView;
@property(weak, nonatomic) IBOutlet UIButton *deletePictureButton;
+@property(weak, nonatomic) IBOutlet UIBarButtonItem *cameraButton;
- (IBAction)backgroundTapped:(id)sender;
@@ -44,11 +46,48 @@ - (id)init {
return self;
}
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
+ @throw [NSException exceptionWithName:@"Wrong initializer" reason:@"Use initForNewItem:"
+ userInfo:nil];
+}
+
- (void)setItem:(BNRItem *)item {
_item = item;
[[self navigationItem] setTitle:[[self item] itemName]];
}
+- (id)initForViewItem:(BOOL)isNew {
+ self = [super initWithNibName:@"DetailViewController" bundle:nil];
+
+ if (self) {
+ if (isNew) {
+ UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
+ target:self
+ action:@selector(save:)];
+ [[self navigationItem] setRightBarButtonItem:doneItem];
+
+ UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+ target:self
+ action:@selector(cancel:)];
+ [[self navigationItem] setLeftBarButtonItem:cancelItem];
+ }
+ }
+
+ return self;
+}
+
+- (void)save:(id)save {
+ [[self presentingViewController] dismissViewControllerAnimated:YES completion:[self dismissBlock]];
+}
+
+- (void)cancel:(id)cancel {
+ // If the user cancalled, then remove the BNRItem from the store
+ [[BNRItemStore sharedStore] removeItem:[self item]];
+
+ [[self presentingViewController] dismissViewControllerAnimated:YES completion:[self dismissBlock]];
+}
+
+
- (IBAction)deletePicture:(id)sender {
[[BNRImageStore sharedStore] removeImageForKey:[[self item] imageKey]];
[[self item] setImageKey:nil];
@@ -135,10 +174,10 @@ - (void)viewWillAppear:(BOOL)animated {
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
- [self saveItem];
+ [self saveItem:nil];
}
-- (void)saveItem {
+- (void)saveItem:(id)o {
// Save changes to item
BNRItem *item = [self item];
[item setItemName:[[self nameField] text]];
@@ -147,7 +186,7 @@ - (void)saveItem {
}
- (void)finishEditing {
- [self saveItem];
+ [self saveItem:nil];
[[self view] endEditing:YES];
[[self navigationController] popToRootViewControllerAnimated:YES];
}
@@ -243,4 +282,17 @@ - (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
+
+- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
+ if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
+ [[self imageView] setHidden:YES];
+ [[self cameraButton] setEnabled:NO];
+ }
+ else {
+ [[self imageView] setHidden:NO];
+ [[self cameraButton] setEnabled:YES];
+ }
+ }
+}
@end
View
20 Homepwner/Homepwner/DetailViewController.xib
@@ -337,6 +337,14 @@
<int key="connectionID">164</int>
</object>
<object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">cameraButton</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="202025213"/>
+ </object>
+ <int key="connectionID">421</int>
+ </object>
+ <object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">backgroundTapped:</string>
<reference key="source" ref="191373211"/>
@@ -1067,7 +1075,7 @@
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
- <int key="maxID">419</int>
+ <int key="maxID">421</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -1094,15 +1102,21 @@
</object>
</dictionary>
<dictionary class="NSMutableDictionary" key="outlets">
+ <string key="cameraButton">UIBarButtonItem</string>
<string key="dateLabel">UILabel</string>
<string key="deletePictureButton">UIButton</string>
<string key="imageView">UIImageView</string>
<string key="nameField">UITextField</string>
+ <string key="pictureButton">UIBarButtonItem</string>
<string key="serialField">UITextField</string>
<string key="toolbarView">UIToolbar</string>
<string key="valueField">UITextField</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <object class="IBToOneOutletInfo" key="cameraButton">
+ <string key="name">cameraButton</string>
+ <string key="candidateClassName">UIBarButtonItem</string>
+ </object>
<object class="IBToOneOutletInfo" key="dateLabel">
<string key="name">dateLabel</string>
<string key="candidateClassName">UILabel</string>
@@ -1119,6 +1133,10 @@
<string key="name">nameField</string>
<string key="candidateClassName">UITextField</string>
</object>
+ <object class="IBToOneOutletInfo" key="pictureButton">
+ <string key="name">pictureButton</string>
+ <string key="candidateClassName">UIBarButtonItem</string>
+ </object>
<object class="IBToOneOutletInfo" key="serialField">
<string key="name">serialField</string>
<string key="candidateClassName">UITextField</string>
View
3 Homepwner/Homepwner/Homepwner-Info.plist
@@ -30,9 +30,10 @@
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
- <string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationPortrait</string>
</array>
</dict>
</plist>
View
11 Homepwner/Homepwner/HomepwnerAppDelegate.m
@@ -8,6 +8,7 @@
#import "HomepwnerAppDelegate.h"
#import "ItemsViewController.h"
+#import "BNRItemStore.h"
@implementation HomepwnerAppDelegate
@@ -35,8 +36,14 @@ - (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
- // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
- // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+
+ BOOL success = [[BNRItemStore sharedStore] saveChanges];
+ if (success) {
+ NSLog(@"Saved BNRItems");
+ }
+ else{
+ NSLog(@"Could not save any of the BNRItems");
+ }
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
View
26 Homepwner/Homepwner/ItemsViewController.m
@@ -73,15 +73,20 @@ - (IBAction)addNewItem:(id)sender {
/// Create a new BNRItem and add it to the store
BNRItem *newItem = [[BNRItemStore sharedStore] createItem];
- // / Figure out where that item is in the array
- int lastRow = [[[BNRItemStore sharedStore] allItems] indexOfObject:newItem];
- NSIndexPath *ip = [NSIndexPath indexPathForRow:lastRow inSection:0];
-
- // Insert into table
- // We could get a reference to the UITableView instance by using [self view] but as this is inherited
- // from UIViewController, it has no knowledge about what type of view it is
- // Using [self tableView] tells the compiler (and your IDE) that we're dealing with a view of type UITableView
- [[self tableView] insertRowsAtIndexPaths:@[ip] withRowAnimation:UITableViewRowAnimationTop];
+ DetailViewController *detailViewController = [[DetailViewController alloc] initForViewItem:YES];
+
+ [detailViewController setItem:newItem];
+
+ [detailViewController setDismissBlock:^{
+ [[self tableView] reloadData];
+ }];
+
+ UINavigationController *navController = [[UINavigationController alloc]
+ initWithRootViewController:detailViewController];
+
+ [navController setModalPresentationStyle:UIModalPresentationFormSheet];
+
+ [self presentViewController:navController animated:YES completion:nil];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
@@ -102,7 +107,8 @@ - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sou
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
- DetailViewController *detailViewController = [[DetailViewController alloc] init];
+
+ DetailViewController *detailViewController = [[DetailViewController alloc] initForViewItem:NO];
NSArray *items = [[BNRItemStore sharedStore] allItems];
BNRItem *selectedItem = [items objectAtIndex:[indexPath row]];

No commit comments for this range

Something went wrong with that request. Please try again.