Archive for the ‘Xcode’ Category

# “Making Apps”

Both Olaf Monien and Daniel Magin have blogged about the first in their “Making Apps” series of events on iPhone development, which RemObjects Software had the great honor of sponsoring. Among other things, the roadshow also includes a talk by Holger Flick on our new Data Abstract for OS X.

This first event last week was in Munich; from what i hear there might still be a couple of seats available for the encore in Hamburg, next week…

by marc hoffman, March 20th, 2010

# What’s New and Cooking…

The past week has been a busy one, here at RemObjects. On Tuesday, we shipped our new “Spring 2010” releases, updating our entire product suite. We also started work on three major new projects that will significantly shape Data Abstract over the coming year.

Let’s start with a quick look at the “Spring 2010” releases. On first sight, this round looks like a minor update – and in many ways it is, as a large portion of the past product cycle has been concentrating on QA and documentation (which is making great strides in the wiki, i must say – kudos to the entire team for keeping up with their documentation writing). But we also shipped a few great new features and key technologies that will play an important role moving forward.

Script

Firstly, there’s the new RemObjects Script for .NET that Carlo talked about the previous week. Right now, RemObjects Script is is shipping as a standalone library product (like its close sibling Pascal Script for Delphi, and like Internet Pack, it ships free and with complete source, and is available in our public SVN). So that alone, i believe, is pretty cool – but RemObjects Script fits into a greater plan, and that is the expansion of Business Rules Scripting in Data Abstract.

A little known and often overlooked feature we have had in Data Abstract for Delphi for a long time is the ability to define business rules inside the schema, to be run on the client. Not really meant to enforce security, but more to provide a better client experience, the idea was that constraints and business logic could be specified – using Pascal Script – right inside Schema Modeler, and clients will retrieve and run these rules automatically, and would always have the latest set of rules, without needing to update the client .exe.

RemObjects Script is an essential piece in our plan to take this to the next level, and we are currently working on full Business Rules Scripting support, both client and server side, and for all three editions of Data Abstract. The idea is that right inside Schema Modeler, you will be able to specify JavaScript based rules that can run either on the client (be it .NET, Delphi or OS X), the server, or both.

Server side rules can be used for the actual enforcement of rules, making it possible to replace a lot (if not all) of the code that currently makes up a common DA server. Client (and shared) rules can complement these to enhance the local editing experience, by “enforcing” adherence to rules while editing data, without requiring a roundtrip to the server for final validation.

This DA Scripting feature is in the works now, and will ship for the various editions over the remaining course of the year, starting with Data Abstract for .NET in May.

Relativity

Next up, we shipped the first release of Relativity. Relativity is our new standalone Data Abstract application server, replacing the aging (and Delphi based) DAServer.

The idea behind Relativity is that the vast majority of Data Abstract servers don’t really need much custom code (beyond business rules), yet the common Data Abstract approach today is to create a custom server .exe that needs to be built, deployed and maintained. With Relativity, this can now be a thing of the past, and you can deploy Data Abstract services in a ready-made server application, simply by uploading the appropriate .daSchema file.

Relativity is based on Data Abstract for .NET, but it ships with all three editions of Data Abstract. This means it gives Delphi developers the chance to use .NET drivers and the advanced server-side functionality such as DA SQL, without needing to purchase (or learn to work with) DA/.NET. It also allows Mac and iPhone developers to create and host servers (since we don’t ship a server library in DA/OSX).

And of course Relativity will also take full advantage of DA Scripting, starting in May.

More Stuff

In addition to these to “big ones”, we’ve also shipped a range of smaller new features and enhancements.

Internet Pack for .NET has been extended with a native client implementation for LDAP, which Carlo also blogged about before. We use LDAP a great deal internally, and this new client class makes it easy to build LDAP authentication into your RO/DA servers (or any other applications, of course). In fact, Relativity ships with a default LDAP Login Provider that is based on this implementation.

Data Abstract for .NET now provides the ability to expose data via the REST protocol, which makes it very easy to access data from non-DA client applications, for example from client-side AJAX based web sites. REST is one of many features we have added over the past year or so to enable better accessibility from web clients (another notable one is support for JSON messaging in RemObjects SDK), and we’ll be blogging and writing more abut this.

Our Xcode integration has been extended by new project templates that really make it easy to get going with Data Abstract or RemObjects SDK for the Mac or iPhone. These templates were created based on a lot of custom code i had written while implementing our internal Bugs 7 client, and they should provide a great starting point.

