Coreplot on iPhone

I followed Using Core Plot in an iPhone Application to generate a graph. I got some errors though. I originally wanted to comment on the tutorial page but wasn’t allowed to. The errors,

/Users/tilaye/Desktop/apps/CorePlotTest/Classes/CorePlotTestViewController.m:106: error: incompatible type for argument 1 of 'setMajorIntervalLength:'
/Users/tilaye/Desktop/apps/CorePlotTest/Classes/CorePlotTestViewController.m:113: error: request for member 'axisLabelOffset' in something not a structure or union
/Users/tilaye/Desktop/apps/CorePlotTest/Classes/CorePlotTestViewController.m:115: error: incompatible type for argument 1 of 'setMajorIntervalLength:'
/Users/tilaye/Desktop/apps/CorePlotTest/Classes/CorePlotTestViewController.m:122: error: request for member 'axisLabelOffset' in something not a structure or union
/Users/tilaye/Desktop/apps/CorePlotTest/Classes/CorePlotTestViewController.m:125: error: request for member 'bounds' in something not a structure or union
/Users/tilaye/Desktop/apps/CorePlotTest/Classes/CorePlotTestViewController.m:135: error: request for member 'defaultPlotSymbol' in something not a structure or union
/Users/tilaye/Desktop/apps/CorePlotTest/Classes/CorePlotTestViewController.m:138: error: request for member 'bounds' in something not a structure or union
replaced axisLabelOffset with labelOffset,

I did the following to work around the issue,

replaced axisLabelOffset with labelOffset

replaced graph.defaultPlotSpace.bounds with graph.defaultPlotSpace.graph.bounds

replaced [NSDecimalNumber decimalNumberWithString:@"5"] with [[NSDecimalNumber decimalNumberWithString:@"5"] decimalValue]

My final working viewDidLoad method was then,

- (void)viewDidLoad {
  [super viewDidLoad];

  graph = [[CPXYGraph alloc] initWithFrame: self.view.bounds];
  self.view = [[CPLayerHostingView alloc]initWithFrame:[UIScreen mainScreen].bounds];
  CPLayerHostingView *hostingView = (CPLayerHostingView *)self.view;
  hostingView.hostedLayer = graph;
  graph.paddingLeft = 20.0;
  graph.paddingTop = 20.0;
  graph.paddingRight = 20.0;
  graph.paddingBottom = 20.0;

  CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
  plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-6)
  length:CPDecimalFromFloat(12)];
  plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-5)
  length:CPDecimalFromFloat(30)];

  CPLineStyle *lineStyle = [CPLineStyle lineStyle];
  lineStyle.lineColor = [CPColor blackColor];
  lineStyle.lineWidth = 2.0f;

  CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
  axisSet.xAxis.majorIntervalLength = [[NSDecimalNumber decimalNumberWithString:@"5"] decimalValue];
  axisSet.xAxis.minorTicksPerInterval = 4;
  axisSet.xAxis.majorTickLineStyle = lineStyle;
  axisSet.xAxis.minorTickLineStyle = lineStyle;
  axisSet.xAxis.axisLineStyle = lineStyle;
  axisSet.xAxis.minorTickLength = 5.0f;
  axisSet.xAxis.majorTickLength = 7.0f;
  axisSet.xAxis.labelOffset = 3.0f;

  axisSet.yAxis.majorIntervalLength = [[NSDecimalNumber decimalNumberWithString:@"5"] decimalValue];
  axisSet.yAxis.minorTicksPerInterval = 4;
  axisSet.yAxis.majorTickLineStyle = lineStyle;
  axisSet.yAxis.minorTickLineStyle = lineStyle;
  axisSet.yAxis.axisLineStyle = lineStyle;
  axisSet.yAxis.minorTickLength = 5.0f;
  axisSet.yAxis.majorTickLength = 7.0f;
  axisSet.yAxis.labelOffset = 3.0f;

  CPScatterPlot *xSquaredPlot = [[[CPScatterPlot alloc]
  initWithFrame:graph.defaultPlotSpace.graph.bounds] autorelease];
  xSquaredPlot.identifier = @"X Squared Plot";
  xSquaredPlot.dataLineStyle.lineWidth = 1.0f;
  xSquaredPlot.dataLineStyle.lineColor = [CPColor redColor];
  xSquaredPlot.dataSource = self;
  [graph addPlot:xSquaredPlot];

  CPPlotSymbol *greenCirclePlotSymbol = [CPPlotSymbol ellipsePlotSymbol];
  greenCirclePlotSymbol.fill = [CPFill fillWithColor:[CPColor greenColor]];
  greenCirclePlotSymbol.size = CGSizeMake(2.0, 2.0);

  [xSquaredPlot setPlotSymbol:greenCirclePlotSymbol];

  CPScatterPlot *xInversePlot = [[[CPScatterPlot alloc]
  initWithFrame:graph.defaultPlotSpace.graph.bounds] autorelease];
  xInversePlot.identifier = @"X Inverse Plot";
  xInversePlot.dataLineStyle.lineWidth = 1.0f;
  xInversePlot.dataLineStyle.lineColor = [CPColor blueColor];
  xInversePlot.dataSource = self;
  [graph addPlot:xInversePlot];
}

