diff --git a/Classes/ChartLoader.m b/Classes/ChartLoader.m index f768803..c1240f0 100644 --- a/Classes/ChartLoader.m +++ b/Classes/ChartLoader.m @@ -81,6 +81,7 @@ - (BOOL)shouldContinueWithStatusCode:(NSInteger)statusCode if (place.chart) { [self.context deleteObject:place.chart]; + place.chart = nil; [self.context saveAndLogErrors]; } return NO; diff --git a/Classes/ChartObservation.h b/Classes/ChartObservation.h new file mode 100644 index 0000000..670ae6b --- /dev/null +++ b/Classes/ChartObservation.h @@ -0,0 +1,50 @@ +// +// ChartObservation.h +// Slake +// +// Created by Quentin Leseney on 13/01/11. +// Copyright (c) 2010 Bureau of Meteorology +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +// Light version of Observation class and not a managed object + +@class Measurement; + +@interface ChartObservation : NSObject +{ + NSDate* _date; + Measurement* _percentageVolume; + Measurement* _volume; +} + +@property (nonatomic, retain) NSDate* date; +@property (nonatomic, retain) Measurement* percentageVolume; +@property (nonatomic, retain) Measurement* volume; + ++ (ChartObservation*)chartObservationWithDate:(NSDate*)date + percentageVolume:(Measurement*)percentageVolume + volume:(Measurement*)volume; + +@end diff --git a/Classes/ChartObservation.m b/Classes/ChartObservation.m new file mode 100644 index 0000000..19e4e30 --- /dev/null +++ b/Classes/ChartObservation.m @@ -0,0 +1,61 @@ +// +// ChartObservation.m +// Slake +// +// Created by Quentin Leseney on 13/01/11. +// Copyright (c) 2010 Bureau of Meteorology +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#import "ChartObservation.h" +#import "Measurement.h" + +@implementation ChartObservation + +@synthesize date = _date; +@synthesize percentageVolume = _percentageVolume; +@synthesize volume = _volume; + +- (void)dealloc +{ + [_date release]; + [_percentageVolume release]; + [_volume release]; + [super dealloc]; +} + ++ (ChartObservation*)chartObservationWithDate:(NSDate*)date + percentageVolume:(Measurement*)percentageVolume + volume:(Measurement*)volume +{ + ChartObservation* res = [[[ChartObservation alloc] init] autorelease]; + if (res) { + res.date = date; + res.percentageVolume = percentageVolume; + res.volume = volume; + } + return res; +} + +@end \ No newline at end of file diff --git a/Classes/ChartViewController.h b/Classes/ChartViewController.h index 9363796..b9ade6a 100644 --- a/Classes/ChartViewController.h +++ b/Classes/ChartViewController.h @@ -39,12 +39,10 @@ @protocol MarkerLabelDelegate -- (void)showLabelsCurrentYearDate:(NSDate*)date - currentYearPercentage:(Measurement*)currentYearPercentage - currentYearVolume:(Measurement*)currentYearVolume - lastYearDate:(NSDate*)date - lastYearPercentage:(Measurement*)lastYearPercentage - lastYearVolume:(Measurement*)lastYearVolume +// observations is to be an array of ChartObservation, starting from current year, last year... +// if there is no value for a given year, ChartObservation with date and +// nil Measurement for volume and percentage should be given +- (void)showLabelsForChartObservations:(NSArray*)observations awayFrom:(float)viewXPosition; - (void)hideLabels; @@ -70,8 +68,7 @@ id _chartDelegate; int _xCoordinate; float _viewXPosition; - NSNumber* _currentYearYCoordinate; - NSNumber* _lastYearYCoordinate; + NSMutableArray* _yCoordinates; } @property (nonatomic, retain) Place* place; diff --git a/Classes/ChartViewController.m b/Classes/ChartViewController.m index 71c01e4..6f5ff58 100644 --- a/Classes/ChartViewController.m +++ b/Classes/ChartViewController.m @@ -34,6 +34,7 @@ #import "ChartSeries.h" #import "ChartDataset.h" #import "ChartValue.h" +#import "ChartObservation.h" #import "Measurement.h" #import "Place.h" #import "Observation.h" @@ -46,8 +47,7 @@ @interface ChartViewController () // private //marker @property (nonatomic) int xCoordinate; @property (nonatomic) float viewXPosition; -@property (nonatomic, retain) NSNumber* currentYearYCoordinate; -@property (nonatomic, retain) NSNumber* lastYearYCoordinate; +@property (nonatomic, retain) NSMutableArray* yCoordinates; - (void)updateChart:(Chart*)chart; @@ -58,12 +58,19 @@ - (void)createPlotSpace; @implementation ChartViewController +//percentage value at the top of the visible chart view +CGFloat const kChartTopYValue = 1.1f; + +//Invisible negative padding to fix a plot rendering issue. +//Anything over kChartTopYValue is not visible but still drawn so that the +//gradient below the plot is not broken +CGFloat const kMaxYValue = 4.0f; + @synthesize graph; @synthesize markerPlot = _markerPlot; @synthesize xCoordinate = _xCoordinate; @synthesize viewXPosition = _viewXPosition; -@synthesize currentYearYCoordinate = _currentYearYCoordinate; -@synthesize lastYearYCoordinate = _lastYearYCoordinate; +@synthesize yCoordinates = _yCoordinates; @synthesize chartDelegate = _chartDelegate; - (void)dealloc @@ -72,8 +79,7 @@ - (void)dealloc [graph release]; [place release]; [_markerPlot release]; - [_currentYearYCoordinate release]; - [_lastYearYCoordinate release]; + [_yCoordinates release]; [super dealloc]; } @@ -82,11 +88,16 @@ - (void)setPlace:(Place *)newPlace { if (newPlace != place) { - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextObjectsDidChangeNotification object:[place managedObjectContext]]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:NSManagedObjectContextObjectsDidChangeNotification + object:[place managedObjectContext]]; [place release]; place = [newPlace retain]; _chart = place.chart; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(objectsDidChangeNotification:) name:NSManagedObjectContextObjectsDidChangeNotification object:[place managedObjectContext]]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(objectsDidChangeNotification:) + name:NSManagedObjectContextObjectsDidChangeNotification + object:[place managedObjectContext]]; } } @@ -103,8 +114,7 @@ - (void)viewDidUnload // e.g. self.myOutlet = nil; self.graph = nil; self.markerPlot = nil; - self.currentYearYCoordinate = nil; - self.lastYearYCoordinate = nil; + self.yCoordinates = nil; } @@ -125,60 +135,55 @@ - (void)objectsDidChangeNotification:(NSNotification*)notification - (void)updateChart:(Chart*)chart { assert([NSThread isMainThread]); - + //remove existing plots for (CPPlot* plot in [self.graph allPlots]) { [self.graph removePlot:plot]; } - //dicard potential marker + //discard potential marker self.markerPlot = nil; [self.markerLabelDelegate hideLabels]; - NSInteger currentYear = [[[NSCalendar gregorian] components:NSYearCalendarUnit fromDate:chart.xEnd] year]; - NSInteger previousYear = currentYear - 1; + double red = 0.0/255; + double green = 186.0/255; + double blue = 255.0/255; - ChartSeries* currentYearSeries = nil; - ChartSeries* lastYearSeries = nil; - for (ChartSeries* series in chart.series) + NSInteger currentYear = [[[NSCalendar gregorian] components:NSYearCalendarUnit fromDate:chart.xEnd] year]; + NSSortDescriptor *yearDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"year" ascending:NO] autorelease]; + NSArray* orderedSeries = [[chart.series allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObject:yearDescriptor]]; + for (ChartSeries* series in orderedSeries) { - if ([series.year intValue] == currentYear) + float alpha = 0.0f; + int year = [series.year intValue]; + if (year == currentYear) { - currentYearSeries = series; + alpha = 1.0f; } - else if ([series.year intValue] == previousYear) + else if (year == currentYear - 1) { - lastYearSeries = series; + alpha = 0.35f; } - } - NSArray* orderedSeries = [NSArray arrayWithObjects:currentYearSeries, lastYearSeries, nil]; - - for (ChartSeries* series in orderedSeries) - { - float alpha = 0.0f; - if ([series.year intValue] == currentYear) + else if (year == currentYear - 2) { - alpha = 1.0f; + alpha = 0.15f; } - else if ([series.year intValue] == previousYear) + else { - alpha = 0.3f; + continue; } - + + CPColor* topPlotColor = [CPColor colorWithComponentRed:red green:green blue:blue alpha:alpha-0.15]; + CPColor* bottomPlotColor = [CPColor colorWithComponentRed:red green:green blue:blue alpha:alpha-0.3]; + CPColor* lineColor = [CPColor colorWithComponentRed:1.0 green:1.0 blue:1.0 alpha:alpha]; for (ChartDataset* dataset in series.datasets) { - CPScatterPlot *plot = [[[CPScatterPlot alloc] - initWithFrame:CGRectNull] autorelease]; - plot.dataLineStyle.lineColor = [CPColor colorWithComponentRed:1.0 green:1.0 blue:1.0 alpha:alpha]; + CPScatterPlot *plot = [[[CPScatterPlot alloc] initWithFrame:CGRectNull] autorelease]; + plot.dataLineStyle.lineColor = lineColor; plot.dataLineStyle.lineWidth = 2.0f; plot.dataSource = dataset; CPGradient* plotGradient = [[[CPGradient alloc] init] autorelease]; - double red = 0.0/255; - double green = 186.0/255; - double blue = 255.0/255; - CPColor* topPlotColor = [CPColor colorWithComponentRed:red green:green blue:blue alpha:alpha-0.15]; - CPColor* bottomPlotColor = [CPColor colorWithComponentRed:red green:green blue:blue alpha:alpha-0.3]; plotGradient = [plotGradient addColorStop:topPlotColor atPosition:0]; plotGradient = [plotGradient addColorStop:bottomPlotColor atPosition:1]; plotGradient.angle = 270.0f; @@ -187,7 +192,6 @@ - (void)updateChart:(Chart*)chart plot.areaBaseValue = CPDecimalFromString(@"0.0"); [self.graph addPlot:plot]; - //NSLog(@"ScatterPlot: %@", plot); } } [self.chartDelegate chartUpdated]; @@ -200,7 +204,7 @@ - (void)createPlotSpace plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromInteger(1) length:CPDecimalFromInteger(366)]; plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0f) - length:CPDecimalFromFloat(1.1f)]; + length:CPDecimalFromFloat(kMaxYValue)]; CPColor* colorAxis = [CPColor colorWithComponentRed:210.0/255 green:240.0/255 blue:255/255 alpha:1]; CPLineStyle* lineStyle = [CPLineStyle lineStyle]; @@ -287,19 +291,17 @@ - (void)viewDidLoad //CorePlot chart rendering self.graph = [[[CPXYGraph alloc] initWithFrame:CGRectZero] autorelease]; - self.graph.paddingLeft = 0.0; - self.graph.paddingBottom = 0.0; - self.graph.paddingRight = 0.0; - self.graph.paddingTop = 0.0; - - self.graph.plotAreaFrame.paddingLeft = 0.0; - self.graph.plotAreaFrame.paddingBottom = 0.0; - self.graph.plotAreaFrame.paddingRight = 0.0; - self.graph.plotAreaFrame.paddingTop = 0.0; //10.0 + self.graph.paddingLeft = 0.0f; + self.graph.paddingBottom = 0.0f; + self.graph.paddingRight = 0.0f; + self.graph.paddingTop = 0.0f; + self.graph.plotAreaFrame.paddingLeft = 0.0f; + self.graph.plotAreaFrame.paddingBottom = 0.0f; + self.graph.plotAreaFrame.paddingRight = 0.0f; + self.graph.plotAreaFrame.paddingTop = (kChartTopYValue - kMaxYValue) / kChartTopYValue * self.view.frame.size.height; //create background - CPGradient *backgroundGradient = [[[CPGradient alloc] init] autorelease]; CPColor* topBackgroundColor = [CPColor colorWithComponentRed:9.0/255.0 green:102.0/255.0 blue:180.0/255.0 alpha:1.0]; CPColor* bottomBackgroundColor = [CPColor colorWithComponentRed:4.0/255.0 green:77.0/255.0 blue:123.0/255.0 alpha:1.0]; @@ -341,82 +343,48 @@ - (void)setMarkerLabelDelegate:(id )delegate } -- (void)updateChartValues +- (void)updateMarkerValues { - - ChartSeries* currentYearSeries = nil; - ChartSeries* lastYearSeries = nil; - - NSCalendar* gregorian = [NSCalendar gregorian]; Chart* chart = self.place.chart; - NSDateComponents* compsCurrent = [gregorian components:NSYearCalendarUnit fromDate:chart.xEnd]; - NSDateComponents* compsLast = [[[NSDateComponents alloc] init] autorelease]; - [compsLast setYear:[compsCurrent year] - 1]; - - for (ChartSeries* series in chart.series) - { - if ([series.year intValue] == compsCurrent.year) - { - currentYearSeries = series; - } - else if ([series.year intValue] == compsLast.year) - { - lastYearSeries = series; - } - } - - if (self.xCoordinate > 31 + 28 && ![NSCalendar isLeapYear:[currentYearSeries.year intValue]]) { - [compsCurrent setDay:self.xCoordinate - 1]; - } else { - [compsCurrent setDay:self.xCoordinate]; - } - if (self.xCoordinate > 31 + 28 && ![NSCalendar isLeapYear:[lastYearSeries.year intValue]]) { - [compsLast setDay:self.xCoordinate - 1]; - } else { - [compsLast setDay:self.xCoordinate]; - } - NSDate* currentYearDate = [gregorian dateFromComponents:compsCurrent]; - NSDate* lastYearDate = [gregorian dateFromComponents:compsLast]; - - ChartValue* currentYearValue = [currentYearSeries getValueForDayInYear:self.xCoordinate]; - ChartValue* lastYearValue = [lastYearSeries getValueForDayInYear:self.xCoordinate]; - self.currentYearYCoordinate = currentYearValue ? [NSNumber numberWithDouble:currentYearValue.percentage] : nil; - self.lastYearYCoordinate = lastYearValue ? [NSNumber numberWithDouble:lastYearValue.percentage] : nil; + NSCalendar* gregorian = [NSCalendar gregorian]; + NSInteger currentYear = [[gregorian components:NSYearCalendarUnit fromDate:chart.xEnd] year]; //WARNING Assert that unit is volume, can only be checked from yAxisLabel in parenthesis based on current chart XML format - Measurement* currentYearPercentage= nil; - Measurement* currentYearVolume = nil; - NSString* unit = place.obsCurrent.capacity.unit ?: @"ML"; - if (currentYearValue) + NSString* volumeUnit = place.obsCurrent.capacity.unit ?: @"ML"; + + NSMutableArray* observations = [NSMutableArray arrayWithCapacity:3]; + self.yCoordinates = [NSMutableArray arrayWithCapacity:3+2]; + [self.yCoordinates addObject:[NSNumber numberWithInt:-10]]; + for (NSInteger yearIndex = currentYear; yearIndex > currentYear - 3; yearIndex--) { - currentYearPercentage = [[[Measurement alloc] init] autorelease]; - currentYearPercentage.unit = @"%"; - currentYearPercentage.value = currentYearValue.percentage * 100.0; - currentYearVolume = [[[Measurement alloc] init] autorelease]; - currentYearVolume.unit = unit; - currentYearVolume.value = currentYearValue.value; + NSPredicate* predicate = [NSPredicate predicateWithFormat:@"year == %@", [NSNumber numberWithInt:yearIndex]]; + ChartSeries* yearSeries = [[chart.series filteredSetUsingPredicate:predicate] anyObject]; + + NSDateComponents* dateComps = [[[NSDateComponents alloc] init] autorelease]; + [dateComps setYear:yearIndex]; + if (self.xCoordinate > 31 + 28 && ![NSCalendar isLeapYear:yearIndex]) { + [dateComps setDay:self.xCoordinate - 1]; + } else { + [dateComps setDay:self.xCoordinate]; + } + + NSDate* date = [gregorian dateFromComponents:dateComps]; + ChartValue* yearValue = [yearSeries getValueForDayInYear:self.xCoordinate]; + + Measurement* percentageVolume = nil; + Measurement* volume = nil; + if (yearValue) { + percentageVolume = [Measurement measurementWithUnit:@"%" value:yearValue.percentage * 100.0]; + volume = [Measurement measurementWithUnit:volumeUnit value:yearValue.value]; + [(NSMutableArray*)self.yCoordinates addObject:[NSNumber numberWithDouble:yearValue.percentage]]; + } + [observations addObject:[ChartObservation chartObservationWithDate:date + percentageVolume:percentageVolume + volume:volume]]; } - Measurement* lastYearPercentage= nil; - Measurement* lastYearVolume = nil; - if (lastYearValue) - { - lastYearPercentage = [[[Measurement alloc] init] autorelease]; - lastYearPercentage.unit = @"%"; - lastYearPercentage.value = lastYearValue.percentage * 100.0; - lastYearVolume = [[[Measurement alloc] init] autorelease]; - lastYearVolume.unit = unit; - lastYearVolume.value = lastYearValue.value; - } - - [self.markerLabelDelegate - showLabelsCurrentYearDate:currentYearDate - currentYearPercentage:currentYearPercentage - currentYearVolume:currentYearVolume - lastYearDate:lastYearDate - lastYearPercentage:lastYearPercentage - lastYearVolume:lastYearVolume - awayFrom:self.viewXPosition]; + [self.yCoordinates addObject:[NSNumber numberWithInt:10]]; + [self.markerLabelDelegate showLabelsForChartObservations:observations awayFrom:self.viewXPosition]; } -(CGPoint)viewCoordinatesForChartPoint:(NSDecimal*)chartPoint @@ -467,7 +435,7 @@ -(BOOL)plotSpace:(CPPlotSpace *)space shouldHandlePointingDeviceDownEvent:(id)ev self.viewXPosition = point.x; CPColor* yellow = [CPColor colorWithComponentRed:0.9 green:0.80 blue:0.05 alpha:1.0]; - [self updateChartValues]; + [self updateMarkerValues]; CPLineStyle *symbolLineStyle = [CPLineStyle lineStyle]; symbolLineStyle.lineColor = yellow; @@ -506,7 +474,7 @@ -(BOOL)plotSpace:(CPPlotSpace *)space shouldHandlePointingDeviceDraggedEvent:(id if (self.xCoordinate != x) { self.xCoordinate = x; self.viewXPosition = point.x; - [self updateChartValues]; + [self updateMarkerValues]; [self.markerPlot reloadData]; } } @@ -546,46 +514,24 @@ -(BOOL)plotSpace:(CPPlotSpace *)space shouldHandlePointingDeviceUpEvent:(id)even -(NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot { - return 4; + return [self.yCoordinates count]; } -(NSArray*)numbersForPlot:(CPPlot*)plot field:(NSUInteger)fieldEnum recordIndexRange:(NSRange)indexRange { - NSMutableArray* result; - if(fieldEnum == CPScatterPlotFieldX) - { - result = [NSArray arrayWithObjects: - [NSNumber numberWithInt:_xCoordinate], - [NSNumber numberWithInt:_xCoordinate], - [NSNumber numberWithInt:_xCoordinate], - [NSNumber numberWithInt:_xCoordinate], - nil]; - } - else + if (fieldEnum == CPScatterPlotFieldX) { - //CPScatterPlotFieldY - result = [[[NSMutableArray alloc] initWithCapacity:3] autorelease]; - [result addObject:[NSNumber numberWithInt:-10]]; - if (_currentYearYCoordinate) { - [result addObject:_currentYearYCoordinate]; - } - else - { - [result addObject:[NSNumber numberWithInt:-10]]; - } - if (_lastYearYCoordinate) { - [result addObject:_lastYearYCoordinate]; + NSMutableArray* result = [NSMutableArray arrayWithCapacity:[self.yCoordinates count]]; + for (int i=0; i<[self.yCoordinates count]; i++) { + [result addObject:[NSNumber numberWithInt:_xCoordinate]]; } - else - { - [result addObject:[NSNumber numberWithInt:-10]]; - } - [result addObject:[NSNumber numberWithInt:10]]; - //NSLog(@"points: %@", result); + return result; + } else { + //CPScatterPlotFieldY + return self.yCoordinates; } - return result; } @end diff --git a/Classes/DataManager.m b/Classes/DataManager.m index a9631e6..4f951bb 100644 --- a/Classes/DataManager.m +++ b/Classes/DataManager.m @@ -48,6 +48,9 @@ NSString* const kHostName = @"water.bom.gov.au"; NSString* const kBaseURL = @"http://water.bom.gov.au/waterstorage/"; +// flag for model fix stored in store to address corrupted data problem +NSString* const kCustomMetadataModelFixedChartDeleteRule = @"ChartDeletionRuleInModelFixed"; + @interface DataManager () // private @property (nonatomic, retain) id requestInProgress; @@ -418,17 +421,32 @@ - (NSPersistentStoreCoordinator *)persistentStoreCoordinator nil]; BOOL happy = NO; - + NSURL* storeURL = [self storeURL]; + #ifdef GET_FRESH_PLACES // GET_FRESH_PLACES is used to load a clean database containing // only Places, no observations or charts. // Start with a blank store and load everything. #else - happy = [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType + + NSDictionary *metadata = [NSPersistentStoreCoordinator + metadataForPersistentStoreOfType:NSSQLiteStoreType URL:storeURL error:&error]; + if (metadata == nil) { + NSLog(@"Error accessing store metadata: %@", error); + } + else if (![metadata objectForKey:kCustomMetadataModelFixedChartDeleteRule]) + { + //possibly a corrupted store, wipe it out and install fresh one from bundle + NSLog(@"Current store may contain places with broken reference to chart, starting with fresh store..."); + [self installDefaultStore]; + } + + happy = [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil - URL:[self storeURL] + URL:storeURL options:options error:&error] != nil; + if (!happy) { // This occurs when the model changes. // We revert to the default store and try again. @@ -436,7 +454,7 @@ - (NSPersistentStoreCoordinator *)persistentStoreCoordinator error = nil; happy = [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil - URL:[self storeURL] + URL:storeURL options:options error:&error] != nil; } @@ -450,17 +468,27 @@ - (NSPersistentStoreCoordinator *)persistentStoreCoordinator NSLog(@"DEBUG Removed the store."); error = nil; - happy = [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType - configuration:nil - URL:[self storeURL] - options:options - error:&error] != nil; + NSPersistentStore* store = + [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType + configuration:nil + URL:storeURL + options:options + error:&error]; + happy = store != nil; + if (happy) { + //Set the custom key-pair in the store, regarding model fix + NSDictionary* metadata = [persistentStoreCoordinator metadataForPersistentStore:store]; + NSMutableDictionary* newMetadata = [[metadata mutableCopy] autorelease]; + [newMetadata setObject:@"YES" forKey:kCustomMetadataModelFixedChartDeleteRule]; + [persistentStoreCoordinator setMetadata:newMetadata forPersistentStore:store]; + NSLog(@"DEBUG Created new store and saved flag in metadata: %@", kCustomMetadataModelFixedChartDeleteRule); + } } if (!happy) { // Really not happy. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); - } + } return persistentStoreCoordinator; } diff --git a/Classes/FavouritesTableViewController.m b/Classes/FavouritesTableViewController.m index 376973f..7e2b78a 100644 --- a/Classes/FavouritesTableViewController.m +++ b/Classes/FavouritesTableViewController.m @@ -52,6 +52,7 @@ @implementation FavouritesTableViewController - (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; [favouritesHelpView release]; [super dealloc]; } @@ -74,15 +75,19 @@ - (void)viewDidLoad [[NSBundle mainBundle] loadNibNamed:@"FavouritesHelp" owner:self options:nil]; } - -- (void)viewWillAppear:(BOOL)animated +//notification is passed when this method is called from an event +- (void)loadDataIfNeeded:(NSNotification*)notification { - [[DataManager manager] clearQueue]; Favourites* favourites = [Favourites favourites]; for (int i = 0; i < [favourites count]; i++) { [[DataManager manager] loadPlace:[favourites itemAtIndex:i] entire:NO force:NO]; } - +} + +- (void)viewWillAppear:(BOOL)animated +{ + [[DataManager manager] clearQueue]; + [self loadDataIfNeeded:nil]; [super viewWillAppear:animated]; [self.tableView reloadData]; @@ -90,6 +95,10 @@ - (void)viewWillAppear:(BOOL)animated [self.view.superview addSubview:favouritesHelpView]; } [self itemCountChanged]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(loadDataIfNeeded:) + name:UIApplicationDidBecomeActiveNotification + object:nil]; } /* @@ -107,6 +116,7 @@ - (void)viewWillDisappear:(BOOL)animated - (void)viewDidDisappear:(BOOL)animated { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil]; [super viewDidDisappear:animated]; self.editing = NO; } diff --git a/Classes/LandscapeViewController.h b/Classes/LandscapeViewController.h index 12f4a85..75c545d 100644 --- a/Classes/LandscapeViewController.h +++ b/Classes/LandscapeViewController.h @@ -40,7 +40,6 @@ @protocol LandscapeViewControllerDelegate - (void)landscapeViewControllerDidAppear; -- (void)landscapeViewControllerDidDisappear; @end @@ -53,12 +52,6 @@ ChartViewController* _chartViewController; UIView* _valuesOverlay; BOOL _valuesOverlayIsVisible; - UILabel* _currentYearDate; - UILabel* _currentYearPercentage; - UILabel* _currentYearVolume; - UILabel* _lastYearDate; - UILabel* _lastYearPercentage; - UILabel* _lastYearVolume; UILabel* _chartTotalCapacityLabel; UILabel* _chartTotalCapacityPercentageLabel; @@ -68,12 +61,6 @@ @property (nonatomic, retain) IBOutlet UINavigationItem* titleNavigationItem; @property (nonatomic, retain) IBOutlet ChartViewController* chartViewController; @property (nonatomic, retain) IBOutlet UIView* valuesOverlay; -@property (nonatomic, retain) IBOutlet UILabel* currentYearDate; -@property (nonatomic, retain) IBOutlet UILabel* currentYearPercentage; -@property (nonatomic, retain) IBOutlet UILabel* currentYearVolume; -@property (nonatomic, retain) IBOutlet UILabel* lastYearDate; -@property (nonatomic, retain) IBOutlet UILabel* lastYearPercentage; -@property (nonatomic, retain) IBOutlet UILabel* lastYearVolume; @property (nonatomic, retain) IBOutlet UILabel* chartTotalCapacityLabel; @property (nonatomic, retain) IBOutlet UILabel* chartTotalCapacityPercentageLabel; diff --git a/Classes/LandscapeViewController.m b/Classes/LandscapeViewController.m index 308518a..09857fb 100644 --- a/Classes/LandscapeViewController.m +++ b/Classes/LandscapeViewController.m @@ -36,6 +36,7 @@ #import "Chart.h" #import "Observation.h" #import "Measurement.h" +#import "ChartObservation.h" #import "CalendarHelpers.h" @@ -49,34 +50,30 @@ @interface LandscapeViewController () @implementation LandscapeViewController +//marker overlay labels are identified using tags (in view attributes) +NSInteger const kTagLabelsStart = 3; +NSInteger const kTagLabelElementSize = 3; +NSInteger const kTagDateOffset = 0; +NSInteger const kTagPercentageOffset = 1; +NSInteger const kTagVolumeOffset = 2; + @synthesize delegate = _delegate; @synthesize titleNavigationItem = _titleNavigationItem; @synthesize place = _place; @synthesize chartViewController = _chartViewController; @synthesize valuesOverlay = _valuesOverlay; @synthesize valuesOverlayIsVisible = _valuesOverlayIsVisible; -@synthesize currentYearDate = _currentYearDate; -@synthesize currentYearPercentage = _currentYearPercentage; -@synthesize currentYearVolume = _currentYearVolume; -@synthesize lastYearDate = _lastYearDate; -@synthesize lastYearPercentage = _lastYearPercentage; -@synthesize lastYearVolume = _lastYearVolume; @synthesize chartTotalCapacityLabel = _chartTotalCapacityLabel; @synthesize chartTotalCapacityPercentageLabel = _chartTotalCapacityPercentageLabel; - (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; [_titleNavigationItem release]; [_place release]; [_chartViewController release]; [_valuesOverlay release]; - [_currentYearDate release]; - [_currentYearPercentage release]; - [_currentYearVolume release]; - [_lastYearDate release]; - [_lastYearPercentage release]; - [_lastYearVolume release]; [_chartTotalCapacityLabel release]; [_chartTotalCapacityPercentageLabel release]; [super dealloc]; @@ -86,12 +83,6 @@ - (void)viewDidUnload { self.titleNavigationItem = nil; self.valuesOverlay = nil; - self.currentYearDate = nil; - self.currentYearPercentage = nil; - self.currentYearVolume = nil; - self.lastYearDate = nil; - self.lastYearPercentage = nil; - self.lastYearVolume = nil; self.chartTotalCapacityLabel = nil; self.chartTotalCapacityPercentageLabel = nil; [super viewDidUnload]; @@ -154,6 +145,7 @@ - (void)viewDidLoad self.valuesOverlay.alpha = 0.0f; self.valuesOverlay.layer.cornerRadius = 3.0f; [self.valuesOverlay viewWithTag:1].layer.cornerRadius = 3.0f; + [self.valuesOverlay viewWithTag:2].layer.cornerRadius = 3.0f; self.chartViewController.chartDelegate = self; self.chartTotalCapacityLabel.layer.cornerRadius = 2.0f; self.chartTotalCapacityPercentageLabel.layer.cornerRadius = 2.0f; @@ -163,6 +155,10 @@ - (void)viewWillAppear:(BOOL)animated { [self.chartViewController viewWillAppear:animated]; [super viewWillAppear:animated]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(loadDataIfNeeded:) + name:UIApplicationDidBecomeActiveNotification + object:nil]; } - (void)viewDidAppear:(BOOL)animated @@ -184,9 +180,19 @@ - (void)viewWillDisappear:(BOOL)animated - (void)viewDidDisappear:(BOOL)animated { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil]; [super viewDidDisappear:animated]; [self.chartViewController viewDidDisappear:animated]; - [self.delegate landscapeViewControllerDidDisappear]; +} + +//notification is passed when this method is called from an event +- (void)loadDataIfNeeded:(NSNotification*)notification +{ + if (self.place) { + //load chart first + [[DataManager manager] loadChartForPlace:self.place force:NO]; + [[DataManager manager] loadPlace:self.place entire:YES force:NO]; + } } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation @@ -213,20 +219,32 @@ - (void)chartUpdated #pragma mark MarkerLabelDelegate protocol --(void)showLabelsCurrentYearDate:(NSDate*)currentYearDate - currentYearPercentage:(Measurement*)currentYearPercentage - currentYearVolume:(Measurement*)currentYearVolume - lastYearDate:(NSDate*)lastYearDate - lastYearPercentage:(Measurement*)lastYearPercentage - lastYearVolume:(Measurement*)lastYearVolume +-(void)showLabelsForChartObservations:(NSArray*)observations awayFrom:(float)viewXPosition { - self.currentYearDate.text = [[currentYearDate readableDateNoWeekDay] uppercaseString]; - [self.currentYearPercentage setMeasurementAsPercentage:currentYearPercentage forceSign:NO]; - [self.currentYearVolume setMeasurementAsVolume:currentYearVolume forceSign:NO]; - self.lastYearDate.text = [[lastYearDate readableDateNoWeekDay] uppercaseString]; - [self.lastYearPercentage setMeasurementAsPercentage:lastYearPercentage forceSign:NO]; - [self.lastYearVolume setMeasurementAsVolume:lastYearVolume forceSign:NO]; + NSMutableString* spokenMessage = nil; + if (UIAccessibilityIsVoiceOverRunning != nil && UIAccessibilityIsVoiceOverRunning()) { + spokenMessage = nil;[NSMutableString stringWithCapacity:100]; + } + for (NSInteger i = 0; i < [observations count]; i++) + { + ChartObservation* obs = [observations objectAtIndex:i]; + NSInteger blockOffset = kTagLabelsStart + i * kTagLabelElementSize; + UILabel* dateLabel = (UILabel*)[self.valuesOverlay viewWithTag:(blockOffset + kTagDateOffset)]; + dateLabel.text = [[obs.date readableDateNoWeekDay] uppercaseString]; + [spokenMessage appendString:dateLabel.text]; + [spokenMessage appendString:@" "]; + + UILabel* percentageLabel = (UILabel*)[self.valuesOverlay viewWithTag:(blockOffset + kTagPercentageOffset)]; + [percentageLabel setMeasurementAsPercentage:obs.percentageVolume forceSign:NO]; + [spokenMessage appendString:percentageLabel.accessibilityLabel]; + [spokenMessage appendString:@" "]; + + UILabel* volumeLabel = (UILabel*)[self.valuesOverlay viewWithTag:(blockOffset + kTagVolumeOffset)]; + [volumeLabel setMeasurementAsVolume:obs.volume forceSign:NO]; + [spokenMessage appendString:volumeLabel.accessibilityLabel]; + [spokenMessage appendString:@" "]; + } CGRect frame = self.valuesOverlay.frame; float margin = 20.0f; float leftLimit = frame.size.width + margin; @@ -255,19 +273,7 @@ -(void)showLabelsCurrentYearDate:(NSDate*)currentYearDate self.valuesOverlayIsVisible = YES; if (UIAccessibilityIsVoiceOverRunning != nil && UIAccessibilityIsVoiceOverRunning()) { - NSMutableString* message = [NSMutableString stringWithCapacity:50]; - [message appendString:self.currentYearDate.text]; - [message appendString:@" "]; - [message appendString:self.currentYearPercentage.accessibilityLabel]; - [message appendString:@" "]; - [message appendString:self.currentYearVolume.accessibilityLabel]; - [message appendString:@" "]; - [message appendString:self.lastYearDate.text]; - [message appendString:@" "]; - [message appendString:self.lastYearPercentage.accessibilityLabel]; - [message appendString:@" "]; - [message appendString:self.lastYearVolume.accessibilityLabel]; - UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, message); + UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, spokenMessage); } } diff --git a/Classes/Measurement.h b/Classes/Measurement.h index eb95ca1..3e66e3f 100644 --- a/Classes/Measurement.h +++ b/Classes/Measurement.h @@ -40,6 +40,8 @@ @property (nonatomic) double value; @property (nonatomic, copy) NSString* unit; ++ (Measurement*)measurementWithUnit:(NSString*)unit value:(double)value; + // Returns the measurement formatted as a percentage. - (NSString*) textAsPercentageForceSign:(BOOL)forceSign; diff --git a/Classes/Measurement.m b/Classes/Measurement.m index 7266a2c..def6f1d 100644 --- a/Classes/Measurement.m +++ b/Classes/Measurement.m @@ -58,6 +58,17 @@ - (void)encodeWithCoder:(NSCoder*)encoder [encoder encodeObject:self.unit forKey:@"unit"]; } ++ (Measurement*)measurementWithUnit:(NSString*)unit value:(double)value +{ + Measurement* m = [[[Measurement alloc] init] autorelease]; + if (m) + { + m.unit = unit; + m.value = value; + } + return m; +} + // Returns the measurement formatted as a percentage. - (NSString*) textAsPercentageForceSign:(BOOL)forceSign { diff --git a/Classes/PlaceDetailViewController.m b/Classes/PlaceDetailViewController.m index ef31005..7d11985 100644 --- a/Classes/PlaceDetailViewController.m +++ b/Classes/PlaceDetailViewController.m @@ -159,7 +159,10 @@ - (id)initWithPlace:(Place*)place; if ((self = [super initWithNibName:@"PlaceDetailView" bundle:nil])) { self.place = place; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(objectsDidChangeNotification:) name:NSManagedObjectContextObjectsDidChangeNotification object:[_place managedObjectContext]]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(objectsDidChangeNotification:) + name:NSManagedObjectContextObjectsDidChangeNotification + object:[_place managedObjectContext]]; self.title = _place.longName; NSManagedObjectContext* context = [_place managedObjectContext]; @@ -269,19 +272,32 @@ - (BOOL)canBecomeFirstResponder return YES; } -- (void)viewWillAppear:(BOOL)animated +//notification is passed when this method is called from an event +- (void)loadDataIfNeeded:(NSNotification*)notification { - [[DataManager manager] clearQueue]; [[DataManager manager] loadPlace:self.place entire:YES force:NO]; [[DataManager manager] loadChartForPlace:self.place force:NO]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [[DataManager manager] clearQueue]; + [self loadDataIfNeeded:nil]; + [self.chartViewController viewWillAppear:animated]; - [[UIApplication sharedApplication] addObserver:self forKeyPath:@"networkActivityIndicatorVisible" options:NSKeyValueObservingOptionInitial context:nil]; + [[UIApplication sharedApplication] addObserver:self + forKeyPath:@"networkActivityIndicatorVisible" + options:NSKeyValueObservingOptionInitial + context:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(loadDataIfNeeded:) + name:UIApplicationDidBecomeActiveNotification + object:nil]; [self updatePlaceDetailsAnimated:NO]; [self setWaterPositionForView:self.mainWaterView percentage:0.0f]; [self setWaterPositionForView:self.secondaryWaterView percentage:0.0f]; [super viewWillAppear:animated]; - self.viewIsActive = YES; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context @@ -297,19 +313,27 @@ - (void)viewDidAppear:(BOOL)animated [self.chartViewController viewDidAppear:animated]; [self updatePlaceDetailsAnimated:animated]; [self becomeFirstResponder]; + self.viewIsActive = YES; + // For the cases where the user switches to landscape while navigating to a different place and where + // the user switches to portrait and back to landscape while the modal view controller is still disappearing + // Because presenting a modal view controller while this view controller is being loaded + // causes will/did (dis)appear inconsistencies, there is a lapse of time where no place detail + // view controller has viewIsActive == YES. If we missed a rotation event, then we check orientation now. + [self checkAndShowLandscapeChartIfNeeded]; } - (void)viewWillDisappear:(BOOL)animated { + self.viewIsActive = NO; [self.chartViewController viewWillDisappear:animated]; - [[UIApplication sharedApplication] removeObserver:self forKeyPath:@"networkActivityIndicatorVisible"]; [super viewWillDisappear:animated]; } - (void)viewDidDisappear:(BOOL)animated { - self.viewIsActive = NO; [super viewDidDisappear:animated]; + [[UIApplication sharedApplication] removeObserver:self forKeyPath:@"networkActivityIndicatorVisible"]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil]; [self.chartViewController viewDidDisappear:animated]; } @@ -426,15 +450,6 @@ - (void)landscapeViewControllerDidAppear [self checkAndShowLandscapeChartIfNeeded]; } -- (void)landscapeViewControllerDidDisappear -{ - // For the case where the user switches to portrait and back to landscape while the - // modal view controller is still disappearing. It is not possible to present a modal - // view controller while one is still disappearing, so this callback lets us present - // it when the old one has finished disappearing. - [self checkAndShowLandscapeChartIfNeeded]; -} - - (void)orientationChanged:(NSNotification *)notification { [self checkAndShowLandscapeChartIfNeeded]; @@ -479,9 +494,6 @@ - (void)chartUpdated self.chartTotalCapacityPercentageLabel.frame.size.width, self.chartTotalCapacityPercentageLabel.frame.size.height); */ - Measurement* m = [[[Measurement alloc] init] autorelease]; - m.value = [_place.chart.yMax doubleValue]; - m.unit = _place.obsCurrent.capacity.unit; if (_place.chart.yMax && fabs(_place.obsCurrent.capacity.value - [_place.chart.yMax doubleValue]) > 1.0) { NSLog(@"Warning: Total capacity volume from observation (%f) is different from yMax value from chart (%f) Label in chart will be incorrect", diff --git a/Classes/PlaceParser.m b/Classes/PlaceParser.m index 91e5309..2b5de44 100644 --- a/Classes/PlaceParser.m +++ b/Classes/PlaceParser.m @@ -301,10 +301,7 @@ - (void)gotChildren:(id)element if (!number) { return nil; } - Measurement* measurement = [[[Measurement alloc] init] autorelease]; - measurement.value = [number doubleValue]; - measurement.unit = unit; - return measurement; + return [Measurement measurementWithUnit:unit value:[number doubleValue]]; } } return nil; diff --git a/Classes/PlaceRequest.m b/Classes/PlaceRequest.m index 6502776..1127701 100644 --- a/Classes/PlaceRequest.m +++ b/Classes/PlaceRequest.m @@ -56,6 +56,7 @@ - (DataLoader*)makeLoader - (BOOL)isSatisfied { +#ifndef GET_FRESH_PLACES if (!self.place.completeLoadDate || !self.place.obsCurrent.loadDate) { return NO; } @@ -79,6 +80,9 @@ - (BOOL)isSatisfied // Unforced load is satisfied if it was loaded "recently enough" return [DataManager dateIsRecentEnough:date]; } +#else + return (self.place.completeLoadDate != nil); +#endif } - (BOOL)isClearable diff --git a/Places.sqlite b/Places.sqlite index b03fa74..c2b439c 100644 Binary files a/Places.sqlite and b/Places.sqlite differ diff --git a/Release-notes.txt b/Release-notes.txt index 14f5a8f..1fb9f75 100644 --- a/Release-notes.txt +++ b/Release-notes.txt @@ -3,6 +3,15 @@ Release Notes: Water Storage iPhone App ======================================= +v1.1 -- Mon 7 Feb 2011 + +* Fixed a crash that was caused by an incorrectly configured AWRIS server. +* Added a third year plot to the chart. +* Check for and refresh old data upon wake up. +* Fixed a minor issue where a chart for the wrong place could appear in landscape view. +* Fixed a minor issue with the appearance of charts with values exceeding 110%. + + v1.0 -- Tue 19 Oct 2010 Submitted for App Store approval. diff --git a/Slake-Info.plist b/Slake-Info.plist index cb81370..a62fb09 100644 --- a/Slake-Info.plist +++ b/Slake-Info.plist @@ -27,9 +27,9 @@ CFBundleSignature ???? CFBundleVersion - 10.0 + 11.0 CFBundleGetInfoString - 1.0 + 1.1 LSRequiresIPhoneOS NSMainNibFile diff --git a/Slake.xcodeproj/project.pbxproj b/Slake.xcodeproj/project.pbxproj index 078ea3c..d108fbe 100755 --- a/Slake.xcodeproj/project.pbxproj +++ b/Slake.xcodeproj/project.pbxproj @@ -82,7 +82,6 @@ BEB71EA81123C41F008FC2B1 /* SBJsonWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB71EA21123C41F008FC2B1 /* SBJsonWriter.m */; }; BEB71EFC1123D1F8008FC2B1 /* PlaceDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB71EFA1123D1F8008FC2B1 /* PlaceDetailViewController.m */; }; BEC1C8D4117D786600B7BCB3 /* FavouriteToggleButtonController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEC1C8D3117D786600B7BCB3 /* FavouriteToggleButtonController.m */; }; - BEC5A587118FE7AE00A066E8 /* ChartViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEC5A586118FE7AE00A066E8 /* ChartViewController.m */; }; BEC9482D118A582B00441F99 /* DataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BEC9482C118A582B00441F99 /* DataManager.m */; }; BECDB275116D52E60039539E /* AboutViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BECDB273116D52E60039539E /* AboutViewController.m */; }; BECDB276116D52E60039539E /* AboutView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BECDB274116D52E60039539E /* AboutView.xib */; }; @@ -99,6 +98,17 @@ BEF9CEF9113B23C300998428 /* Places.xcdatamodel in Sources */ = {isa = PBXBuildFile; fileRef = BEF9CEF8113B23C300998428 /* Places.xcdatamodel */; }; BEF9CF20113B2AA500998428 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEF9CF1F113B2AA500998428 /* CoreData.framework */; }; F316259D1191665200B40280 /* libCorePlot-CocoaTouch.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F385C5C0118E97AD00E37A00 /* libCorePlot-CocoaTouch.a */; }; + F37A271813133E6D00DE434A /* about-over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F37A271713133E6D00DE434A /* about-over@2x.png */; }; + F37A271D1313451F00DE434A /* tab-australia@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F37A271C1313451F00DE434A /* tab-australia@2x.png */; }; + F37A27241313476500DE434A /* tab-about@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F37A27201313476500DE434A /* tab-about@2x.png */; }; + F37A27251313476500DE434A /* tab-nearby@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F37A27211313476500DE434A /* tab-nearby@2x.png */; }; + F37A27261313476500DE434A /* tab-search@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F37A27221313476500DE434A /* tab-search@2x.png */; }; + F37A27271313476500DE434A /* tab-star@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F37A27231313476500DE434A /* tab-star@2x.png */; }; + F37A273713134A5C00DE434A /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F37A273613134A5C00DE434A /* Default@2x.png */; }; + F37A274213134D1900DE434A /* fav-star-big@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F37A273E13134D1900DE434A /* fav-star-big@2x.png */; }; + F37A274313134D1900DE434A /* fav-star-help@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F37A273F13134D1900DE434A /* fav-star-help@2x.png */; }; + F37A274413134D1900DE434A /* favstar_off@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F37A274013134D1900DE434A /* favstar_off@2x.png */; }; + F37A274513134D1900DE434A /* favstar_on@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F37A274113134D1900DE434A /* favstar_on@2x.png */; }; F385C5D3118EA70800E37A00 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F385C5D2118EA70800E37A00 /* QuartzCore.framework */; }; F38B995D11AA5D6700DC3EF3 /* ChartParser.m in Sources */ = {isa = PBXBuildFile; fileRef = F38B995C11AA5D6700DC3EF3 /* ChartParser.m */; }; F38B9D4C11ACEBE600DC3EF3 /* ChartDataset.m in Sources */ = {isa = PBXBuildFile; fileRef = F316272111977E1800B40280 /* ChartDataset.m */; }; @@ -106,6 +116,8 @@ F38B9D4E11ACEBFA00DC3EF3 /* ChartSeries.m in Sources */ = {isa = PBXBuildFile; fileRef = F316272511977E1800B40280 /* ChartSeries.m */; }; F38B9D4F11ACEC0100DC3EF3 /* Chart.m in Sources */ = {isa = PBXBuildFile; fileRef = F316272711977E1800B40280 /* Chart.m */; }; F3BA6CA011E44CD9004D8118 /* CalendarHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = F3BA6C9F11E44CD9004D8118 /* CalendarHelpers.m */; }; + F3E3CE1412DEC3AD00DA2A82 /* ChartObservation.m in Sources */ = {isa = PBXBuildFile; fileRef = F3E3CE1312DEC3AD00DA2A82 /* ChartObservation.m */; }; + F3E3CE7912DFF14600DA2A82 /* ChartViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BEC5A586118FE7AE00A066E8 /* ChartViewController.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -274,12 +286,25 @@ F316272611977E1800B40280 /* Chart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Chart.h; path = Classes/Chart.h; sourceTree = ""; }; F316272711977E1800B40280 /* Chart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Chart.m; path = Classes/Chart.m; sourceTree = ""; }; F316276F11993B2F00B40280 /* ChartParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChartParser.h; sourceTree = ""; }; + F37A271713133E6D00DE434A /* about-over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "about-over@2x.png"; path = "images/about-over@2x.png"; sourceTree = ""; }; + F37A271C1313451F00DE434A /* tab-australia@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tab-australia@2x.png"; path = "images/tab-australia@2x.png"; sourceTree = ""; }; + F37A27201313476500DE434A /* tab-about@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tab-about@2x.png"; path = "images/tab-about@2x.png"; sourceTree = ""; }; + F37A27211313476500DE434A /* tab-nearby@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tab-nearby@2x.png"; path = "images/tab-nearby@2x.png"; sourceTree = ""; }; + F37A27221313476500DE434A /* tab-search@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tab-search@2x.png"; path = "images/tab-search@2x.png"; sourceTree = ""; }; + F37A27231313476500DE434A /* tab-star@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tab-star@2x.png"; path = "images/tab-star@2x.png"; sourceTree = ""; }; + F37A273613134A5C00DE434A /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "images/Default@2x.png"; sourceTree = ""; }; + F37A273E13134D1900DE434A /* fav-star-big@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "fav-star-big@2x.png"; path = "images/fav-star-big@2x.png"; sourceTree = ""; }; + F37A273F13134D1900DE434A /* fav-star-help@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "fav-star-help@2x.png"; path = "images/fav-star-help@2x.png"; sourceTree = ""; }; + F37A274013134D1900DE434A /* favstar_off@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "favstar_off@2x.png"; path = "images/favstar_off@2x.png"; sourceTree = ""; }; + F37A274113134D1900DE434A /* favstar_on@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "favstar_on@2x.png"; path = "images/favstar_on@2x.png"; sourceTree = ""; }; F385C5BA118E97AD00E37A00 /* CorePlot-CocoaTouch.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "CorePlot-CocoaTouch.xcodeproj"; path = "core-plot/framework/CorePlot-CocoaTouch.xcodeproj"; sourceTree = SOURCE_ROOT; }; F385C5D2118EA70800E37A00 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; F38B995C11AA5D6700DC3EF3 /* ChartParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChartParser.m; sourceTree = ""; }; F38B9B5611ABC22100DC3EF3 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; F3BA6C9E11E44CD9004D8118 /* CalendarHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CalendarHelpers.h; sourceTree = ""; }; F3BA6C9F11E44CD9004D8118 /* CalendarHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CalendarHelpers.m; sourceTree = ""; }; + F3E3CE1212DEC3AD00DA2A82 /* ChartObservation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChartObservation.h; sourceTree = ""; }; + F3E3CE1312DEC3AD00DA2A82 /* ChartObservation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChartObservation.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -346,6 +371,8 @@ BE0BA9DA124865E6001115FF /* AboutWebViewController.m */, BEC1C8D2117D786600B7BCB3 /* FavouriteToggleButtonController.h */, BEC1C8D3117D786600B7BCB3 /* FavouriteToggleButtonController.m */, + F3E3CE1212DEC3AD00DA2A82 /* ChartObservation.h */, + F3E3CE1312DEC3AD00DA2A82 /* ChartObservation.m */, BEC5A585118FE7AE00A066E8 /* ChartViewController.h */, BEC5A586118FE7AE00A066E8 /* ChartViewController.m */, BE337617119CD7EC005951C6 /* SearchViewController.h */, @@ -458,6 +485,7 @@ children = ( BEE10BE8126D0D7A009BB640 /* about-bg.png */, BE911E711153660E008B9075 /* Default.png */, + F37A273613134A5C00DE434A /* Default@2x.png */, BE83DABA11CF016A007FFAF3 /* iTunesArtwork */, BE9B68C211558DA500715895 /* Icon.png */, BEECADA811F0397400FCDDB0 /* Icon-Small.png */, @@ -470,8 +498,11 @@ 5085FE9F11CA07C30012CAEE /* chart-footer.png */, 50029F4711ABA8D600D4B905 /* water-full.png */, 508F783611AB8B7B00F5627D /* about-over.png */, + F37A271713133E6D00DE434A /* about-over@2x.png */, 508F780111AB7CFE00F5627D /* fav-star-big.png */, + F37A273E13134D1900DE434A /* fav-star-big@2x.png */, 508F780211AB7CFE00F5627D /* fav-star-help.png */, + F37A273F13134D1900DE434A /* fav-star-help@2x.png */, 50BF6B8A11AA609000FA771C /* search-cell-bg-selected.png */, 50BF6B8B11AA609000FA771C /* search-cell-bg.png */, 50D109BB11AA44C100DB21AC /* superfluous.png */, @@ -486,12 +517,19 @@ 22DC4A7E11A516AC00759395 /* table-volumebar-bg.png */, 22353F5011A4A02E00F1CB04 /* table-cell-bg.png */, BEEE96D811879AAB00C15EAE /* favstar_off.png */, + F37A274013134D1900DE434A /* favstar_off@2x.png */, BEEE96D911879AAB00C15EAE /* favstar_on.png */, + F37A274113134D1900DE434A /* favstar_on@2x.png */, 50D10A4011AA4EA400DB21AC /* tab-search.png */, + F37A27221313476500DE434A /* tab-search@2x.png */, 50D10A3611AA4DF800DB21AC /* tab-star.png */, + F37A27231313476500DE434A /* tab-star@2x.png */, BE337558119A3D1B005951C6 /* tab-about.png */, + F37A27201313476500DE434A /* tab-about@2x.png */, BECDB3C6116D90720039539E /* tab-nearby.png */, + F37A27211313476500DE434A /* tab-nearby@2x.png */, BE911E731153679F008B9075 /* tab-australia.png */, + F37A271C1313451F00DE434A /* tab-australia@2x.png */, ); name = Images; sourceTree = ""; @@ -574,6 +612,7 @@ }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Slake" */; compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, @@ -658,6 +697,17 @@ BE22E793123F52C100930459 /* about in Resources */, BE0BA9D6124865D2001115FF /* AboutWebView.xib in Resources */, BEE10BE9126D0D7A009BB640 /* about-bg.png in Resources */, + F37A271813133E6D00DE434A /* about-over@2x.png in Resources */, + F37A271D1313451F00DE434A /* tab-australia@2x.png in Resources */, + F37A27241313476500DE434A /* tab-about@2x.png in Resources */, + F37A27251313476500DE434A /* tab-nearby@2x.png in Resources */, + F37A27261313476500DE434A /* tab-search@2x.png in Resources */, + F37A27271313476500DE434A /* tab-star@2x.png in Resources */, + F37A273713134A5C00DE434A /* Default@2x.png in Resources */, + F37A274213134D1900DE434A /* fav-star-big@2x.png in Resources */, + F37A274313134D1900DE434A /* fav-star-help@2x.png in Resources */, + F37A274413134D1900DE434A /* favstar_off@2x.png in Resources */, + F37A274513134D1900DE434A /* favstar_on@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -687,7 +737,6 @@ BE1C218311788B74007A638D /* PlaceCell.m in Sources */, BEC1C8D4117D786600B7BCB3 /* FavouriteToggleButtonController.m in Sources */, BEC9482D118A582B00441F99 /* DataManager.m in Sources */, - BEC5A587118FE7AE00A066E8 /* ChartViewController.m in Sources */, BE24035E1193EE1400A47257 /* XMLStreamParser.m in Sources */, BE337638119CE091005951C6 /* SearchViewController.m in Sources */, BE337745119D1AB5005951C6 /* PlaceTableViewController.m in Sources */, @@ -713,6 +762,8 @@ BE83DBCE11D04C82007FFAF3 /* LandscapeViewController.m in Sources */, F3BA6CA011E44CD9004D8118 /* CalendarHelpers.m in Sources */, BE0BA9DB124865E6001115FF /* AboutWebViewController.m in Sources */, + F3E3CE1412DEC3AD00DA2A82 /* ChartObservation.m in Sources */, + F3E3CE7912DFF14600DA2A82 /* ChartViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -750,7 +801,6 @@ "-lxml2", ); PRODUCT_NAME = WaterStorage; - SDKROOT = iphoneos4.0; }; name = Debug; }; @@ -777,7 +827,6 @@ ); PRODUCT_NAME = WaterStorage; "PROVISIONING_PROFILE[sdk=iphoneos*]" = "7AF56A79-7D0D-40C6-AB2B-BC392C27A6DC"; - SDKROOT = iphoneos4.0; }; name = Release; }; @@ -791,7 +840,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 3.0; PREBINDING = NO; - SDKROOT = iphoneos4.0; + SDKROOT = iphoneos; }; name = "Get Fresh Places"; }; @@ -819,7 +868,6 @@ "-lxml2", ); PRODUCT_NAME = WaterStorage; - SDKROOT = iphoneos4.0; }; name = "Get Fresh Places"; }; @@ -833,7 +881,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 3.0; PREBINDING = NO; - SDKROOT = iphoneos4.0; + SDKROOT = iphoneos; }; name = Debug; }; @@ -848,7 +896,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 3.0; PREBINDING = NO; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; - SDKROOT = iphoneos4.0; + SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; name = Release; diff --git a/Todo.txt b/Todo.txt index c1955d1..df97974 100644 --- a/Todo.txt +++ b/Todo.txt @@ -12,6 +12,8 @@ User Visible Release Test Checklist ---------------------- +* Use build and analyse +* Run on iOS 3.0 to check that no unrecognized selector exception is thrown * Use valgrind * Instruments leak check * NSZombie @@ -22,7 +24,7 @@ Release Checklist ----------------- * Update Places.sqlite with Get Fresh Places. -* Bump bundle version number in Slake-Info.plist. +* Bump bundle version number and get info string in Slake-Info.plist. * Tag the release. * Build and Archive, distribute the IPA diff --git a/images/Default@2x.png b/images/Default@2x.png new file mode 100644 index 0000000..1569f5b Binary files /dev/null and b/images/Default@2x.png differ diff --git a/images/about-over@2x.png b/images/about-over@2x.png new file mode 100644 index 0000000..9729441 Binary files /dev/null and b/images/about-over@2x.png differ diff --git a/images/fav-star-big@2x.png b/images/fav-star-big@2x.png new file mode 100644 index 0000000..c70a74e Binary files /dev/null and b/images/fav-star-big@2x.png differ diff --git a/images/fav-star-help@2x.png b/images/fav-star-help@2x.png new file mode 100644 index 0000000..fe64fdb Binary files /dev/null and b/images/fav-star-help@2x.png differ diff --git a/images/favstar_off@2x.png b/images/favstar_off@2x.png new file mode 100644 index 0000000..990b031 Binary files /dev/null and b/images/favstar_off@2x.png differ diff --git a/images/favstar_on@2x.png b/images/favstar_on@2x.png new file mode 100644 index 0000000..b9af9c5 Binary files /dev/null and b/images/favstar_on@2x.png differ diff --git a/images/tab-about@2x.png b/images/tab-about@2x.png new file mode 100644 index 0000000..ce98d79 Binary files /dev/null and b/images/tab-about@2x.png differ diff --git a/images/tab-australia@2x.png b/images/tab-australia@2x.png new file mode 100644 index 0000000..903f1da Binary files /dev/null and b/images/tab-australia@2x.png differ diff --git a/images/tab-nearby@2x.png b/images/tab-nearby@2x.png new file mode 100644 index 0000000..b452422 Binary files /dev/null and b/images/tab-nearby@2x.png differ diff --git a/images/tab-search@2x.png b/images/tab-search@2x.png new file mode 100644 index 0000000..23872ef Binary files /dev/null and b/images/tab-search@2x.png differ diff --git a/images/tab-star@2x.png b/images/tab-star@2x.png new file mode 100644 index 0000000..cc91107 Binary files /dev/null and b/images/tab-star@2x.png differ diff --git a/views/LandscapeView.xib b/views/LandscapeView.xib index eb780df..c26dcc1 100644 --- a/views/LandscapeView.xib +++ b/views/LandscapeView.xib @@ -1,18 +1,18 @@ - 1024 + 1056 10F569 - 788 + 823 1038.29 461.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 117 + 132 YES - + YES @@ -513,6 +513,229 @@ 292 YES + + + 290 + {{12, 134}, {106, 15}} + + + 2 + MC44MTU2ODYyNzQ1IDAuODkwMTk2MDc4NCAxIDAAA + + NO + YES + 9 + NO + + + + IBCocoaTouchFramework + 14 APR 2009 + + + 2 + MC44NTA5ODAzOTIyIDAuOTMzMzMzMzMzMyAwLjk2MDc4NDMxMzcAA + + + + 1 + MCAwIDAgMC45AA + + {0, 1} + 1 + 10 + + + + 290 + {{12, 143}, {106, 29}} + + + 2 + MC44MTU2ODYyNzQ1IDAuODkwMTk2MDc4NCAxIDAAA + + NO + YES + 10 + NO + + + + IBCocoaTouchFramework + 67.2% + + Helvetica + 20 + 16 + + + 2 + MC45Mzc5NTYyMDQ0IDAuOTY0NzA1ODgyNCAwLjk2ODYyNzQ1MQA + + + + 1 + MCAwIDAgMC45AA + + {0, 1} + 1 + 9 + + + + 290 + {{12, 166}, {106, 17}} + + + 2 + MC44MTU2ODYyNzQ1IDAuODkwMTk2MDc4NCAxIDAAA + + NO + YES + 11 + NO + + + + IBCocoaTouchFramework + 536,888 ML + + Helvetica + 10 + 16 + + + 2 + MC44NTA5ODAzOTIyIDAuOTMzMzMzMzMzMyAwLjk2MDc4NDMxMzcAA + + + + 1 + MCAwIDAgMC45AA + + {0, 1} + 1 + 9 + + + + 292 + + YES + + + 290 + {{12, 78}, {106, 15}} + + + 2 + MC44MTU2ODYyNzQ1IDAuODkwMTk2MDc4NCAxIDAAA + + NO + YES + 6 + NO + + + + IBCocoaTouchFramework + 14 APR 2010 + + + 2 + MC44NTA5ODAzOTIyIDAuOTMzMzMzMzMzMyAwLjk2MDc4NDMxMzcAA + + + + 1 + MCAwIDAgMC45AA + + {0, 1} + 1 + 10 + + + + 290 + {{12, 87}, {106, 30}} + + + 2 + MC44MTU2ODYyNzQ1IDAuODkwMTk2MDc4NCAxIDAAA + + NO + YES + 7 + NO + + + + IBCocoaTouchFramework + 55.7% + + Helvetica + 22 + 16 + + + 2 + MC45Mzc5NTYyMDQ0IDAuOTY0NzA1ODgyNCAwLjk2ODYyNzQ1MQA + + + + 1 + MCAwIDAgMC45AA + + {0, 1} + 1 + 9 + + + + 290 + {{12, 113}, {106, 17}} + + + 2 + MC44MTU2ODYyNzQ1IDAuODkwMTk2MDc4NCAxIDAAA + + NO + YES + 8 + NO + + + + IBCocoaTouchFramework + 536,101 ML + + Helvetica + 11 + 16 + + + 2 + MC44NTA5ODAzOTIyIDAuOTMzMzMzMzMzMyAwLjk2MDc4NDMxMzcAA + + + + 1 + MCAwIDAgMC45AA + + {0, 1} + 1 + 9 + + + {130, 133} + + + 1 + MC4wNDMxMzcyNTQ5IDAuMzE3NTE4MjQ4MiAwLjUyMTg5NzgxMDIAA + + 1 + IBCocoaTouchFramework + 292 @@ -521,7 +744,7 @@ 290 - {{12, 9}, {106, 15}} + {{12, 4}, {106, 15}} 2 @@ -529,21 +752,19 @@ NO YES + 3 NO IBCocoaTouchFramework - 14 APR 2010 + 14 APR 2011 Helvetica-Bold 11 16 - - 2 - MC43MjE1Njg2Mjc1IDAuODc0NTA5ODAzOSAxAA - + 1 @@ -556,7 +777,7 @@ 290 - {{12, 22}, {108, 37}} + {{12, 15}, {108, 40}} 2 @@ -564,6 +785,7 @@ NO YES + 4 NO @@ -575,10 +797,7 @@ 30 16 - - 2 - MC45Mzc5NTYyMDQ0IDAuOTY0NzA1ODgyNCAwLjk2ODYyNzQ1MQA - + 1 @@ -591,7 +810,7 @@ 290 - {{12, 59}, {114, 17}} + {{12, 50}, {114, 17}} 2 @@ -599,6 +818,7 @@ NO YES + 5 NO @@ -606,7 +826,7 @@ IBCocoaTouchFramework 536,906,808 ML - + 1 @@ -617,122 +837,21 @@ 9 - {130, 90} + {130, 75} 1 - MC4wNDMxMzcyNTQ5IDAuMjM3MjI2Mjc3NCAwLjQwNTEwOTQ4OTEgMC45NQA + MC4wOTg1NDAxNDU5OSAwLjUwNzI5OTI3MDEgMC43MDQzNzk1NjIAA - 1 + 2 IBCocoaTouchFramework - - - 290 - {{12, 99}, {106, 15}} - - - 2 - MC44MTU2ODYyNzQ1IDAuODkwMTk2MDc4NCAxIDAAA - - NO - YES - NO - - - - IBCocoaTouchFramework - 14 APR 2009 - - - 2 - MC43MjE1Njg2Mjc1IDAuODc0NTA5ODAzOSAxAA - - - - 1 - MCAwIDAgMC45AA - - {0, 1} - 1 - 10 - - - - 290 - {{12, 110}, {106, 37}} - - - 2 - MC44MTU2ODYyNzQ1IDAuODkwMTk2MDc4NCAxIDAAA - - NO - YES - NO - - - - IBCocoaTouchFramework - 55.7% - - Helvetica - 22 - 16 - - - 2 - MC45Mzc5NTYyMDQ0IDAuOTY0NzA1ODgyNCAwLjk2ODYyNzQ1MQA - - - - 1 - MCAwIDAgMC45AA - - {0, 1} - 1 - 9 - - - - 290 - {{12, 140}, {106, 17}} - - - 2 - MC44MTU2ODYyNzQ1IDAuODkwMTk2MDc4NCAxIDAAA - - NO - YES - NO - - - - IBCocoaTouchFramework - 536,101 ML - - Helvetica - 11 - 16 - - - 2 - MC43MjE1Njg2Mjc1IDAuODc0NTA5ODAzOSAxAA - - - - 1 - MCAwIDAgMC45AA - - {0, 1} - 1 - 9 - - {{0, 89}, {130, 167}} + {{0, 80}, {130, 185}} 1 - MC4wMzc0ODExMDc2MyAwLjE2NDIzMzU3NjYgMC4yODgzMjExNjc5IDAuOTUAA + MCAwLjIgMC40AA @@ -799,54 +918,6 @@ 43 - - - currentYearPercentage - - - - 45 - - - - currentYearVolume - - - - 46 - - - - lastYearPercentage - - - - 48 - - - - lastYearVolume - - - - 49 - - - - currentYearDate - - - - 50 - - - - lastYearDate - - - - 51 - chartTotalCapacityPercentageLabel @@ -1024,32 +1095,15 @@ YES - - - + + + + Overlay - - 39 - - - Last Year Volume Label - - - 38 - - - Last Year Percentage Label - - - 37 - - - Last Year Date Label - 36 @@ -1060,25 +1114,25 @@ - Current Background + Current Year Background 42 - Selection Date Label + Current Year Date Label 41 - Selection Percentage Label + Current Year Percentage Label 40 - Selection Volume Label + Current Year Volume Label 16 @@ -1100,6 +1154,54 @@ 100% Label + + 57 + + + YES + + + + + + Last Year Background + + + 37 + + + Last Year Date Label + + + 38 + + + Last Year Percentage Label + + + 39 + + + Last Year Volume Label + + + 61 + + + Two Years Ago Date Label + + + 62 + + + Two Years Ago Percentage Label + + + 63 + + + Two Years Ago Volume Label + @@ -1142,28 +1244,44 @@ 32.IBPluginDependency 34.IBPluginDependency 35.IBPluginDependency + 35.notes 36.IBPluginDependency + 36.IBViewBoundsToFrameTransform 37.CustomClassName 37.IBPluginDependency + 37.IBViewBoundsToFrameTransform 38.CustomClassName 38.IBPluginDependency + 38.IBViewBoundsToFrameTransform 39.CustomClassName 39.IBPluginDependency + 39.IBViewBoundsToFrameTransform 40.CustomClassName 40.IBPluginDependency + 40.IBViewBoundsToFrameTransform 41.CustomClassName 41.IBPluginDependency 42.CustomClassName 42.IBPluginDependency 53.IBPluginDependency 54.IBPluginDependency + 57.IBPluginDependency + 61.CustomClassName + 61.IBPluginDependency + 61.IBViewBoundsToFrameTransform + 62.CustomClassName + 62.IBPluginDependency + 62.IBViewBoundsToFrameTransform + 63.CustomClassName + 63.IBPluginDependency + 63.IBViewBoundsToFrameTransform 7.IBPluginDependency YES LandscapeViewController UIResponder - {{413, 354}, {480, 320}} + {{213, 221}, {480, 320}} com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin CPLayerHostingView @@ -1197,21 +1315,87 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + Tags are used in the subviews for identification + + + YES + + YES + NSColor + NSFont + NSOriginalFont + NSParagraphStyle + + + YES + + 6 + System + textColor + + 3 + MAA + + + + LucidaGrande + 11 + 3100 + + + + 4 + + + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + FancyLabel com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AUFAAABCnAAAA + FancyLabel com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AUFAAABCtAAAA + FancyLabel com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AUFAAABC3AAAA + FancyLabel com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AUFAAABCbAAAA + FancyLabel com.apple.InterfaceBuilder.IBCocoaTouchPlugin FancyLabel com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin FancyLabel com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AUFAAABDAgAAA + + FancyLabel com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AUFAAABDDAAAA + + FancyLabel com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + AUFAAABDIAAAA + com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -1231,7 +1415,7 @@ - 56 + 63 @@ -1270,12 +1454,6 @@ chartTotalCapacityLabel chartTotalCapacityPercentageLabel chartViewController - currentYearDate - currentYearPercentage - currentYearVolume - lastYearDate - lastYearPercentage - lastYearVolume titleNavigationItem valuesOverlay @@ -1284,12 +1462,6 @@ UILabel UILabel ChartViewController - UILabel - UILabel - UILabel - UILabel - UILabel - UILabel UINavigationItem UIView @@ -1301,12 +1473,6 @@ chartTotalCapacityLabel chartTotalCapacityPercentageLabel chartViewController - currentYearDate - currentYearPercentage - currentYearVolume - lastYearDate - lastYearPercentage - lastYearVolume titleNavigationItem valuesOverlay @@ -1324,30 +1490,6 @@ chartViewController ChartViewController - - currentYearDate - UILabel - - - currentYearPercentage - UILabel - - - currentYearVolume - UILabel - - - lastYearDate - UILabel - - - lastYearPercentage - UILabel - - - lastYearVolume - UILabel - titleNavigationItem UINavigationItem @@ -1565,6 +1707,13 @@ UIKit.framework/Headers/UISearchDisplayController.h + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIPrintFormatter.h + + UIView @@ -1622,7 +1771,7 @@ IBCocoaTouchFramework com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 @@ -1635,6 +1784,6 @@ chart-footer.png {1, 32} - 117 + 132