Screenshot 1 - Templates.png

(One of the next items on my list is a post that will look at these in more detail).

 

Visual Studio 2010The last important change i want to highlight is that the entire range of products for .NET is now compatible and integrates with the new Visual Studio 2010 (based on the current Release candidate, although we expect no problems between now and the final release of vs2010 in April).

What’s Next

Ok, so i mentioned work on three new major features has started this week, as well. What are those? The first one, of course, is the new DA Scripting support i mentioned above.

The second new feature is one that we have been planning for a while but are finally getting around to for this time, and that is a brand new “New Project” template architecture for both Delphi and .NET. The current templates are pretty server-focused, and don’t make it very easy to create different client types. Our new templates will be focused around ann the various client applications you might want to create (WinForms, WPF, Gtk#, Silverlight, Monobjc, ASP.NET, VCL, UCL, and so on), combined with a great integrated wizard that will allow you to either create a new server project to match, or connect your client to an existing (custom or Relativity) server.

The third new feature, which i am most excited about, is to round of our Mac development story to allow for pure Mac development of DA applications. We have the library to build great clients on Mac, iPhone and iPad. We now have Relativity to host DA services on a variety of server platforms. What’s missing, and what we’re working hard on for the May release, is the tool chain in the middle – a Schema Modeler for Mac that will enable developers to design and test their schemas, for Relativity deployment, right in their Mac.

 

Stay tuned for a lot more talk about all three of these topics, over the next three months. In the mean time, go and check out our “Spring 2010” releases, available now!

 

marc

by marc hoffman, March 6th, 2010

# Photo(s) of the Week #28


DSC_9205.jpg

It’s been a while since i last posted photos. Has, in fact, been a while since i last got around to doing some decent shooting.

I mostly blame Xcode.

You see, when i started up serious photography in 2006, computing as my main hobby of choice had started failing me. Computer work, and programming, had become work, not a hobby, and i no longer felt like doing programming in my spare time. A year later, along came my first Mac (ironically because &ndash among other things – it allowed me to do the post-processing of my photos without having to deal with the scourge that is Windows), and about half a year later came interest in developing with Xcode, which turned around to be such an awesome and fun development environment that it turned around my apathy regarding programming and made me enjoy it enough, again, to do it in my spare time.

So these days, my weekends and evenings are, once again, spent developing cool stuff (like our Bugs 7 application or my OneSpace iPad app). Going out and shooting pictures moved a bit to the back burner. (of course, the cold Winter hasn’t helped, either ;).

In any case, today has been one of the first days of great (for February) weather here in Berlin, along with at times almost clear blue sky, and some great clouds, giving me the chance to whip out my camera and grab a few dozen nice shots for cloudporn.com, my neglected photo blog (SFW).

DSC_9170.jpg

These images were all shot on my converted D50 and the Nikkor 70-300mm. They are all infra-red, with only really minor retouching (contrast, mostly) in the new Aperture 3. While i’m usually a Lightroom guy, what i like about Aperture is that it allows me to preserve my in-camera calibrated white balance in infra-red short. (in Lightroom, it’d be impossible to get out images looking like these, except by converting to grayscale; the images you see here are not grayscaled).

DSC_9217.jpg

We’ll see how it goes, but for the new decade, i’ve sworn to find more balance and get out to do more photo shooting, once again…

by marc hoffman, February 28th, 2010

# Using Cocoa Bindings for binding DADataTable to NSTableView.

As you might know, Cocoa offers several ways for populating NSTableView with data.
The first approach is to use the NSTableViewDataSource protocol, which we are applying widely in our samples.

The second approach I want to cover today, is using Cocoa Bindings.

What is Cocoa Bindings?

Cocoa Bindings is an amazing technology that allows us to establish a full two-way data binding without writing any “glue” code. Cocoa Bindings widely uses the MVC paradigm, where models encapsulate application data, view display and edit data and controllers mediate between model and view.

So firstly, we will need to implement our own DataTableController, which we can reuse for any future projects.

In order to avoid creating a new sample from scratch, I’ve used our DASimpleSample, from which I removed all code for filling NSTableView using the NSTableViewDataSource protocol.

Implementing our DataTableController:

As the base for our controller, we will take the NSArrayController class.

So, let’s create a new class called DataTableController, inherit it from NSArrayController, add the DADataTable instance variable, which represents our data table and expose it as the read/write property like on code-snipped below:

//  DataTableController.h
 
#import <DataAbstract/DataAbstract.h>
 
@interface DataTableController : NSArrayController
{
	DADataTable *table;
}
 
@property (retain) DADataTable *table;
 
@end

In the DataTableController.m file we need to implement the setTable method, which retains the given DADataTable and set the table rows as content property of our controller.

-(void)setTable:(DADataTable *)newTable
{
	[newTable retain];
	[table release];
	table = newTable;
	[self setContent:[table rows]];
}

Also, in order to allow our controller to add and delete rows, we need to override add and remove methods as shown below:

-(void)add:(id)object
{
	if (!table) return;
	DADataTableRow *newRow = [table addNewRow];
	[self rearrangeObjects];
	[self setSelectedObjects:[NSArray arrayWithObject:newRow]];
}
 
-(void)remove:(id)object
{
	if (!table) return;
	for (DADataTableRow *row in [self selectedObjects])
		[table removeRow:row];
	[self rearrangeObjects];
	[self selectNext:self];
}

That’s all, our controller is ready. Let’s see how to use it for binding data.

Binding DataTable:

Open MainMenu.xib in Interface Builder and add NSArrayController.

Then, having added the selected controller, go to the Identity Inspector and select DataTableController as the class of the controller.

Then open Attributes Inspector and add keys. Keys is the column name of our DataTable. Specifying keys will allow us to select appropriate values in binding columns.

Now go to our window, select the NSTableView control and bind each of its columns to our controller.

For that, you will need to select a column and, in the Binding Inspector tab in the Value section, choose Bind To: Data Table Controller, set arrangedObjects as Controller Key and put the appropriate column name in the Model Key Path combo-box. We should get something like this:

Finally, we will set a link between add/remove methods and our controller.

To do that, we have to expand the toolbar of our application, then open the HUD window for our controller by performing a right mouse button click on it and connect add: and remove: actions with the appropriate toolbar buttons. You will see something like this:

We are now finished with the visual part and can close Interface Builder. The last thing to do is to set the content of our controller to a specific table. Switch to XCode and modify the asyncRequest: didReceiveTable: method as shown below:

- (void)asyncRequest:(DAAsyncRequest *)request didReceiveTable:(DADataTable *)table
{
	workersTable = [table retain];
	// set our table...
	[tableController setTable:workersTable];
}

That’s All. Let’s compile and run our application to see the results.

We can edit/insert/delete rows, all should work as expected and all the configuration took place in Interface Builder, we just had to write one line of code.

[tableController setTable:workersTable];

In the next my blog post, I’m going to tell you more about Cocoa Bindings. We will, among other things, try to add the client-side filtering of data in the table, the highlighting of changed cells.

by Alexander, February 15th, 2010

# Everything is Relative

Today i want to talk a bit about “Relativity”, a new feature we’re shipping with Data Abstract this month (and which is actually available as “tech preview”in the current Winter 2009 releases).

“Relativity” is, simply put, a standalone server application that can be used to host Data Abstract schemas and serve data. In essence, it provides the complete Data Abstract middle tier, in a precompiled box and ready run. This offers several benefits, not the least of which are:

  1. No need to build your own. Relativity provides all the power and abstraction of a true Data Abstract middle tier server, without you actually having to create, build, and deploy your own executable. This allows you to concentrate on the client development. It also is really handy for prototyping, if you just want to have database server to talk to, without much work, even if you plan to eventually implementing your own custom server.
  2. Build on Data Abstract for .NET. .NET is platform with the most advanced version of DA – it supports our powerful DA SQL execution engine, and other features not available on all platforms. “Relativity” is being made available to all users of Data Abstract, so whether you’re a developer using .NET, Delphi, or Xcode, you can now write clients against Relativity that take full advantage of these features.

But let’s go and take a more detailed technical look at Relativity.

Relativity is a server application, so it does not provide any user interface. You can deploy a Relativity server in several ways, including:

  • Running it as a regular user application, on Windows.
  • Installing it as a Windows service.
  • Running it as a Unix daemon with the mono-service2 tool, on Mac and Linux.
  • Running it as a menubar item, on Mac.

Regardless of how you deploy and run it, Relativity will start making it’s Data Abstract services available on (by default) port 7099. But of course before it can start serving actual data, it will need to be configured with what data to serve. That is done thru the Relativity Server Admin tool, which is currently available for Windows (but versions for both Mac and iPhone are in the works).

When you first start it, the Admin tool will look something like this:

Screen shot 2010-02-03 at 2.24.03 PM.png

On the left hand side, you will see a tree view with all known instances of “Relativity” servers. This includes any servers (local or remote) that you connected to in the past, as well as any servers discovered on the local network using ROZeroConf.

Select any of the servers (here, “VEMMY” is the one instance running in my Windows VM), to connect and get more options.

Screen shot 2010-02-03 at 2.30.01 PM.png

The first two nodes allow you to configure how this “Relativity” server is accessed. This includes options such as what ports to listen on, what RemObjects SDK channels and messages to use, etc. Here you have the full choice of all the options provided by RO, you can choose the familiar HTTP, TCP, Super HTTP or other channels, BinMessage, SOAP Message, and so on.

Where it gets more interesting is the third node – Domains. This is where you configure the meat of the services Relativity is providing.

Each Domain corresponds to what typically would be a separate Data Abstract middle tier server. Domains are completely abstracted from one another and Relativity allows you to host as many separate domains as needed. With that, a single Relativity server can replace multiple DA servers, be it for related to completely independent applications or projects.

As you can see, i have three domains set up in my server, one for “BC7″, our new bug tracking system (using a PostgreSQL database running on our Xserve build server), one for “RemObjectsCom”, the database that drives our website (Microsoft SQL Server, running on the Windows server that hosts our website), and finally “OneSpace”, the database for a personal iPad project i am working on.

As we drill into a specific domain, you start seeing more things that will be familiar to you as a Data Abstract developer. Each domain can contain one or more Schemas – which correspond directly to .daSchema files or TDASchema components as you know them. You can manage schemas right there in the Admin tool, or directly launch Schema Modeler to edit the schema in question:

Screen shot 2010-02-03 at 2.39.38 PM.png

The domain also maintains a list of Connections to back-end databases available to it’s schemas. Once again, this directly corresponds to the .daConnections file or TDAConnectionManager component. Since Relativity is based on DA/.NET, these connections are based on the available DA/.NET drivers – regardless of whether your regular development platform is .NET, Delphi or Cocoa.

Another interesting part is the Login node. Relativity provides several options for handling authentication from client applications for data access (something you would normally need to manually implement, in a standalone DA server): in addition to relying on a static list of allowed username/password combinations, you can also choose to use a data table or command defined in one of the domain’s schemas to verify users (as i do in the example shown below) or query an external LDAP server for login.

The LDAP option is very handy if you are running a variety of services – some using Relativity, and some not – that you want to share user data among. We recently switched to LDAP for all our employee resources, and it has made administration so much easier.

The LDAP support in Relativity is based on a new 100% managed LDAP client implementation we’ve added to Internet Pack for this upcoming release. Carlo will blog more about this, soon.

Screen shot 2010-02-03 at 3.05.53 PM.png

The Login Provider architecture is extensible, so you can implement your own providers, for example if you need to do user authentication with a different method.

Client Access

Once you have Relativity set up to serve your data, your client application(s) can access it like any other Data Abstract server.

The only slight difference is that, since a Relativity server can host more than one domain, you need to tell the server which domain to access, by simply passing an additional Domain parameter as your login string, as in

User=foo;Password=bar;Domain=DomainName

You will also want to select which Schema to query. in regular DA applications, each schema usually has its own DataService, so keeping in line with that, Relativity allows you to append a schema name to the ServiceName property of your Remote Service. Instead of using DataService, simply use DataService.DomainName. (Alternatively, you can also pass a Schema to LoginEx).

In Closing…

So, this has been a brief introduction to Relativity – i hope you found it useful.

We think of Relativity as a strategic piece of Data Abstract, and it will play an increasing part in what we do for DA. We have lots of things planned for the future that will make Relativity even more powerful, such as our upcoming JavaScript Business Rules Scripting based on Carlo’s RemObjects Script for .NET.

You can try out the tech preview of Relativity now, and the official release will be part of what we ship at the end of this month. I’m looking forward to your thoughts and feedback!

marc

by marc hoffman, February 3rd, 2010

# Visualizing Data with Core-Plot

Core Plot is an open source graphing framework for Cocoa developers that makes it really easy to add graphs to your applications for the Mac and iPhone. Over the past half year, i’ve had the chance to use Core Plot in several of the internal applications i have been working on and have been very impressed with it, so i wanted to talk a little bit about how to use the library, in general, and how to make generate charts based on data in a Data Abstract for OS X application, in particular.

The example shown here is from a small iPhone application i wrote to keep track of the status of our Continuous Integration servers. The application shows the success (or errors) of any builds done on the machine, as well as – and this is the part where Core Plot comes in – graphs the number of tests that run and fail, over time:

In the application in question, the chart is being displayed in a cell within a UITableView, so our example starts out by implementing a custom UITableViewCell class that will host the graph. But the same general principles apply to show a chart anywhere else (and, replacing UIView with NSView, for using charts in a desktop app).

Core Plot uses a Core Animation as underlying technology, and as such draws itself in a specialized view class CPLayerHostingView. So we start out by crating this view, and adding it as sub-view:

- (id)initWithStyle:(UITableViewCellStyle)style 
{
  self = [super initWithStyle:style reuseIdentifier:@"MyChartCell"];
  if (self)
  {
    CGRect frame = self.contentView.bounds;
    CPLayerHostingView *chartView = [[CPLayerHostingView alloc] initWithFrame: frame];
    [self addSubview:chartView];
    //...

Once the CPLayerHostingView is created, we can add a graphs to it, and configure them. There are several graph types supported, but we want a regular line graph with X/Y coordinates, so we’ll choose a CPXYGraph class. We’ll add the graph to the view, and set a padding, to give us some room between the edges of the table cell:

  // create an CPXYGraph and host it inside the view
  CPTheme *theme = [CPTheme themeNamed:kCPPlainWhiteTheme];
  graph = (CPXYGraph *)[theme newGraph];	
  chartView.hostedLayer = graph;
 
  graph.paddingLeft = 10.0;
  graph.paddingTop = 10.0;
  graph.paddingRight = 10.0;
  graph.paddingBottom = 10.0;

The next step is to set up a plot space. A plot space defines the coordinate system for one or more charts in a graph, essentially mapping logical values to the area in the graph. For example, your chart might show values ranging from, say, 0 to 1000. The plot space defines the scale of those values in relation to the graph. It also defines the visual range of values that can be seen on screen.

To match our X/Y graph, we’ll create a CPXYPlotSpace, and set it to a range of 0-100 for both axis:

  CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
  plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
                                                 length:CPDecimalFromFloat(100)];
  plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
                                                 length:CPDecimalFromFloat(100)];

Finally, we’ll set up to axis, for the X and Y coordinates. Axis provide labels and tick-marks for the viewer, to give context to the values being shown.

The X/Y graph already provides a set of axis in for of a – you guessed it – CPXYAxisSet class. There are several properties on the axis’ that are worth looking at at tweaking to to suite out needs:

  • majorIntervalLength defines the number of units between “big” ticks on the axis. In this case it’s set to show one very 10 units. (if it were not for the exclusionRanges, discussed below, a numeric label would show for each major tick, as well).
  • minorTicksPerInterval specified how many small ticks will be shown between each major one. in this case, a value of 2 indicated that small would show for 5, 15, 25, etc. (a value of 9 would show ticks for every single unit).
  • Finally, exclusionRanges allows to define areas where no axis labels will be drawn. In my app, i don’t want to see any labels, so i set a range to exclude the entire visible graph
  CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
 
  CPXYAxis *x = axisSet.xAxis;
  x.majorIntervalLength = length:CPDecimalFromFloat(10);
  x.constantCoordinateValue = length:CPDecimalFromFloat(2);
  x.minorTicksPerInterval = 2;
  x.borderWidth = 0;
  x.labelExclusionRanges = [NSArray arrayWithObjects:
                              [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-100) 
                                                          length:CPDecimalFromFloat(300)], 
							  nil];;
 
  CPXYAxis *y = axisSet.yAxis;
  y.majorIntervalLength = length:CPDecimalFromFloat(10);
  y.minorTicksPerInterval = 1;
  y.constantCoordinateValue = length:CPDecimalFromFloat(2);
  y.labelExclusionRanges = [NSArray arrayWithObjects:
                              [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-100) 
                                                          length:CPDecimalFromFloat(300)], 
							  nil];