I also got

/Users/tilaye/Desktop/apps/TestApp/Classes/TaggedVideoGraphViewController.m:135: warning: method definition for '-numberOfRecordsForPlot:' not found

and changed my function signature from

-(NSUInteger)numberOfRecords {

to

-(NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot {

Recover iphone contacts and SMS (text) from backup

I just broke my iPhone. I need to wait a while before I could get a replacement. In the meanwhile, I needed to recover my contacts (address book) from a backup file. Thanks to this discussion where I got most of the info I needed. There were a few turns though. So I’ll write the steps if it helps somebody.

I used: Windows XP, iTunes 8.2, Firefox.

1. Back backup

I needed to use a tool to recover my data. I first backed up my backup files because I wasn’t sure if I could trust the tool. So I simply made a copy of the folder C:\Documents and Settings\MyUserName\Application Data\Apple Computer\MobileSync\Backup in another folder. I finally realized that I didn’t need this step because everything worked ok. But if you want to be comfortable then go for it. It took my machine about 4 minutes to copy the whole folder.

2. Extract address book

To extract the address book from the backup file, I used the tool Backup Extractor for iPhone (see update at the end of this post for a more recentl URL). I downloaded the free version which turned out to satisfy my needs allright. I run the program and I got a list of backup files to restore. Some were iPhone files and the rest were iPod files. I chose the most recent iPhone backup. The second step of the restore wizard brought up two options. I had to choose the second option (manual). The first one is not available in the free version of the software anyway. On the third step, I navigated to Library->AddressBook and checked AddressBook.sqlitedb. At the last step I chose to put the restored file in C:\restored. When the process finished I got the file C:\restored\AddressBook.sqlitedb. I then had to rename the extension of this file from .sqlitedb to .sqlite. This will become important shortly.

3. Open AddressBook database

I opened firefox and installed the SQLite Manager add-on for Firefox, restarted firefox. I then went to Tools->SQLite Manager. On SQLite Manager window I clicked the open icon and selected C:\restored\AddressBook.sqlite.

4. Retrieve contacts from database

The discussion I referred to earlier gives a nice query to select contacts from the database,

select ABPerson.first,ABPerson.last, ABMultiValue.value from ABPerson,ABMultiValue where ABMultiValue.record_id=ABPerson.ROWID

I went to “Execute SQL” tab in SQLite Manager window in Firefox, pasted the above query and run it. That gave all my contacts. Some of the numbers were missing first and last names so I couldn’t tell who they belonged to. The trick was to change the query to select the ABPerson.prefix column too,

select ABPerson.prefix, ABPerson.first,ABPerson.last, ABMultiValue.value from ABPerson,ABMultiValue where ABMultiValue.record_id=ABPerson.ROWID

Now I need to call my insurance…

EDIT

I just recovered my SMS as well. The process is similar except in step 2 extract Library->SMS->check sms.db and rename sms.db to sms.sqlite. In step 4 use the query,

SELECT rowid, address, date, text FROM message ORDER BY date

UPDATE

iPhone Backup Extractor has moved to a new address now. Thanks to Matt Collins for the update.