Our graph is now fully set up – except for one important part: we still need to define one or more charts to display actual values. My application needs to show two graphs on top of each other – one showing the total number of tests that ran, and another showing the number of failures.

Core Plot supports a variety of chart (or, plot) types, such as bar and pie chart, but for this scenario, we want a simple line graph, which is done via a CPScatterPlot. (A scatter plot actually allows to draw a plot with points scattered all over the place, not just as string y = f(x) values, but we will use it in the more simplistic case).

We’ll create a new CPScatterPlot instance, configure some properties such as its lineWidth and lineColor, and most importantly, set the dataSource to the object that will provide the plot with its data – in this case, self. To round things off, we also tell the plot to fill the area underneath it with a gradient, going from almost-transparent green to nothing. This gives the plot some depth, without hiding the other plots.

  CPScatterPlot *dataSourceLinePlot = [[[CPScatterPlot alloc] init] autorelease];
  dataSourceLinePlot.identifier = @"AllTests";
  dataSourceLinePlot.dataLineStyle.lineWidth = 3.f;
  dataSourceLinePlot.dataLineStyle.lineColor = [CPColor greenColor];
  dataSourceLinePlot.dataSource = self;
  [graph addPlot:dataSourceLinePlot];
 
  // Put an area gradient under the plot above
  CPColor *areaColor = [CPColor colorWithComponentRed:0.3 
                                                green:1.0
                                                 blue:0.3
                                                alpha:0.3];
  CPGradient *areaGradient = [CPGradient gradientWithBeginningColor:areaColor 
                                                        endingColor:[CPColor clearColor]];
  areaGradient.angle = -90.0f;
  CPFill *areaGradientFill = [CPFill fillWithGradient:areaGradient];
  dataSourceLinePlot.areaFill = areaGradientFill;
  dataSourceLinePlot.areaBaseValue = CPDecimalFromString(@"1.75");

We repeat the above to add a second plot, except this time we use red for the line color and gradient, and set the identifier to @"FailedTests".

This was quite a bit setup, but our graph is now ready plot, and will ask its data source (our cell) for data by sending it messages from the CPPlotDataSource protocol. This protoco will be familiar to any Cocoa developer who worked with, for example, a UITableView or NSTableView, or any other control using a data source.

To the protocol, two methods need to be implemented. The first is numberOfRecordsForPlot: which will, simply enough, return the number of items (in case of a scatter plot, points, the chart will contain. The second can be one of three methods that return the actual data. We’ll implement numberForPlot:field:recordIndex:.

The data to display is retrieved via Data Abstract, using a simple DA SQL request on a table that contains all test runs:

	NSString *sql = [NSString stringWithFormat:@"SELECT TOP 50 ID, _TotalTestCount, \
                                     _FailedTestCount, FROM TestRuns ORDER BY ID DESC"];
	testRuns = [[rda getDataTableWithSQL:sql] retain];

The _TotalTestCount and _FailedTestCount fields are server-calculated based on a relation table and contain the total number of run and failed tests for each test run. We can Key Path operators to get the maximum value, and adjust our plot space accordingly, so that the entire graph fits into the chart:

  int count = [[testRuns rows] count];
  int maxTests = [[[testRuns rows] valueForKeyPath:@"@max._TotalTestCount"] intValue];
 
  CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
  plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
                                                 length:CPDecimalFromFloat(count)];
  plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
                                                 length:CPDecimalFromFloat(maxTests)];

This is of course a bit redundant with the values we set earlier, but in real life application, the data access will usually happen in a different place than the initial setup (and data might get changed or refreshed during the course of the application), so i find it important to set up the graph properly to begin with, but then adjust the range to the real data.

With the data retrieved and the plot space adjusted, we can now implement the two data source methods.

numberOfRecordsForPlot: will simply return the number of rows in our table. numberForPlot:field:recordIndex will be called twice per data point, once for the X value (since we’re drawing a “non-scattered” plot, we’ll simply return the indexes) and one for the Y value, which we’ll retrieve from our data table. The different identifiers we assigned to the two plots will serve to distinguish which field to use for the Y value.

-(NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot 
{
  return [rows count];
}
 
-(NSNumber *)numberForPlot:(CPPlot *)plot 
                     field:(NSUInteger)fieldEnum 
               recordIndex:(NSUInteger)index 
{
  switch (fieldEnum)
  {
    case CPScatterPlotFieldX: 
    {
        // inverse numbers, so first (latest) test run is on the right.
        int x = [rows count]-recordIndex; 
        return [NSDecimalNumber numberWithInt:x];
    }
    case CPScatterPlotFieldY:
    {
      if ([plot.identifier isEqual:@"AllTests"])
      {
        float v = [[[rows objectAtIndex:index] valueForKey:@"_TotalTestCount"] floatValue];
        return [NSNumber numberWithFloat:v];
      }
      else
      {
        float v = [[[rows objectAtIndex:index] valueForKey:@"_FailedTestCount"] floatValue];
        return [NSNumber numberWithFloat:v];
      }
    }
  }
  return nil;
}

And that’s it! You can find more info on Core Plot on their Google code page; i also recommend joining their mailing list for latest news and support.

by marc hoffman, January 26th, 2010

# Using NSPredicateEditor with DADataTable

Today I want to talk about NSPredicateEditor and how to use it with a DADataTable.

What is NSPredicateEditor…

Cocoa’s NSPredicateEditor class provides an excellent way to compose predicates at runtime. The main benefit is that the user needs to know nothing about predicates and their format, but with help of NSPredicateEditor can easily build quite complex conditions they need. Using NSPredicateEditor also allows to avoid any kind of typing errors, because in most of cases all the user needs is to do is just to select appropriate fields and values from popup buttons.

Here is the screenshot of Bugs 7 showing NSPredicateEditor that represents following condition: (Live == 1 AND AreaID == 4 AND OwnerID == 5) OR ID == 37222

NSPredicateEditor uses a list of NSPredicateEditorRowTemplate objects, where each row template describes certain elementary comparison predicate object.  Combining different row templates allows the NSPredicateEditor to represent compound predicates with unlimited complexity.

Usually, a row template holds three elements: left and right expressions and a condition between them. In our case, the left expression represents the column from our table and the right expression represents the value pattern for that column. Obviously, it is good to have template with most suitable editor for each column data type. DataAbstract for OS X provides proper templates for each fields that can be used in the table. In addition to standard  NSPredicateEditorRowTemplate DA brings several custom row templates that simplify building predicates for the tables.

The most interesting here is the DALookupFieldPredicateEditorRowTemplate class. This class allows to create row template for a lookup field, where the user can chose certain lookup value from list of allowed values, proposed by a popup button. It allows user to deal with meaningful values instead of just IDs. This is well shown in the figure above.

I should also mention DAFallbackPredicateEditorRowTemplate. This class describes special template for any predicate that is not supported by a given set of templates. For example if your editor tries to render a NSPredicate that comes into your application from outside and cannot understand a certain part of the compound predicate, then it will render it as “unsupported predicate” with help of DAFallbackPredicateEditorRowTemplate. This assures that the sub-predicate, while not editable in the NSPredicateEditor, will not get lost.

…and How Can You Use it?

Let’s see how to configure NSPredicateEditor instance for composing predicates for a certain custom DADataTable.

When you need to configure the editor for exposing a sub-set of columns only, you need to create array of row templates obtained from each table field you want to see in editor:

NSMutableArray *rowTemplates = [NSMutableArray arrayWithCapacity:[[da bugs] fieldCount]];
for (NSString *f in allowedFields)
{
  DAFieldDefinition *fd = [[da bugs] fieldByName:f];
  [rowTemplates addObjectsFromArray:[fd predicateEditorRowTemplates]];
}

Then you should supplement that array with additional row template for building compound predicates

NSPredicateEditorRowTemplate *compoundTemplate =
  [[[NSPredicateEditorRowTemplate alloc] initWithCompoundTypes:
    [NSArray arrayWithObjects:
      [NSNumber numberWithInt: NSAndPredicateType],
      [NSNumber numberWithInt: NSOrPredicateType],
      [NSNumber numberWithInt: NSNotPredicateType],
      nil]] autorelease];
[rowTemplates addObject:compoundTemplate];

and (optionally) add an instance of DAFallbackPredicateEditorRowTemplate for rendering unsupported predicates.

[rowTemplates addObject:[DAFallbackPredicateEditorRowTemplate rowTemplate]];

Finally, you should assign that templates array to your NSPredicateEditor instance

[editor setRowTemplates:rowTemplates];

If you want to expose all visible fields in the editor, then you can just use the convenient defaultPredicateEditorRowTemplates] method on the table, and whole configuration will be reduced to single line of code, as followings:

[editor setRowTemplates:[[da bugs] defaultPredicateEditorRowTemplates]];

That’s all. Your predicate editor is properly configured and you can use it for building any kind of predicates for given table.

You can use that editor to let the user define NSPredicates both for local filtering data in table like:

NSPredicate *p = [editor predicate];
rows = [[[myTable rows] filteredArrayUsingPredicate:p] retain];
[tableView reloadData];

or for creating Dynamic Where for server-side filtering data.

NSPredicate *p = [editor predicate];
DADynamicWhereClause *clause = [DADynamicWhereClause dynamicWhereClauseWithPredicate:p];
request = [rda beginGetDataTable:@"MyTable"
                          select:[self fieldsToSelect]
                           where:clause
                           start:NO];
[request setDelegate:self];
[request start];

I recomend to review our DAFilters sample that ships with DA/OSX, to see NSPredicateEditor and the techniques shown here in action.

by Alexander, January 18th, 2010

# Is that a Wiki in your Xcode?

We’re getting close to shipping our first release of Data Abstract for OS X as well as the 1.1 update for RemObjects SDK for OS X at the end of this month, and as part of crossing all the final Is and dotting all the remaining Ts, Carlo and i have been working on leveraging the tools in our new documentation tool chain to integrate the RemObjects Wiki (or, the relevant part of it) as Xcode documentation:

What you are seeing here is our wiki as standard Xcode doc set. You can browse and search it just as you would the standard Apple docs; you can navigate to it by Cmd+Option-Double-clicking identifiers in your code – in other words, you get the full documentation experience.

The version shown here works directly on the live wiki – meaning as soon as changes and updates are made to the pages online, you will see them reflected in the wiki as well. In the long term (not for this release, yet), we’ll also be providing an offline version, that contains a snapshot of the entire wiki, for offline use (i.e, when you’re working on the proverbial plane).

The Docset will also update via RSS feed, so content (in the offline version) and structure changes (such as the addition of new pages to the indexes, etc) will automatically update within Xcode, on a regular basis.

Stay tuned for more info on RO/OSX and DA/OSX, as we near release.

by marc hoffman, October 12th, 2009

# iPhone & Desktop Pairing with RemObjects SDK

One common scenario when developing iPhone apps is that you have a desktop application of some sorts that you want your iPhone to pair with – be it to sync data, remote control one with the other, or establish any other kind of communication.

In this scenario, the desktop app would be the “server”, in RemObjects SDK terminology, and the iPhone would be the client.

For the next release of RemObjects SDK for OS X, coming next month, we’ve created a nice sample that illustrates how to easily achieve this, and i figured i would post a small screencast of the sample in action, below.

What you see is a desktop app written in Delphi (although .NET will do just fine, as well), which for sample purposes has a pretty minimal UI, but in real life would be your full-fledged desktop UI app. When the iPhone client is a launched, it automatically detects any instance of your desktop app running on the local network and shows them in a list.

(The UI for this would be up to the application designer, obviously; for simplicity we simply show them all in a UITableView. In real life, if only one server was found you’d probably want to forgo the list altogether and just ask the user if he wants to connect).

Once the user picks a server, communication is initiated, by the iPhone calling a service method and passing it a unique GUID it generated. Since this is the first time these two are talking to each other, the server rejects the phone, but displays a random 4-digit code in it’s UI (this code is not known to the phone, at this stage). The phone asks the user to enter the code and, once done, sends it to the server to confirm the pairing. Once successful, the server stores the client’s GUID for future reference – and any future calls (even after the phone app has been restarted) will work right away.

Of course instead of showing an UIAlertView, your application would instead commence doing it’s real work.

Here’s the app in action:

by marc hoffman, September 18th, 2009

# An Update on Data Abstract for OS X

I realize it’s been a while since i talked about Data Abstract for OS X, so i figured today would be a good time to post a small teaser for what’s coming up in the next beta drop – most likely before the end of the week.

The previous beta, which we shipped in early June, provided read-only access to Data Abstract servers created using .NET and Delphi. Since then we’ve been busy both refining that support but also, more importantly, adding the ability to make changes, persist deltas and and apply updated back to the server.

Below, you’ll see a screenshot of a small sample application that downloads a table from our unified PCTrade sample database, allows to make changes, and post them back. in the background, you see the sample server (running in a Virtual Machine on Windows) accepting and handling those update requests.

The app uses the briefcase model, so it can work offline, with changes staying local until the user presses the “Update” button to send them back to the server; of course DA will also all you to sending changes to the server implicitly, to provide a more seamless “online” experience for the user.

As you might notice, the sample also leverages the new ROZeroConf support we shipped in May, to find the server on the local network without manual configuration (in this case, the server machine is called VEMMY, as can be seen in the popup button in the client’s toolbar – if more than one server were running on the network, the user could pick which one to use, defaulting to the one found first).

by marc hoffman, July 15th, 2009